Druzya.org
Возьмемся за руки, Друзья...
 
 
Наши Друзья

Александр Градский
Мемориальный сайт Дольфи. 
				  Светлой памяти детей,
				  погибших  1 июня 2001 года, 
				  а также всем жертвам теракта возле 
				 Тель-Авивского Дельфинариума посвящается...

Библиотека :: Компьютеры и Программирование :: Котеров Д. В. - Самоучитель PHP 4
<<-[Весь Текст]
Страница: из 287
 <<-
 
дних и тех же данных, когда можно хранить 

их в программе и сразу же использовать? Это свойство будет инициализироваться 
при конструировании объекта класса MysqlTable и обновляться каждый раз при 
обращении к методу SetInfo(). 
То есть наше свойство будет представлять собой аналог "зеркала" записи в 
таблице MySQL, по аналогии с "зеркалами" сайтов в Интернете. Класс 
MysqlTable должен следить за тем, чтобы оно всегда содержало актуальные 
данные — те же самые, что и в реальной таблице. 
Но, к сожалению, описанная схема не может быть реализована в PHP напрямую, и 
именно по причине обязательного полного копирования переменных. Вот пример, 
который породит ошибку: 
$t1=new MysqlTable("MyTable"); 
. . . 
function DoIt($t) 
{ $t->SetInfo("This is the new info!"); 
} 
. . . 
$t=new MysqlTable("MyTableName"); 
$t->SetInfo("Data"); 
DoIt($t); 
$Inf=$t->GetInfo(); // в $Inf будет строка Data! 
Впрочем, в приведенном только что фрагменте это недоразумение можно легко пре- 
одолеть, передав функции ссылку на объект: 
function DoIt(&$t) 
{ $t->SetInfo("This is the new info!"); 
} 
Я намеренно привел здесь пример, когда ограничение на копирование объектов все 
же можно обойти относительно безболезненно. Настало время описать неразрешимую 
(во всяком случае, похожим методом) задачу. Но прежде обратите внимание, что в 
нашем примере объект передается "вглубь" кода (внутрь функции), а не "наружу" 
(из 
функции). Вот как раз в последнем случае и будет возникать неразрешимая 
проблема. 

Часть V. Приемы программирования на PHP 480 
Но обо всем по порядку. Чтобы чуть сгустить краски и не вдаваться в абстрактные 

рассуждения, давайте предположим, что наш класс MysqlTable вообще не допускает 
копирования его объектов, а при случайном выполнении такого копирования 
работает 
совершенно неправильно. Нужно заметить, что это не так уж и далеко от истины, 
особенно если мы используем MysqlTable не напрямую, а как базовый для какого-то 

другого типа (например, для класса форума). 
Мы знаем, что в таком случае объекты этого класса можно передать без побочных 
эффектов внутрь функций по ссылке. Сейчас мы остановимся на обратном процессе. 
Итак, пусть мы написали более-менее универсальный модуль, в котором есть 
единст- 
венная интерфейсная функция OpenTable(), создающая новую таблицу в базе дан- 
ных и, соответственно, новый объект класса MysqlTable. Специфика этой функции в 

том, что в случае, если таблица существует, новый объект не создается, а 
возвращает- 
ся уже имеющийся. Иными словами, для двух вызовов функции с одинаковыми па- 
раметрами должен быть возвращен один и тот же объект, а не две его копии. 
Возможно, вы спросите: зачем нам вообще такая функция, когда можно вос- 
пользоваться оператором new напрямую? Тогда еще раз перечитайте предпо- 
следнюю фразу предыдущего абзаца: "В случае, если таблица уже существует, 
новый объект не создается". В то же время оператор new всегда создает но- 
вый объект, что нам, конечно, не подходит. Ведь мы договорились никогда не 
иметь в программе двух разных объектов, связанных с одной и той же табли- 
цей. 
Легко сказать — "возвращает уже существующий объект", но несколько сложнее — 
реализовать это. Рассмотрим два различных способа, с помощью которых мы можем 
достичь цели. 
Как следует из законов Мэрфи, "у любой сложной задачи всегда имеется одно 
простое, красивое и легкое для понимания… неправильное решение". В нашем 
случае это будет возврат из функции объекта класса MysqlTable "обычным" 
способом, подразумевающим копирование. Но ведь, по имеющейся между на- 
ми договоренности, объекты этого класса нельзя копировать! 
Возврат ссылки на объект 
Первый прием связан с новой возможностью PHP версии 4 — ссылочными перемен- 
ными. Помните, в части III этой книги мы говорили, что функция может возвращать 

ссылку на переменную (объект), а не только копию переменной?.. В нашем случае 
это 
оказывается довольно удобно. Вот как могла бы выглядеть функция OpenTable() и 
использование для нее
 
<<-[Весь Текст]
Страница: из 287
 <<-