
PHP5_nachinayushim
.pdf



Введение в базы данных и SQL 417
Резюме
Вданной главе рассматривались модели хранения информации, базы данных
инаиболее жизнеспособные варианты хранения больших массивов данных, а также был дан краткий обзор преимуществ систем управления реляционными базами данных (СУРБД). Кроме того, в главе обсуждались такие проблемы, как производительность, работоспособность и безопасность. В главе объясняется, почему свободно доступная СУРБД MySQL является серьезным кандидатом для применения в большинстве при+ ложений, использующих базы данных.
Еще раз кратко опишем преимущества реляционных баз данных с клиент/сервер+ ной архитектурой (которую поддерживают не все СУРБД):
производительность: нормализация баз данных значительно увеличивает про+ изводительность;
многопользовательская среда: единственным ограничением, налагаемым на коли+ чество одновременно подключающихся пользователей, является тип приобретен+ ной лицензии и/или производительность имеющегося аппаратного обеспечения;
доступность: сетевая СУРБД может обрабатывать запросы ‘‘в реальном времени’’, в любое время делая доступными актуальные данные; иначе говоря, при необхо+ димости к такой базе данных можно получить доступ отовсюду и в любой момент;
безопасность: жизненно важным является управление доступом к данным по+ средством хорошо организованной схемы обеспечения безопасности; напри+ мер, система MySQL не предоставляет непосредственный доступ к каким+либо сохраненным в ней данным, обеспечивая таким образом безопасность инфор+ мации на более высоком по сравнению с операционной системой уровне; поль+ зователь, не имеющий необходимых привилегий, не может выполнять несанк+ ционированные операции с данными;
надежность: когда речь идет о программном обеспечении, степень надежности, как правило, измеряется частотой таких отказов продукта в течение срока службы, которые требуют перезапуска; например, MySQL порождает дочерние процессы для обработки одновременных запросов; когда дочерний процесс ра+ ботает неверно и в конечном итоге останавливается, он редко тянет за собой весь сервер баз данных, таким образом, сводя к минимуму свое влияние на це+ лостность данных в базе.
Подведем итог: планируя разработку целевых многопользовательских Web+прило+ жений, в качестве сервера для хранения данных стоит рассматривать сетевую СУРБД.
В этой главе также рассматривалась установка MySQL+сервера и основы SQL ++++++
языка структурированных запросов, на котором основана система MySQL. В главе описывались некоторые основные SQL+запросы ++++++ SELECT, INSERT, REPLACE, DELETE и UPDATE, а также права доступа в MySQL.
Любой сценарий, в котором для подключения к MySQL+серверу используются PHP+ функции, позволяет выбрать определенную информацию в базах данных сервера. В главе описывалось несколько способов для обработки ошибок, возникающих в MySQL+сервере; рассматривалось создание и модификация таблиц с помощью SQL+ операторов, а также заполнение таблиц в базе данных информацией, которую можно будет использовать в последующих главах.

10
Получение данных от MySQL с помощью PHP
До сих пор основное внимание в книге уделялось проверке соединения с MySQL либо через клиентскую программу, либо посредством MySQL+функций PHP, а также созданию таблиц и заполнению их данными. Одним из первых SQL+операторов, ко+ торые описывались в главе 9, был базовый оператор SELECT. Чтобы точно опреде+ лить, какие данные должна возвращать база, можно использовать множество других операторов. В этой главе описываются способы получения доступа к данным, храня+ щимся в MySQL+базе данных, из PHP+сценариев.
Вначале следует рассмотреть PHP+функции, предназначенные для получения данных,
азатем изучить методику формирования SQL+операторов SELECT, позволяющих получить доступ к необходимым данным, упорядоченным так, как нужно для работы приложения.
Затем будет рассмотрена возможность ограничения количества возвращаемых ре+ зультатов, а также их упорядочение и группировка. Кроме того, в учебных примерах данной главы создается сценарий для просмотра пользовательских записей, позво+ ляющий просматривать таблицы созданной в предыдущей главе базы данных.
Получение данных с помощью PHP
При использовании SELECT+операторов с функцией mysql_query() результи+ рующее множество (которое также можно отобразить в командной строке mysql) пе+ редается в память, и возвращается идентификатор результата. Обычно этот иденти+ фикатор сохраняется в переменной, например, $result, и используется для указания результирующего множества в последующих вызовах функций.
Ранее уже было показано, как функция mysql_fetch_row() возвращает одну строку из результирующего множества. В простом примере из предыдущей главы ис+ пользуется цикл while для поочередного вывода каждой строки результирующего

