Pozor na statické volání nestatické metody


Dnes jsem svou nepozorností objevil jednu docela nepříjemnou vlastnost PHP. Zkuste se podívat na následující kód. Ten se snaží zaobalit funkcionalitu "Zend_View_Helper_Translate" helperu do třídy "Wrapper". Nepozorností jsem přehlédl, že metoda "translate($messageid = null)" není statická.


<?php

class Wrapper
{
	public function translate($key)
	{
		return Zend_View_Helper_Translate::translate($key);
	}
}

class Zend_View_Helper_Translate
{
	public function translate($messageid = null)
	{
		//...
		$this->getTranslator();
		//...
	}
}

$class = new Wrapper();
$class->translate("key");

Bystřejší si jistě hned všimli, že nestatická metoda "Zend_View_Helper_Translate::translate()" obsahuje volání "$this->getTranslator()". A právě zde je důležité jak se PHP zachová.

Možná si říkáte, že kód selže, protože nelze staticky volat nestatickou metodu - neselže

Další co Vás asi napadne je, že "$this" vlastně neexistuje, protože jsme nevytvořili instanci. Myslíte, že PHP selže? - neselže

Poslední otázkou tedy je, co je vlastně ono "$this"... Budete překvapeni, i já jsem byl... Aktuálně v PHP 5.3.2 je "$this" instanceOf "Wrapper", takže výsledek je "Fatal error: Call to undefined method Wrapper::getTranslator()".

PHP bug since 2002 #20089 Calling static method from instance method results in invalid $this. Have fun... :)