| |
ра.
// В противном случае генерируется ошибка.
// Рекомендуется при создании таблицы для поля $field создать индекс.
function TableGetDistinct($field,$Expr="")
{ $this->Error="";
if(!$Expr) $Expr="1=1";
$r=mysql_query("select distinct $field from ".
Глава 31. Объектно-ориентированное программирование на PHP 477
$this->TableName." where ($Expr) and (id>1)");
// distinct НЕ работает вместе с order by! Почему — неясно...
if(!$r) { $this->Error=mysql_error(); return 0; }
for($Arr=array(),$i=0,$n=mysql_num_rows($r); $i<$n; $i++)
$Arr[]=mysql_result($r,$i,0);
return $Arr;
}
function GetDistinct($field,$Expr="")
{ return $this->TableGetDistinct($field,$Expr); }
}; // Конец класса
?>
А вот пример применения этого класса (листинг 31.3). Делает он следующее:
откры-
вает таблицу в некоторой базе данных (если таблицы с таким именем не существует,
создает ее) и добавляет одну пробную запись.
Листинг 31.3. Пример использования класса MysqlTable
include "librarian.phl"; // подключаем библиотекарь
Uses("MysqlTable"); // подключаем модуль с классом таблицы
// Устанавливаем соединение с базой данных
mysql_connect("localhost");
mysql_select_db("test");
// Открываем таблицу
$t=new MysqlTable("test",array("t"=>"int"));
// Добавляем запись
$d=array("t"=>time());
$t->Add($d);
// Работаем с блоком информации
$Inf=$t->GetInfo();
$Inf["a"]=@$Inf["a"]+1;
$Inf["b"]=@$Inf["b"]+10;
echo $Inf["a"]," ",$Inf["b"]," ";
$t->SetInfo($Inf);
// Выбираем все записи и выводим их
$d=$t->Select();
foreach($d as $id=>$Data) {
echo "$id: ".$Data['t']." ";
Часть V. Приемы программирования на PHP 478
}
?>
Попробуйте запустить этот сценарий (естественно, сделав так, чтобы ему был
досту-
пен библиотекарь), а затем понажимать кнопку Обновить в браузере. Вы должны
увидеть, что информация действительно накапливается в базе данных.
Копирование объектов
Так уж устроен PHP, что в нем все переменные, в том числе и объекты (а что
такое
объект, как не переменная определенного класса?), всегда рассматриваются как
про-
стой набор значений и копируются целиком. Например, если у нас есть громадный
массив $A и мы выполняем оператор $B=$A, то все содержимое $A будет скопировано
в $B один-в-один. Возможно, это как раз то, что и требуется, но вот с объектами
сложных классов все обстоит совсем иначе. Предположим, например, что мы выпол-
нили команды:
$Obj1=new MysqlTable("test");
$Obj2=$Obj1;
$Obj1->Drop();
Объект-таблица $Obj1 благополучно уничтожится и пометит в своих свойствах, что
он
уничтожен, и больше использоваться не должен, но вот $Obj2 об этом и не
"догадается".
$Obj2 по-прежнему будет "считать", что он — "единственный и неповторимый"
объект,
привязанный к существующей таблице test, и будет честно пытаться выполнить с
ней
какие-то операции по запросам.
Этого, к сожалению, нельзя избежать в PHP. А именно, мы не можем никак контро-
лировать процесс копирования объектов. И в этом — безусловная слабость PHP. Так
что будьте особенно бдительны.
Ссылки и интерфейсы
Как мы знаем, в PHP оператор присваивания всегда копирует значения переменных,
какой бы сложной структуры они ни были. Это же, напомню, происходит и с объек-
тами. Что тогда получится, если мы скопируем, например, объект класса
MysqlTable? Вообще говоря, ничего хорошего. Произойдет дублирование всех
свойств и методов объекта. Фактически, мы получим сразу две независимые
"обертки" для одной и той же таблицы MySQL. Таким образом, изменения, внесен-
ные в первый объект, никак не повлияют на второй, и наоборот.
Я специально проектировал класс MysqlTable так, что даже после копирования объ-
ектов этого типа не происходило никаких фатальных недоразумений описанного вы-
ше рода. Однако так можно сделать далеко не всегда. Представьте, например, что
Глава 31. Объектно-ориентированное программирование на PHP 479
нам приходится очень часто использовать функцию GetInfo() и довольно редко —
SetInfo(). Так как GetInfo() при каждом запросе обращается к MySQL, мы мо-
жем получить здесь ощутимый проигрыш в быстродействии. Очевидное решение за-
ключается в промежуточном хранении данных, возвращаемых нашим "обычным"
методом GetInfo() в специальном свойстве объекта. Действительно, зачем загру-
жать сервер лишней работой по чтению
|
|