Запросы в PHP
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
В предыдущем уроке мы познакомились с основами языка SQL и теперь попробуем применить эти знания на практике.
Все запросы в PHP в основном выполняются с помощью функции mysql_query(). Функция принимает два параметра: строку запроса и идентификатор подключения, полученный после вызова mysql_connect(). В принципе, идентификатор подключения можно не указывать, тогда будет использоваться последнее сделаное подключение. Но такой подход чреват ошибками в сложных скриптах с несколькими одновременными подключениями к различным базам.
В качестве первого примера выберем все строки из нашей таблицы:
<?php $sql = 'SELECT id, user_ip, user_agent FROM user_tracker'; $qry = mysql_query($sql, $dblink); if(!$qry) { echo 'Ошибка выполнения запроса: ' . mysql_error(); exit(); } // обрабатываем результаты запроса ?>
Функция mysql_query() позвращает ссылку на результаты выполнения запроса. Если запрос завершился с ошибкой - функция вернёт false, после чего текст ошибки можно будет получить вызовом функции mysql_error(), а номер ошибки - функцией mysql_errno().
Для получения отдельной записи из результатов запроса необходимо воспользоваться одной из fetch-функций (функции получения данных). Их несколько и каждая удобна в своём случае.
mysql_fetch_array($result, $type) |
|
|
$result - это переменная, полученная после вызова mysql_query() Параметр $type описывает формат возвращаемых данных. Может принимать одно из трёх значений: MYSQL_NUM. Функция возвращает нумерованный массив, где нулевой элемент - значение нулевого поля, первый элемент - значение первого поля и т.д. (поля считаются "слева направо" в том порядке, в котором были объявлены в запросе): <?php ... $row = mysql_fetch_array($qry, MYSQL_NUM); echo "IP-адрес пользователя: " . $row[1]; echo "Используемый браузер: " . $row[2]; ... ?> MYSQL_ASSOC. Функция возвращает ассоциативный массив, в котором элемент с именем поля содержит значение этого поля. <?php ... $row = mysql_fetch_array($qry, MYSQL_NUM); echo "IP-адрес пользователя: " . $row['user_ip']; echo "Используемый браузер: " . $row['user_name']; ... ?> MYSQL_BOTH. Возвращается массив, в котором можно одновременно обращаться к данным и по номеру и по имени. <?php ... $row = mysql_fetch_array($qry, MYSQL_NUM); echo "IP-адрес пользователя: " . $row[1]; echo "Используемый браузер: " . $row['user_agent']; ... ?>
|
mysql_fetch_assoc ( $result ) |
|
Функция польностью аналогична функции mysql_fetch_array() с указанием типа MYSQL_ASSOC. |
|
mysql_fetch_row ( $result ) |
|
Функция польностью аналогична функции mysql_fetch_array() с указанием типа MYSQL_NUM. |
|
mysql_fetch_object ( $ result ) |
|
Функция возвращает объект, содержащий свойства, одноимённые полям результатов запроса. Значения этих свойств всегда текстового типа и равны значению соответствующего поля. <?php ... $row = mysql_fetch_object($qry); echo "IP-адрес пользователя: " . $row->user_ip; echo "Используемый браузер: " . $row->user_agent; ... ?>
|
|
Все fetch-функции работают по одному алгоритму. При первом вызове функция проверяет наличие строк и если результат запроса не пустой - возвращает первую строку и переводит указатель текщей строки на следующую запись. При каждом последующем вызове функция возвращает пользователю текущую строку и переходит к следующей. Если достигнута последняя строка и передавать больше нечего - функция возвращает false.
Таким образом, цикл перебора всех записей будет выгядеть так:
<?php ... // получаем первую строку $row = mysql_fetch_object($qry); while ($row) { // обрабатываем полученные данные echo "IP-адрес пользователя: " . $row->user_ip; echo "Используемый браузер: " . $row->user_agent; // получаем следующую строку $row = mysql_fetch_object($qry); } ... ?>
Иногда возникает необходимость передвигаться по записям не только "вперёд", но и "назад", т.е. по направлению от текущей строки к первой. В этом случае надо использовать функцию mysql_data_seek(), которая позволяет перейти к записи с заданным номером.
<?php ... // $x - требуемый номер строки $x = 100; if(mysql_data_seek($qry, $x)) echo 'успешно перешли к строке №' . $x; else echo 'перейти к строке №' . $x . ' не удалось'; ... ?>
Значение номера строки должно быть в диапазоне от 0 до количества строк в результатах запроса. Количество строк можно узнать при помощи функции mysql_num_rows (). С учётом этого, можно переписать предыдущий пример в более безопасной форме:
<?php ... // $x - требуемый номер строки $x = 100; if($x < mysql_num_rows($qry)) mysql_data_seek($qry, $x); else echo "перейти к строке №" . $x . " не удалось." . "Строка с таким номером не существует."; ... ?>
Однако mysql_num_rows() применима только к результатам выполнения SELECT. При выполнении всех остальных команд (INSERT, UPDATE и DELETE) функция возвращает 0 (ведь сервер не возвращал ни одной строки). Чтобы определить, сколько строк было вставлено, изменени или удалено при выполнении последнего запроса необходимо воспользоваться функцией mysql_affected_rows().
Например, следующий код помогает узнать результаты очистки таблицы:
<?php $sql = "DELETE FROM user_tracker"; $qry = mysql_query($sql, $dblink); if($qry) echo 'Удалено ' . mysql_affected_rows() . ' строк.'; else 'Ошибка удаления: ' . mysql_error(); ?>
Если вам необходимо узнать значение автоинкрементного поля для только что вставленной записи - воспользуйтесь функцией mysql_insert_id().
<?php $sql = "INSERT user_tracker (session_id, enter_dt, 'user_ip') ". "VALUES('ahduyfis', NOW(), '192.168.10.33')"; $qry = mysql_query($sql, $dblink); if($qry) { echo 'Добавлена запись с id = ' . mysql_insert_id($dblink); } else 'Ошибка добавления: ' . mysql_error(); ?>
Как уже говорилось ранее - все текстовые значения в запросах записываются в одинарных кавычках. Но очень часто возникает ситуация, когда необходимо занести строку, в которой уже есть кавычки (например, пароль вида "my'1super'2password"). Если попробовать внести её в исходном виде, то MySQL не сможет обработать запрос и выдаст соответствующую ошибку. Чтобы этого избежать необходимо предварительно подготовить строку к занесению. Для этого применяется функция mysql_real_escape_string(). Она преобразует все служебные и нечитаемые символы в соответствующие им спецсимволы, такие как \x00, \n, \r и т.п.
Обязательная проверка всех данных перед занесением в таблицу не только является признаком "хорошего тона" среди программистов, но и является насущной необходимостью для защиты сайта от взлома и хищения данных.
<?php $session_id = mysql_real_escape_string('ahduyfis'); $user_ip = mysql_real_escape_string('192.168.10.33'); $sql = "INSERT user_tracker (session_id, enter_dt, 'user_ip') ". "VALUES($session_id, NOW(), $user_ip)"; ... ?>
При написании сложных запросов лучше всего предварительно запрос испытать при помощи сторонних программ, а только потом добавлять его в код. Такой подход существенно облегчает тестирование как запроса, так и скрипта в целом.