проверка выполнения запроса mysql php
Проверка выполнения запроса mysql php
Пример #1 Выполнение запросов
Буферизация результатов запроса
После выполнения запроса результаты можно либо получить сразу, либо считать строку за строкой с сервера. Буферизация набора результатов на стороне клиента позволяет серверу как можно раньше высвободить ресурсы, связанные с результатами запроса. Проще говоря, клиенты медленно используют наборы результатов. Поэтому рекомендуется использовать буферизованные наборы результатов. mysqli::query() объединяет выполнение запроса и буферизацию набора результатов.
PHP-приложения могут свободно оперировать данными внутри буферизованных результирующих наборов. Быстрая навигация по строкам наборов обусловлена тем, что наборы полностью располагаются в памяти клиента. Следует помнить, что зачастую обработка результатов на клиенте проще, нежели средствами сервера.
Пример #2 Навигация по строкам буферизованной результирующей таблицы
Результат выполнения данного примера:
Небуферизованные результирующие наборы
Если клиентские ресурсы ограничены, и в тоже время не требуется поддерживать низкую нагрузку на сервер, можно использовать не буферизованные результирующие наборы. Навигация по таким таблицам невозможна, потому что так или иначе должны быть обработаны все строки набора.
Пример #3 Навигация по строкам небуферизованной результирующей таблицы
Типы данных значений в результирующей таблице
Пример #4 Текстовый протокол по умолчанию возвращает строки
Результат выполнения данного примера:
Пример #5 Получение исходных типов данных в приложении
Работа с MySQL в PHP
PHP поддерживает работу с базой данных MySQL.
Специальные встроенные функции для работы с MySQL позволяют просто и эффективно работать с этой СУБД: выполнять любые запросы, читать и записывать данные, обрабатывать ошибки.
Сценарий, который подключается к БД, выполняет запрос и показывает результат, будет состоять всего из нескольких строк. Для работы с MySQL не надо ничего дополнительно устанавливать и настраивать; всё необходимое уже доступно вместе со стандартной поставкой PHP.
Что такое mysqli?
mysqli (MySQL Improved) — это расширение PHP, которое добавляет в язык полную поддержку баз данных MySQL. Это расширение поддерживает множество возможностей современных версий MySQL.
Как выглядит работа с базой данных
Типичный процесс работы с СУБД в PHP-сценарии состоит из нескольких шагов:
Функция mysqli connect: соединение с MySQL
Но чтобы выполнить соединение с сервером, необходимо знать как минимум три параметра:
Базовый синтаксис функции mysqli_connect() :
Проверка соединения
Первое, что нужно сделать после соединения с СУБД — это выполнить проверку, что оно было успешным.
Эта проверка нужна, чтобы исключить ошибку при подключении к БД. Неверные параметры подключения, неправильная настройка или высокая нагрузка заставит MySQL отвеграть новые подключения. Все эти ситуации приведут к невозможности соединения, поэтому программист должен проверить успешность подключения к серверу, прежде чем выполнять следующие действия.
Соединение с MySQL и проверка на ошибки:
Функция mysqli_connect_error() просто возвращает текстовое описание последней ошибки MySQL.
Установка кодировки
Первым делом после установки соединения крайне желательно явно задать кодировку, которая будет использоваться при обмене данными с MySQL. Если этого не сделать, то вместо записей со значениями, написанными кириллицей, можно получить последовательность из знаков вопроса: ‘. ’.
Вызови эту функцию сразу после успешной установки соединения: mysqli_set_charset($con, «utf8»);
Выполнение запросов
Установив соединение и определив кодировку мы готовы выполнить свои первые SQL-запросы. Вы уже умеете составлять корректные SQL команды и выполнять их через консольный или визуальный интерфейс MySQL-клиента.
Те же самые запросы можно отправлять без изменений и из PHP-сценария. Помогут в этом несколько встроенных функций языка.
Два вида запросов
Следует разделять все SQL-запросы на две группы:
При выполнении запросов из среды PHP, запросы из второй группы возвращают только результат их исполнения: успех или ошибку.
Запросы первой группы при успешном выполнении возвращают специальный ресурс результата. Его, в свою очередь, можно преобразовать в ассоциативный массив (если нужна одна запись) или в двумерный массив (если требуется список записей).
Добавление записи
Вернёмся к нашему проекту — дневнику наблюдений за погодой. Начнём практическую работу с заполнения таблиц данными. Для начала добавим хотя бы один город в таблицу cities.
Выражение INSERT INTO используется для добавления новых записей в таблицу базы данных.
Функция insert id: как получить идентификатор добавленной записи
Теперь у нас есть всё необходимое, чтобы добавить погодную запись.
Вот как будет выглядеть комплексный пример с подключением к MySQL и добавлением двух новых записей:
Чтение записей
В этом примере показано, как вывести все существующие города из таблицы cities:
Чтобы получить действительные данные, то есть записи из таблицы, следует использовать другую функцию — mysqli_fetch_array() — и передать ей единственным параметром эту самую ссылку.
Теперь каждый вызов функции mysqli_fetch_array() будет возвращать следующую запись из всего результирующего набора записей в виде ассоциативного массива.
Цикл while здесь используется для «прохода» по всем записям из полученного набора записей.
Значение поля каждой записи можно узнать просто обратившись по ключу этого ассоциативного массива.
Как получить сразу все записи в виде двумерного массива
Иногда бывает удобно после запроса на чтение не вызывать в цикле mysqli_fetch_array для извлечения очередной записи по порядку, а получить их сразу все одним вызовом. PHP так тоже умеет. Функция mysqli_fetch_all($res, MYSQLI_ASSOC) вернёт двумерный массив со всеми записями из результата последнего запроса.
Перепишем пример с показом существующих городов с её использованием:
Как узнать количество записей
а как узнать выполнился ли запрос?
Safary
Новичок
а как узнать выполнился ли запрос?
$q=mysql_query(‘SELECT * FROM aples’);
как узнать выполнился ли запрос?
Я конечно могу проверить не является ли кол-во полей нулю, но эта функция медленнее будет выполняться, у меня цикл в цикле, и перед каждым вызовом цикла, который в цикле проверяется остались ли ещё ряды.
Есть специальная функция? похоже нету, искал час её по инету, ниче не нашел.
Или придется кол-во полей проверять всётаки?
Мне нужно это для выхода из цикла.
HraKK
Мудак
Safary
Новичок
$q=mysql_query(‘SELECT * FROM aples’);
вот такая функция не работает:
или такая:
if($q==0) break;
у меня mysql_result вот такую ошибку выдает ((
Unable to jump to row 1 on MySQL result index 9
Фанат
oncle terrible
Safary
Новичок
но ведь mysql_query возращает FALSE если не верно запрос сделан, а мне нужно чтоб функция возвращала FALSE, если ничего не нашлось.
Ааа. Всё работает, я просто напутал кое-что.
че-то такая странная конструкция получается, что сам не знаю даже что делать )))
$q=’SELECT * FROM structure WHERE link REGEXP «^’.$_SERVER[‘REQUEST_URI’].'[a-z0-9_-]+/$» LIMIT ‘.$w.’,’.$wnum;
if(mysql_query($q))
mysql_query();
while($ar=mysql_fetch_array($q))<
Фанат
oncle terrible
Beavis
Banned
dimagolov
Новичок
Safary, ты бредишь. читай ман как по mysql_query так и по mysql_fetch_array.
кроме того, чтобы узнать, что запрос ничего не отбирает не надо делать SELECT *, надо SELECT COUNT(*), но это если сами данные не нужны при этом
Safary
Новичок
Ну да, эту функцию я знаю, но ведь она считает сколько найдено, а это потеря скорости небольшая получается. у меня цикл просто в цикле, вот =)
или может если так написать if(mysql_num_rows($q)==0)
Она будет считать сколько равно num_rows?
Или сразу увидит что не равно 0 и дальше считать не будет и проскочит?
Кстати, странно ПХП реагирует.
$q=’SELECT * FROM structure WHERE link REGEXP «^’.$_SERVER[‘REQUEST_URI’].'[a-z0-9_-]+/$» LIMIT ‘.$w.’,’.$wnum;
Фанат
oncle terrible
dimagolov
Новичок
Safary, ты мануал читать отказываешь принципиально и изучать что значат операторы видимо тоже.
какой смысл отвечать на твои вопросы? это все равно что младенцу теорию относительности излагать.
Safary
Новичок
x-yuri
Новичок
Safary
Новичок
запрос к примеру. сайт.ру/programs/
______________________
архиваторы | редакторы |
___________|__________|
вьюверы. | система. |
___________|__________|
графика. | браузеры. |
___________|__________|
dimagolov
Новичок
Safary, да ты крут немерянно. ты в качестве ключа для поиска в БД используешь url страницы да еще и с регуляркой. и у тебя по этому ключу дерево построено. это явно уникальная идея.
даже не знаю что тебе посоветовать. вернее в каких словах это будет понятно тебе.
Асинхронные запросы к MySQL
В mysqlnd появилась возможность выполнять запросы к MySQL асинхронно, то есть продолжить работу скрипта не дожидаясь выполнения запроса и формирования результата. Преимущество такого подхода очевидно, ведь можно выполнить массу полезной работы во время ожидания запроса, но для начала я приведу немного другой пример:
Допустим у Вас есть 3 запроса (q1, q2, q3), каждый запрос выполняется за определенное время (t1, t2, t3), например так:
В случае синхронного выполнения запросов, Вы сможете получить результаты их выполнения через t1 + t2 + t3 (ex: 6 секунд), а в случае асинхронного выполнения запросов уже за max(t1, t2, t3) (ex: 3 секунды)
Примеры работы с асинхронными запросами, а также другие примеры работы с mysqlnd можно найти на github
Выполнение асинхронных запросов
Для выполнения асинхронных запросов достаточно указать специальный флаг MYSQLI_ASYNC.
Данная константа объявляется непосредственно в расширении, поэтому выражения выше не выполнится без mysqlnd. Для обеспечения возможности выполнить запрос синхронно, в случае отсутствия mysqlnd, существует несколько вариантов выполнения запроса:
В отличии от обычного результата работы этой функции, в случае асинхронного выполнения запроса на чтение (SELECT и тд) она вернет true, вместо mysqli_result.
Проверка выполнения асинхронных запросов
Для проверки выполнения асинхронных запросов используется функция mysqli_poll. К сожалению, функция не документирована, а набор параметров вызывает недоумение, поэтому мне пришлось лезть в исходники и смотреть что же все-таки происходит. В итоге выяснилось что функция является оберткой для системного вызова select, наподобие функции stream_select:
На вход функции mysqli_poll подаются три массива, содержащие объекты mysqli, которые необходимо проверить и значения таймаута проверки (sec, [usec]). Массивы преобразуются в соответствующий набор файловых дескрипторов, значения для таймаута преобразуются в структуру timeval и отдаются на вход системному вызову select, затем совершается обратное преобразование дескрипторов в объекты mysqli и возвращается результат системного вызова select. Примеры проверки результатов асинхронных запросов можно посмотреть здесь.
Получение результатов запроса
Получение результатов выполнения асинхронного запроса происходит через функцию mysqli_reap_async_query. Вызов функции необходим всегда, так как он снимает блокировку с запроса и без этого вызова, все последующие запросы будут падать с «Commands out of sync».Для запросов на чтение (SELECT и тд), функция вернет mysqli_result, который после обработки необходимо «освободить» для продолжения работы с БД, для остальных — bool.
Варианты использования
Основным преимуществом использования асинхронных запросов является более эффективное использование процессорного времени. Вначале статьи есть пример, который показывает насколько быстро можно выполнять множества асинхронных запросов к БД (код). Кроме этого перед разработчиком достаточно часто встает задача написания миграций в БД. Миграции, как правило, делятся на миграции схемы(CREATE, ALTER, DROP) и миграции данных (INSERT, UPDATE, DELETE). В случае работы с большими таблицами, выполнение ALTER занимает большое кол-во времени, которое можно эффективно использовать для подготовки данных для UPDATE (код).
P.S. Работа с асинхронными запросами пока не полностью прозрачна для меня, поэтому я прошу Вашей помощи:
1. Я так и не смог сэмулировать получение ошибок(появления объекта mysqli в массиве errors) через mysqli_poll. Если Вы знаете как это сделать, напишите плз, обязательно добавлю в статью.
2. Если закрыть соединение перед вызовом mysqli_poll у меня получается segfault(ubuntu 12.04, php 5.3.10). Воспроизведите плз у себя следующий код, возможно надо репортить баг:
MySQL On air. Мониторим SQL запросы
Разбираясь как работает та или иная CMS приходится использовать различные инструменты, облегчающие работу.
Наиболее интересная тема — это работа с баз(ой|ами) данных. Естественно для изучения запросов и результатов запросов нужно использовать что-то универсальное. Что-то, что будет работать стабильно как с известным движком, так и с самописной системой.
Предположим у вас оказалась система управления контентом и вам необходимо посмотреть как реализовано добавление новых пользователей или смена паролей.
Большинство инструментов позволяющих мониторить работу с БД являются платными [раз, два]. Я хотел что-то более легкое и удобное, поэтому выбрал mysql-proxy. Хотя возможности утилиты гораздо шире чем мне требуется, я опишу лишь основное. Работает как под Windows, так и под Unix системами.
Скачать можно тут: dev.mysql.com/downloads/mysql-proxy
Первым делом нужно определиться с выбором дистрибутива. На данный момент новейшей версией является «MySQL Proxy 0.8.3 alpha», в качестве ОС у меня стоит Windows 7, поэтому все тесты будут на ней.
После нажатия на кнопку «Download» вас попросят авторизироваться либо зарегистрировать, но снизу есть ссылка для скачивания без лишних действий. (В репозиториях Ubuntu и Debian есть готовые пакеты, так что: sudo apt-get install mysql-proxy)
Хочу заметить, что при размере в 7.9Мб в дистрибутив входит Lua с поддержкой основых модулей.
После скачивания архива его нужно распаковать в удобную для вас директорию, возьмем для примера C:\mysql-proxy
Для запуска приложения нужно определиться с параметрами.
В данном контексте многое зависит от того, что у вас установлено. В качестве LAMP я использую Winginx, прочитать об этой связке можно тут: winginx.ru
По умолчанию MySQL работает на 3306 порту, его мы трогать не будем.
Нам нужно изменить порт для подключения php к базе. Для этого необходимо поправить php.ini
Найдем строку «mysql.default_port» и установим порт (по умолчанию 4040). Для более универсальной работы измените и «mysqli.default_port» на 4040
Подготовительная часть пройдена, перейдем к делу.
Вариант 1. Мониторинг запросов.
Для простого мониторинга необходимо использовать Lua скрипт. Как я уже говорил Lua идет в комплекте, так что ничего нового устанавливать не надо.
Создадим простой скрипт view.lua в директории C:\mysql-proxy\ с содержимым:
Теперь можно проверить результат.
Для удобства создадим в директории C:\mysql-proxy файл view.bat c содержимым:
—proxy-backend-addresses — адрес MySQL сервера на который будем проксировать запрос.
Запустив вэб-сервер и выполнив какие либо запросы к базе можете увидеть такое:
Запросы отображаются, хорошо.
Вариант 2. Мониторинг запросов и запись в файл.
Для записи запросов в файл будем использовать штатные возможности Lua.
Создадим файл view-write.lua в директории C:\mysql-proxy\ с содержимым:
и bat файл — «view-write.bat»
Результат после выполнения запросов (по адресу «C:\mysql-proxy\sql-log.txt»)
Помимо отображения самих запросов, нам может понадобиться вывод результатов этих запросов.
Вариант 3. Запросы и результат
По той-же схеме создаём скрипт «view-result.lua»:
В результате получаем полное логирование запросов и ответов в читаемом виде