PHP fóra: Builder | JakPsatWeb | Webtrh
Nejste přihlášen(a)
Mám tady takový problém a nevím jestli je to nějaké vlastnost PHP nebo
moje neznalost.
O co teda jde. Mám třídu BaseModel.
abstract class BaseModel extends Object
{
static $table = 'table_name';
public static function getTableName()
{
return self::$table;
}
...
}
A dále mám třídu ArticlesModel, která je od
BaseModel poděděna.
class ArticlesModel extends BaseModel
{
static $table = 'articles';
...
}
A můj problem je takový, že ať zavolám getTableName nad
BaseModel nebo ArticlesModel, vždy dostanu
‚table_name‘ ale u ArticlesModel bych očekával
‚articles‘.
Pro názornost:
BaseModel::getTableName(); // vraci 'table_name', to je ok
ArticlesModel::getTableName(); //vraci taky 'table_name', coz je divne, ja bych ocekaval 'articles'
Ví někdo, čím to může být způsobeno a jak to napravit?
Editoval Jur4 (6. 9. 2009 0:33)
Jak to bývá, tak 5 minut po odeslání příspěvku jsem dostal nápad.
Zkusil jsem do ArticlesModel nakopírovat funkci getTableName a
kupodivu to začalo vracet správně.
class ArticlesModel extends BaseModel
{
static $table = 'articles';
public static function getTableName()
{
return self::$table;
}
...
}
Zkusil jsem proto všude nahradit static $table za const
table a je to to stejné. Pokud je funkce getTableName v obou
třídách, dostávám správný výsledek. Pokud ne tak dostávám všude
table_name. Takže tady už je mi jasné, že to způsobuje
volání self::něco, které vždy směřuje na třídu, ve které
bylo použito.
Něco se o tom píše i v dokumentaci v komentářích.
Snad to aspoň někomu pomůže, kdyby se s tím taky setkal.
Narazils přesně na případ, který byl vyřešen až v PHP 5.3, tzv.
„late static binding“. Statické proměnné nevědí, odkud jsou volané.
Jako náprava pomůže neuvádět v getteru self::, ale namísto
toho static::. Ale říkám, až od 5.3ky.
Dík za odpověď. Sice jsem to nakonec pořešil trochu jinak, ale aspoň budu vědět do budoucna. :)