Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 [ 154 ] 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

Полноценный класс таблицы MySQL

Я ранее обещал, что в каждой главе части V книги обязательно будет присутствовать пример нетривиального кода на PHP, который (или идеи из которого) вы сможете использовать в своих программах. На этот раз "исходник" оказался особенно большим, но это с лихвой оправдывается его функциональностью. Сейчас мы с вами разработаем полноценный класс, который существенно облегчает работу с таблицей MySQL, в значительной степени абстрагируя программиста не только от специфики этой СУБД, но и вообще от сложностей SQL-запросов. С помощью этого класса даже начинающий программист сможет построить форум, гостевую книгу, да и вообще любую программу, которая требует структурированного хранилища данных большого объема. Правда, для того, чтобы извлекать максимальную выгоду из использования класса, придется разобраться в механизме наследования, вкратце описанном чуть выше. Впрочем, класс прекрасно работает и сам по себе. Вот его некоторые отличительные черты.

□ Кодирование и декодирование данных производится автоматически. Программисту не нужно заботиться о том, чтобы ставить слэши перед апострофами и другими специальными символами. Все, что от него требуется, - передать той или иной функции массив, представляющий собой запись.

□ Таблица является с точки зрения программиста набором записей совершенно произвольной структуры (с произвольным числом полей). При создании таблицы указываются лишь ее несущие поля, по которым можно в будущем вести поиск, сортировку и т. д. Все остальные поля перед помещением записи в таблицу

MySQL-таблицу, наверное, разумным будет их немного "почистить" - убрать лишние пробелы, HTML-тэги и т. д. Конечно, такой корректировке должны быть подвержены все поля книги. Поэтому класс MysqlTable перед помещением очередной записи в таблицу будет вызывать виртуальную функцию PreModify() , передавая ей в параметрах запись, которая должна быть откорректирована. Естественно, в классе Guestbook эта функция должна переопределяться - так, чтобы выполнять требуемые действия по коррекции записи перед ее занесением в таблицу. Конечно, класс MysqlTable не "знает", как именно будет переопределена PreModify() в производном от него классе, поэтому сам он содержит функцию PreModify() , не делающую ничего (то есть с пустым телом).

Примечание

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



подвергаются сериализации, а при чтении из таблицы - восстановлению, "прозрачно" для вызывающей программы.

□ В то же время имеется возможность добавления/удаления несущих столбцов " на лету", т. е. без какого бы то ни было специального запроса пользователя. Достаточно изменить список несущих полей при создании/открытии таблицы. Класс сам определяет, что именно изменилось, и применяет соответствующие действия по корректировке (вызывает нужные команды SQL).

□ Поддерживается одно автоинкрементное поле с именем id, которое автоматически проставляется у записи при ее добавлении в таблицу. Указывать его в списке несущих полей не надо.

□ Имеется набор стандартных операций, которые можно производить с таблицей: ее создание и удаление, вставка новой записи, обновление записи, удаление записей, выборка указанного числа записей с сортировкой. Кроме того, поддерживаются дополнительные операции, такие как подсчет числа записей, удовлетворяющих запросу, и получение всех уникальных значений в указанном столбце таблицы.

□ Для каждой таблицы можно хранить один дополнительный блок информации любой структуры (например, это может быть даже многомерный ассоциативный массив). Выборка и запись этого блока осуществляются методами GetInfo() и SetInfo(). Блок информации нельзя получить никак иначе, кроме как посредством этих двух функций (он "не виден" даже для функции выборки).

□ Для убыстрения работы программист может назначить для тех или иных столбцов таблицы режим индексирования (при использовании индекса MySQL тратит значительно меньше времени на поиск данных). Индексы, как и несущие поля, вставляются и удаляются автоматически при изменении параметров вызова конструктора. Помните, что хотя они и убыстряют работу, но зато занимают на диске довольно много места.

У этого класса есть один небольшой недостаток, который заставляет применять его аккуратно. Так как количества и размеры полей при вставке могут быть любыми, то злоумышленник может быстро "забить" таблицу разного рода "мусором". Например, если таблица используется как хранилище для гостевой книги, то он может видоизменить форму отправки сообщения и вставить туда какое-нибудь текстовое поле, предварительно поместив в него пару мегабайтов текста. Чтобы избежать этой потенциальной "дыры" в защите, рекомендуется перед вставкой записи в таблицу проверять, какой объем она занимает в сериализованном виде, и в случае превышения определенного числа байтов выводить предупреждение и завершать сценарий по die() . Думаю, читатель сам без труда добавит такую возможность в свои сценарии или же прямо в класс MysqlTable.

Согласитесь, не так уж и мало для каких-то четхрехсот строчек кода...... Листинг

31.2 представляет собой исходный текст библиотеки, реализующей наш класс. Она предполагает, что соединение с MySQL уже открыто и выбрана верная текущая база данных.



! Листинг 31.2. Полноценный класс MySQL-таблицы

<?

MysqlTable - "прозрачная работа" с таблицей MySQL. Класс MysqlTable обычно делают базовым для какого-нибудь другого класса (например, CGuestBook), и переопределяют нужн1е функции.

Поле для хранения сериализованных полей ( снаружи " не видно") define("DataField"," data ");

******************* Вспомогательн1е функции ******************* Если переменная пуста, инициализирует ее

function Def0(&$st,$def) { if(!isSet($st)$st=="") $st=$def; } Подготавливает строку двоичн1х данн1х для помещения в таблицу. function Apostrophs(&$st) { $st=str replace(chr(0),"\\0",$st);

$st=ereg replace("\\\\","\\\\",$st);

$st=ereg replace("","\\",$st);

return $st;

Упаков1вает объект и превращает его в строку. function SqlPack(&$obj)

{ $s=Serialize($obj); return Apostrophs($s); }

Распаков1вает строку и создает объект.

function SqlUnpack(&$st) { return Unserialize($st); }

****************************************************************

*** Далее идет описание класса таблицы.

Каждая запись таблицы, помимо тех полей, которые указаны в

конструкторе, будет иметь еще два поля - id ( уникальный

идентификатор записи) и data ( упакованный массив

всех остальных полей). Кроме того, в запись можно вводить

произвольные поля - они тоже будут сохраняться, но по

ним нельзя будет вести поиск ( предложение "select"),

потому что эти поля будут автоматически сериализованы при

добавлении/изменении записи и распакованы при извлечении.

class MysqlTable {

*** Внутренние переменные

var $TableName; имя таблицы

var $UniqVars; список уникальн1х полей (имя=1, имя=1...)

var $Index; для этих полей построены индексы ( имя=1, имя=1... )



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 [ 154 ] 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189