Доступ объекта к своим свойствам
Как ни странно, но при изучении ООП "с нуля" программисты, привыкшие к структурному программированию, часто с трудом понимают, каким образом объект может добраться до своих собственных свойств. Рассмотрим, например, такую программу:
$Obj1=new Mysqltable;
$Obj2=new MysqlTable;
. . .
echo $Obj1->TableName, " ", $Obj2->TableName;
Здесь никаких проблем не возникает— ясно, что выводятся свойства разных объектов — мы же сами указали их до стрелки. Однако давайте посмотрим, что будет, если вызвать какой-нибудь метод одного из объектов:
$Obj1->Drop();
Как видите, при вызове метода так же, как и при доступе к свойству, нужно указать объект, который должен "откликнуться на запрос". Действительно, этой командой мы удаляем из базы данных таблицу $Obj1, а не $Obj2. Рассмотрим теперь тело метода Drop():
class MysqlTable {
function Drop()
{ сюда интерпретатор попадет, когда вызовется Drop() для
какого-то объекта
}
}
По логике, Drop() — функция. Эта функция, конечно, едина для всех объектов класса MysqlTable. Но как же метод Drop() узнает, для какого объекта он был вызван? Ведь мы не можем Drop() для $Obj1 сделать одним, а для $Obj2 — другим, иначе нарушился бы весь смысл нашей объектной ориентированности. В том-то вся и соль, что два различных объекта-таблицы являются объектами одного и того же класса...
Оказывается, для доступа к свойствам (и методам, т. к.
один метод вполне может вызывать другой) внутри метода используется специальная предопределенная переменная $this, содержащая тот объект, для которого был вызван метод. Теперь мы можем определить Drop() внутри класса так:
function Drop()
{ // сначала удаляем все записи из таблицы
$this->Delete("1=1"); // всегда истинное выражение
// а затем удаляем саму таблицу
mysql_query("drop table ".$this->TableName);
}
Если мы вызвали Drop() как $Obj1->Drop(), то $this будет являться тем же объектом, что и $Obj1 (это будет ссылка на $Obj1), а если бы мы вызвали $Obj2->Drop()[E151] , то $this был бы равен $Obj2. То есть метод всегда знает, для какого объекта он был вызван. Это настолько важно, что я повторю еще раз: метод всегда знает, для какого объекта он был вызван.
Использование ссылок говорит о том, что $this — не просто копия объекта-хозяина, это и есть
хозяин. Например, если бы в $Obj1->Drop() мы захотели изменить какое-то свойство $this, оно поменялось бы и у $Obj1, но не у $Obj2 или других объектов.
В синтаксисе PHP есть один просчет: запись вида
$ArrayOfObjects["obj"]->DoIt();
считается синтаксически некорректной. Вместо нее применяйте следующие две команды:
$obj=&$ArrayOfObjects["obj"]; $obj->DoIt();
Не забудьте про &
сразу после оператора присваивания (то есть создавайте ссылку на элемент массива), иначе метод DoIt()
будет вызван не для самого объекта, присутствующего в массиве, а для его копии, полученной в $obj!