Получение данных от MySQL с помощью PHP 419
множества, созданного оператором SHOW DATABASES. Ниже приводится усовершен+ ствованная версия сценария show_db.php, которая распечатывает информацию из таблицы user базы данных sample_db:
<?php include "./common_db.inc";
$link_id = db_connect('sample_db');
$result = mysql_query("SELECT * FROM user", $link_id);
while($query_data = mysql_fetch_row($result)) {
echo "'",$query_data[1],"' - ",$query_data[4],"<br>";
}
?>
Сценарий возвращает следующий вывод:
'Nicrot' - Mid
'Spargy' - Mid
'Pads' - Winger
'Dodge' - Link
'Mac' - Winger 'Greeny' - Utility back
Сначала сценарий подключается к серверу с помощью функции db_connect (которая определена в подключаемом файле common_db.inc), указывая необходимую базу данных sample_db. Затем выполняется SQL+оператор “SELECT * FROM user”, результи+ рующее множество которого представляет собой все содержимое таблицы user.
В переменной $result хранится возвращаемый идентификатор результата, с по+ мощью которого в вызове функции mysql_fetch_row() указывается результирую+ щее множество. Данная функция в свою очередь выбирает первую строку результата, из которой затем выводятся второе и четвертое поля (userid и userposition, со+ ответственно). После этого внутренний указатель перемещается к следующей строке результата, а цикл while продолжается до тех пор, пока не будут выбраны все содер+ жащиеся в таблице строки.
Достичь того же результата можно более эффективным способом:
$result = mysql_query("SELECT userid, userposition FROM user", $link_id);
while($query_data = mysql_fetch_row($result)) {
echo "'",$query_data[0],"' - ",$query_data[1],"<br>";
}
Извлекая из таблицы только те поля, которые нужны, можно сэкономить время
ипамять.
ВPHP имеется еще две функции, которые можно использовать для выборки дан+ ных: mysql_fetch_array и mysql_fetch_object(). Обе они работают в основном аналогично функции mysql_fetch_row(), единственное отличие заключается в ти+ пе возвращаемых данных. Лучше всего это можно проиллюстрировать на примере кода для выборки значений из результирующего множества.
Функция mysql_fetch_array()() возвращает из результирующего множества один ассоциативный массив, сохраняя каждое значение в элементе, имя которого со+ ответствует имени поля:
while($query_data = mysql_fetch_array($result)) { echo "'",$query_data["userid"],"' - ", $query_data["userposition"],"<br>";
}

420 Глава 10
Функция mysql_fetch_object() возвращает один объект из результирующего множества, сохраняя каждое значение как свойство данного объекта. Свойства име+ нуются согласно именам полей:
while($query_data = mysql_fetch_object($result)) { echo "'",$query_data->userid,"' - ", $query_data->userposition,"<br>";
}
Две эти функции особенно полезны в ситуациях, когда необходимо изменить структуру таблиц базы данных. Если не изменять имена полей, то можно не беспоко+ иться о порядке, в котором они появляются в таблице, потому что можно извлечь значение поля, указав его имя, а не индекс. Хотя обе функции работают медленнее, чем mysql_fetch_row(), они обладают одним дополнительным преимуществом ++++++
эти функции делают сценарии более читабельными (например, впоследствии в коде большого приложения можно перепутать поля, если указывать только их индексы).
Существует еще одна функция, заслуживающая внимания: mysql_result(), кото+ рая возвращает значение определенного поля в определенной записи. В качестве ар+ гументов данная функция принимает, как обычно, идентификатор результата, а также номер строки и имя поля. Можно переписать приведенный выше пример так:
$result = mysql_query("SELECT * FROM user", $link_id);
for($i =0; $i < mysql_num_rows($result); $i++){
echo "'", mysql_result($result, $i, "userid"),"' - ", mysql_result($result, $i, "userposition"),"<br>";
}
Можно также выводить значения в обратном порядке:
$result = mysql_query("SELECT * FROM user", $link_id);
for($i = mysql_num_rows($result)-1; $i >=0; $i--){
echo "'", mysql_result($result, $i, "userid"),"' - ", mysql_result($result, $i, "userposition"),"<br>";
}
В этом случае результирующее множество будет таким:
'Greeny' - Utility back 'Mac' - Winger
'Dodge' - Link
'Pads' - Winger
'Spargy' - Mid
'Nicrot' - Mid
Имя поля также можно указать в виде целого числа, представляющего смещение поля:
echo "'", mysql_result($result, $i, 1),"' - ", mysql_result($result, $i, 3),"<br>";
Другой способ перемещения к заданной строке данных заключается в использова+ нии функции mysql_data_seek(). Она работает аналогично функции fseek(), ко+ торая использовалась в примерах главы 7 для навигации в файловом потоке. Эта функция в качестве аргументов принимает дескриптор результата и целое число, представляющее позицию в результирующем множестве, к которой необходимо пе+ рейти. Как можно предположить, данная функция возвращает True в случае успешно+ го перемещения и False при переходе за границу массива. Сохраните следующий код в файле show_seek.php и откройте его в браузере:

