Дійсно курйозний випадок був у мене коли я майже 40 хвилин тупо потратив на роздебагування непрацюючого PHP сценарію. Пишу я значить на PHP 4, там для присвоєння об’єкта «через посилання» (reference) використовується хитра конструкція: дорівнює-амперсанд « =& ». Структуру коду я б назвав не з простих – множина об’єктів які при визові їх конструкторів послідовно створюють екземпляри (instances) одне одного і присвоюють посилання на створений об’єкт собі в члени класу. Виходить своєрідна гірлянда обєктів =) , де кожен попередній обєкт має в собі вказівник на наступний (якщо мені не зраджує память то класична теорія шаблонів проектування називає такий вид взаємодії міє об’єктами - шаблон Adapter).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /** * User Management class */ class UsersManagement { /** * DataBase Driver * @var db instance */ var $driver= null; /** * Constructor */ function UsersManagement(&$db) { $this->driver &= newSiteDriver($db); } } |
І от, що не роблю, замість посилань на обєкти на всіх рівнях ієрархії отримую int(0). Важкий робочий день поклав свій відбиток на продуктивності роботи і кожен наступний var_dump() писався все важче і важче
. Аж тут відчуваю як в мене волосся дибки стає на потилиці від побаченого. В мене замість присвоєння «=&» написано «&=». Відповідно наступний вираз є коректним і ніякої помилки PHP парсер не поверне а просто вираз поверне 0 (нуль) :
$this->driver &= new SiteDriver($db);
var_dump($this->driver)
Видасть: int(0)
Глюк дійсно важкий і чесно кажучи в великій системі його не так легко буде роздебагати. Чимось нагадує проблему з операторами присвоєння та порівняння (== vs =). І якщо остання проблема у більшості випадків вирішується заміною порівнюваних величин (де замість $a == 1 пишеться 1 == $a і можна отримати попередження парсера при допущеній помилці) , то в конкретно моєму випадку я ще не уявляю як можна було б хоча б якось попередтии таку очепатку
. Тому на далі будьмо обережніші.
Добре що аналогічної проблеми в PHP5 вже не виникне.
