| |
хорош.
И наоборот. Впрочем, совсем абстрагироваться от SQL нам все же не удастся —
все-
таки нужно знать правила составления выражений для выборки и удаления записей,
для их сортировки и т. д. Но это уже не SQL, а что-то гораздо более простое и
интуи-
тивно понятное.
Доступ объекта
к своим свойствам
Как ни странно, но при изучении ООП "с нуля" программисты, привыкшие к струк-
турному программированию, часто с трудом понимают, каким образом объект может
добраться до своих собственных свойств. Рассмотрим, например, такую программу:
$Obj1=new Mysqltable;
Глава 31. Объектно-ориентированное программирование на PHP 459
$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(), то $this был бы равен $Obj2. То есть метод всегда знает, для какого
объекта он был вызван. Это настолько важно, что я повторю еще раз: метод всегда
знает, для какого объекта он был вызван.
Использование ссылок говорит о том, что $this — не просто копия объекта-хозяина,
это и есть хозяин. Например, если бы в $Obj1->Drop() мы захотели изменить ка-
Часть V. Приемы программирования на PHP 460
кое-то свойство $this, оно поменялось бы и у $Obj1, но не у $Obj2 или других
объ-
ектов.
В синтаксисе PHP есть один просчет: запись вида
$ArrayOfObjects["obj"]->DoIt();
считается синтаксически некорректной. Вместо нее применяйте следующие две ко-
манды:
$obj=&$ArrayOfObjects["obj"]; $obj->DoIt();
Не забудьте про & сразу после оператора присваивания (то есть создавайте
ссылку на элемент массива), иначе метод DoIt() будет вызван не для самого
объекта, присутствующего в массиве, а для его копии, полученной в $obj!
Инициализация объекта.
Конструкторы
До сих пор мы не особенно задумывались, каким образом были созданы объекты
$Obj1 и $Obj2 и к какой таблице они прикреплены. Однако вполне очевидно, что
эти
объекты не должны существовать сами по себе — это просто не имеет смысла. По-
этому нам, наравне с уже описанными методами, придется написать еще один — а
именно, метод, который бы:
r "привязывал" только что созданный объект-таблицу к таблице в MySQL;
r сбрасывал индикатор ошибок;
r заполнял свойство Fields;
r делал другую работу по инициализации объекта.
Назовем это метод, например, Init():
class MysqlTable {
. . .
// Привязывает объект-таблицу к таблице с именем $TblName
function Init($TblName)
{ $this->TableName=$TblName;
$this->Error=0;
получаем и заполняем $this->Fields
}
}
. . .
$Obj=new MysqlTable; $Obj->Init("test");
Глава 31. Объектно-ориентированное программирование на PHP 461
А вдруг между вызовами new
|
|