Получение данных от MySQL с помощью PHP 421
<?php
include "./common_db.inc";
$link_id = db_connect('sample_db');
$result = mysql_query("SELECT * FROM user", $link_id);
for($i = mysql_num_rows($result)-1; $i >=0; $i--){
mysql_data_seek($result, $i);
$query_data = mysql_fetch_array($result); echo "'", $query_data["userid"], "' - ", $query_data["username"], "<P>";
}
?>
В этом разделе были рассмотрены различные способы доступа к результирующему множеству из PHP+сценариев. Эти методики помогают найти решение в различных ситуациях и вывести необходимые данные, представленные в том порядке, который требуется. Однако это еще далеко не все.
Известно, что повысить эффективность сценариев можно путем сохранения не+ больших размеров результирующего множества. В приведенных примерах для этого указывались необходимые поля в исходном SELECT+операторе, например:
$result = mysql_query("SELECT userid, username FROM user", $link_id);
Однако при отображении результатов этого запроса в другом порядке могут воз+ никнуть некоторые проблемы. Допустим, что данные нужно выводить в обратном или в алфавитном порядке. Хлопот можно избежать, если упорядочить данные, посту+ пающие в результирующее множество. На самом деле существует множество вариан+ тов обработки данных, эффективность которых, как по времени выполнения, так и по сложности, почти наверняка будет выше, если использовать хорошо продуман+ ные SQL+запросы, а не специальные PHP+функции. По этой причине следует вернуть+ ся к mysql+клиенту и рассмотреть возможности, предоставляемые командой SELECT.
SQL-операторы для выборки данных
Рассмотрим команду SELECT подробнее. Обратите внимание, что все описывае+ мые здесь команды полностью применимы к предыдущим примерам с использовани+ ем PHP ++++++ таблица, отображаемая в командной строке, представляет собой просто эк+ ранное представление результирующего множества, с которым в конечном итоге должен работать PHP+сценарий.
Серверные функции
Вернемся к основам и попытаемся вводить SELECT+запросы, которые вообще не требуют наличия таблицы базы данных. MySQL обладает множеством весьма полез+ ных встроенных серверных функций. Например, чтобы узнать текущее время, можно ввести следующую команду:
mysql> SELECT now(); |
|
||
+---------------------------- |
|
|
+ |
| now() |
|
| |
|
+---------------------------- |
|
|
+ |
| 2004-08-03 |
16:56:03 |
| |
|
+---------------------------- |
|
|
+ |
1 |
row in set |
(0.00 sec) |
|


Получение данных от MySQL с помощью PHP 423
| Dodge |
| Dave Mercer |
| |
| Mac |
| Murray McCallum |
| |
| Greeny |
| Mark Greenfield |
| |
+-------- |
+-------------------------- |
+ |
6 rows in set (0.00 sec)
Все поля таблицы можно просмотреть, используя символ *:
mysql> SELECT * FROM user;
Это эквивалентно указанию каждого поля таблицы. Однако при написании при+ ложений рекомендуется избегать такой формы записи, даже когда действительно требуется извлечь значения всех полей таблицы. Если позднее структура таблицы бу+ дет изменена, и добавятся новые поля или изменится их порядок, то может оказаться, что приложение получает совсем не то результирующее множество, которое ожидает, а это может привести к непредсказуемым результатам. Ниже описываются различные способы применения SQL для более четкого определения результирующего множества.
Ограничение количества возвращаемых результатов
Сузить массив извлекаемых данных можно с помощью SQL+предложений LIMIT и WHERE. Предположим, что необходимо заставить MySQL+сервер извлечь только не+ сколько записей из таблицы. Для этого используется предложение LIMIT. Например, чтобы выбрать первые две строки соответствующих данных, начиная с записи 0, можно ввести следующую команду:
mysql> SELECT userid, username FROM user LIMIT 0, 2;
+-------- |
+------------------- |
+ |
| userid | username |
| |
|
+-------- |
+------------------- |
+ |
| Nicrot | Nic Malan |
| |
|
| Spargy | Andrew Sparg |
| |
|
+-------- |
+------------------- |
+ |
2 |
rows in set (0.00 sec) |
|
Если начальная запись не указана, то по умолчанию используется 0, поэтому сле+ дующий запрос достигает той же цели:
mysql> SELECT userid, username FROM user LIMIT 2;
Предложение LIMIT всегда записывается в конце запроса.
Предложение WHERE используется для выборочного получения строк данных, со+ ответствующих определенным условиям. Например, чтобы получить данные об игро+ ках, занимающих позицию Mid, можно ввести следующую команду:
mysql> SELECT userid, username FROM user
|
-> WHERE userposition = 'Mid'; |
|
+-------- |
+------------------ |
+ |
| userid | username |
| |
|
+-------- |
+------------------ |
+ |
| Nicrot | Nic Malan |
| |
|
| Spargy | Andrew Sparg |
| |
|
+-------- |
+------------------ |
+ |
2 |
rows in set (0.00 sec) |
|
Знак равенства используется для указания условия (в данном примере Mid). Не считая оператора равенства, который эквивалентен PHP+оператору ==, операторы сравнения в предложениях WHERE выглядят почти так же, как операторы сравнения в PHP. В приведенной ниже таблице показаны операторы сравнения в MySQL.