0251 / 590 644 - 0
info@a-coding-project.de

Verkettete Methodenaufrufe in PHP

PHP Logo

Das Logo von PHP

Durch verkettete Methodenaufrufe kann man sich in PHP Einiges an Schreibarbeit sparen. Wer objektorientiert mit PHP arbeitet, wird eventuell Getter- und Setter-Methoden im Einsatz haben. Damit kann man die Variablen einer Klasse auf private stellen und nur über Funktionen auf den Wert schreibend oder lesend zugreifen. Das hat folgende Vorteile:

  • Man kann dafür sorgen, dass die Variable immer im richtigen Format vorliegt
  • Falls die Variable mal verschoben werden soll, kann man einfach die Methoden anpassen und nicht jede einzelne Stelle

Um diese Vorteile auch optimal zu nutzen sollte man diese Funktionen nach Möglichkeit auch innerhalb der gleichen Klasse benutzen.

Ein Beispiel für eine Klasse mit Getter- und Setter Funktion:

<?php
	class Page
	{
		private $title = null;
		private $url   = null;
		
		/**
		 * Title of the Page
		 * 
		 * @param string $title
		 */
		public function setTitle($title)
		{
			if(is_string($title))
			{
				$this->title = $title;
			}
		}
		
		/**
		 * Title of the Page
		 * 
		 * @return string
		 */
		public function getTitle()
		{
			return $this->title;
		}
		
		/**
		 * Url of the Page
		 * 
		 * @param string $url
		 */
		public function setUrl($url)
		{
			if(is_string($url))
			{
				$this->url = $url;
			}
		}
		
		/**
		 * Url of the Page
		 * 
		 * @return string
		 */
		public function getUrl()
		{
			return $this->url;
		}
	}

Um eine neue Instanz der Klasse zu erstellen könnte man nun zum Beispiel Folgendes schreiben:

$contact = new Page();
$contact->setTitle("Kontakt");
$contact->setUrl("https://www.a-coding.de/contact");

Set-Methoden verketten

Diesen Aufruf können wir durch Methodenverkettung nun abkürzen. Dafür muss in den Set-Methoden einfach die aktuelle Instanz ($this) zurückgegeben werden:

<?php
	class Page
	{
		private $title = null;
		private $url   = null;
		
		/**
		 * Title of the Page
		 * 
		 * @param string $title
		 * @return Page
		 */
		public function setTitle($title)
		{
			if(is_string($title))
			{
				$this->title = $title;
			}
			
			return $this;
		}
		
		/**
		 * Title of the Page
		 * 
		 * @return string
		 */
		public function getTitle()
		{
			return $this->title;
		}
		
		/**
		 * Url of the Page
		 * 
		 * @param string $url
		 * @return Page
		 */
		public function setUrl($url)
		{
			if(is_string($url))
			{
				$this->url = $url;
			}
			
			return $this;
		}
		
		/**
		 * Url of the Page
		 * 
		 * @return string
		 */
		public function getUrl()
		{
			return $this->url;
		}
	}

Diese Änderung bewirkt, dass wir nun nicht jedes Mal auf die $contact-Variable zugreifen müssen:

$contact = new Page();
$contact
	->setTitle("Kontakt")
	->setUrl("https://www.a-coding.de/contact");

Durch die Rückgabe der Instanz können wir nach einem Methoden-Aufruf direkt den nächsten starten. Neben der gesparten Schreibarbeit ist vor allem die Autocomplete-Funktion, die es zum Beispiel in Netbeans gibt interessant. Wenn man viele set-Methoden hat, kann man einfach den berühmten Pfeil machen und bekommt wieder alle Methoden aufgelistet.

Instanziierung verketten

Nun müssen wir aber immer noch zweimal auf die Variable zugreifen. Einmal beim Instanziieren durch new und einmal zum Setzen der Eigenschaften. Doch auch diesen Schritt können wir uns noch sparen:

<?php
	class Page
	{
		private $title = null;
		private $url   = null;
		
		/**
		 * A new instance
		 * 
		 * @return Page
		 */
		public static function produce()
		{
			return new self();
		}

		/**
		 * Title of the Page
		 * 
		 * @param string $title
		 * @return Page
		 */
		public function setTitle($title)
		{
			if(is_string($title))
			{
				$this->title = $title;
			}
			
			return $this;
		}
		
		/**
		 * Title of the Page
		 * 
		 * @return string
		 */
		public function getTitle()
		{
			return $this->title;
		}
		
		/**
		 * Url of the Page
		 * 
		 * @param string $url
		 * @return Page
		 */
		public function setUrl($url)
		{
			if(is_string($url))
			{
				$this->url = $url;
			}
			
			return $this;
		}
		
		/**
		 * Url of the Page
		 * 
		 * @return string
		 */
		public function getUrl()
		{
			return $this->url;
		}
	}

Die produce-Funktion liefert uns nun einfach eine neue Page-Instanz zurück. Dadurch ist es möglich direkt nach dem Aufruf mit der Instanz weiterzuarbeiten:

$contact = Page::produce()
             ->setTitle("Kontakt")
             ->setUrl("https://www.a-coding.de/contact");

Variablen aussparen

Eigentlich brauchen wir für unser Beispiel die $contact-Variable gar nicht mehr. Wir können sie entfernen und hätten denselben Effekt. Dies ist vor allem interessant, wenn man Instanzen zum Beispiel einem Array hinzufügen möchte:

//Vorher
$pages = array();

$contact = new Page();
$contact->setTitle("Kontakt");
$contact->setUrl("https://www.a-coding.de/contact");
$pages[] = $contact;

//Nachher
$pages = array();

$pages[] = Page::produce()
             ->setTitle("Kontakt")
             ->setUrl("https://www.a-coding.de/contact");

Hier sieht man, dass wir uns durch dieses Entwurfsmuster die Variable $contact und die Zeile mit dem Hinzufügen der Instanz zum Array quasi komplett sparen. Das schafft mehr Übersicht!