- PHP MySQL: запрос информации из базы данных
- PHP-запрос данных MySQL с помощью простого оператора SELECT
- Сотрудники
- Запрос данных PHP MySQL с использованием подготовленного оператора PDO
- Постраничный вывод и базы данных
- Использование класса
- CSS-стили пагинатора:
- Стили для списка товаров:
- Как разбить вывод из mysql постранично
PHP MySQL: запрос информации из базы данных
Из этой статьи вы узнаете, как с помощью PHP PDO выполнять запрос к базе данных MySQL . А также как использовать подготовленный оператор PDO для безопасного извлечения данных.
PHP-запрос данных MySQL с помощью простого оператора SELECT
Чтобы запросить данные из базы данных MySQL , выполните следующие действия:
Сначала подключитесь к базе данных MySQL .
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
Затем создайте оператор SELECT и выполните его с помощью метода объекта PDO query() .
$sql = 'SELECT lastname, firstname, jobtitle FROM employees ORDER BY lastname'; $q = $pdo->query($sql);
Метод объекта PDO query() возвращает объект PDOStatement или false при ошибке.
Затем с помощью метода setFetchMode() установите режим выборки PDO::FETCH_ASSOC для объекта PDOStatement . Режим PDO::FETCH_ASSOC указывает методу fetch() возвращать набор результатов как массив, проиндексированный по имени столбца с помощью PHP PDO MySQL .
$q->setFetchMode(PDO::FETCH_ASSOC);
После этого, используя метод fetch() объекта PDOStatement извлеките каждую строку из набора результатов, пока не останется ни одной строки.
fetch()): ?>
Весь код PHP PDO примера будет выглядеть следующим образом:
query($sql); $q->setFetchMode(PDO::FETCH_ASSOC); > catch (PDOException $e) < die("Невозможно соединиться с базой данных $dbname :" . $e->getMessage()); > ?>Сотрудники
fetch()): ?> Имя Фамилия Должность
Запрос данных PHP MySQL с использованием подготовленного оператора PDO
На практике часто нужно передать из кода значение в PHP PDO query . Например, чтобы получить данные сотрудников, фамилия которых заканчивается на son . Чтобы сделать это безопасно, нужно использовать подготовленный оператор PDO :
prepare($sql); $q->execute(['%son']); $q->setFetchMode(PDO::FETCH_ASSOC); while ($r = $q->fetch()) < echo sprintf('%s
', $r['lastname']); > > catch (PDOException $pe) < die("Could not connect to the database $dbname :" . $pe->getMessage()); >
Вот, как работает этот скрипт.
- Мы используем в операторе SELECT вопросительный знак (?) . PDO заменит вопросительный знак в запросе соответствующим аргументом. Вопросительный знак называется позиционным заполнителем;
- Затем вызываем метод объекта PDO prepare() , чтобы подготовить оператор SQL к выполнению;
- Далее выполняем запрос PHP PDO , вызывая метод объекта PDOStatement — execute() . Кроме этого мы передаем аргумент в виде массива, чтобы заменить позиционный заполнитель в SELECT . После этого SELECT будет переведен в следующий вид:
SELECT lastname, firstname, jobtitle FROM employees WHERE lastname LIKE '%son';
- Устанавливаем режим извлечения для объекта PDOStatement ;
- Получаем результаты выборки и отображаем поле фамилии.
PHP предоставляет еще один способ использования заполнителей в подготовленном операторе, который называется именованный заполнитель. Преимущества использования именованного заполнителя:
- Имеет более описательный характер;
- Если в операторе SQL имеется несколько заполнителей, то так проще передать аргументы методу execute() .
Рассмотрим следующий PHP PDO пример:
prepare($sql); // передаем значения в запрос и выполняем его $q->execute([':fname' => 'Le%', ':lname' => '%son']); $q->setFetchMode(PDO::FETCH_ASSOC); // выводим набор результатов while ($r = $q->fetch()) < echo sprintf('%s
', $r['lastname']); > > catch (PDOException $e) < die("Could not connect to the database $dbname :" . $e->getMessage()); >
:lname и :fname — это именованные заполнители. Они заменяются соответствующими аргументами в ассоциативном массиве, который мы передаем методу execute .
Из этой статьи вы узнали, как выполнять запросы к базе данных с помощью PHP PDO MySQL .
Вадим Дворников автор-переводчик статьи « PHP MySQL: Querying Data from Database »
Дайте знать, что вы думаете по этой теме в комментариях. Мы крайне благодарны вам за ваши комментарии, отклики, лайки, дизлайки, подписки!
Постраничный вывод и базы данных
В SQL-запросах, для ограничения количества строк в результате используется инструкция LIMIT , например следующий вернёт первые 10 записей:
SELECT * FROM `table` ORDER BY `id` LIMIT 0, 10
В следующем запросе будут записи с 11 по 20:
SELECT * FROM `table` ORDER BY `id` LIMIT 11, 10
Для построения пагинации требуется знать сколько всего записей вернет SQL-запрос без LIMIT, для этого в MySQL есть опция SQL_CALC_FOUND_ROWS . С ней запрос вернет обычный результат.
SELECT SQL_CALC_FOUND_ROWS * FROM `table` ORDER BY `id` LIMIT 0, 10
Но теперь, если следом выполнить запрос SELECT FOUND_ROWS() , то он вернёт общее количество записей в предыдущем запросе.
На этом принципе был написан PHP-класс для постраничного вывода из базы данных.
Использование класса
В класс нужно передать URL страницы, количество записей на странице и SQL-запрос выборки из БД (например товары).
CSS-стили пагинатора:
.pagination-row < overflow: hidden; clear: both; margin: 0 0 20px 0; margin-bottom: 15px; >.pagination < padding: 0; margin: 0; text-align: center; >.pagination .page-item < display: inline-block; margin: 0 2px 3px; >.pagination .page-link < display: inline-block; height: 28px; min-width: 28px; line-height: 28px; font-size: 15px; text-decoration: none; text-align: center; border: 1px solid #ddd; border-radius: 3px; background: #fbfbfb; text-decoration: none; color: #000; >.pagination a.page-link:hover < background: #ffd57b; >.pagination .active a.page-link < background: #2bc2e0; border-color: #a5a5ca; >.pagination .separator .page-link < border-color: #fff; background: #fff; >.pagination .disabled .page-link
Стили для списка товаров:
.prod-list < overflow: hidden; margin: 0 -25px 20px 0; >.prod-item < width: 180px; height: 290px; float: left; border: 1px solid #ddd; padding: 20px; margin: 0 20px 20px 0; text-align: center; border-radius: 6px; >.prod-item-name < margin-bottom: 5px; >.prod-item-btn a
Как разбить вывод из mysql постранично
Как сделать постраничный вывод из mysql «как в яндексе»?
по 10 записей на страницу, внизу — ссылки на остальные страницы?
Сначала научимся получать из базы нужные записи.
Их получение в mysql обеспечивается оператором LIMIT, который вызывается с двумя параметрами — с какой записи начинать, и сколько выводить (внимание! не по какую, а сколько!)
SELECT * FROM table LIMIT 0,10
этот запрос вернет записи с первой по 10, поскольку нумерация начинается с 0
соответственно, запрос для третьей страницы будет выглядеть, как
SELECT * FROM table LIMIT 20,10
получается, что нам всего лишь надо передать в скрипт число, которое потом подставить в запрос.
Этим будет заниматься код, который выводит ссылки на страницы.
Естественно, в цикле.
Для цикла нам понадобится количество записей, которое возвращает запрос без лимита.
Это число можно получить двумя путями. Либо отдельным запросом, в котором отсутствует оператор LIMIT, а вместо перечисления полей после оператора SELECT запрашивается только count(*):
$sql = «SELECT count(*) FROM table»;
$res = mysqli_query($db, $sql);
$row = mysqli_fetch_row($res);
$total_rows=$row[0];
Для тех, кто предпочитает думать самостоятельно, этой информации достаточно.
Вывод ссылок — это простейшая арифметическая операция и никаких особенных знаний для нее не требуется.
Для тех, же, кто ищет готовый код, продолжим.
Для начала определим, сколько всего получится страниц. Для этого надо поделить общее число записей на количество оных на одной странице и округлить результат в большую сторону. Таким округлением занимается в пхп функция ceil()
$num_pages = ceil($total_rows/$per_page);
В этом выражении участвует переменная $per_page , в которую мы положим количество выводимых на странице записей.
Ведь, если это количество изменится, мы же не хотим ползать по всему коду и исправлять цифры? Проще сделать это один раз в начале скрипта при объявлении переменной. В запрос, вторым параметром LIMIT, подставлять нужно, конечно же, тоже ее.
Ну, а дальше, собственно, вывод ссылок.
for($i=1;$i <=$num_pages;$i++) <
echo ».$i.»\n»;
>
в цикле от 1 до $num_pages выводим ссылку с параметром num, равным числу, которое надо передать в LIMIT, а в тексте ссылки пишем номер страницы, поскольку людям понятнее видеть номер страницы, а не записи. На код это не влияет, а людям приятно.
Дальше пойдут украшения.
Во-первых, некрасиво, что номер страницы не совпадает с тем, что видно в адресной строке. Эту проблему можно решить, передавая по ссылке номер страницы в человекопонятном формате, а в скрипте вычислять первый операнд для LIMIT.
Во-вторых, мы явно захотим выделить текущую страницу, не оформляя ее ссылкой.
В-третьих, мы захотим нумеровать записи
Старая версия, классический говнокод
что у нас в результате получилось?
// количество записей, выводимых на странице
$per_page=10;
// получаем номер страницы
if (isset($_GET[‘page’])) $page=($_GET[‘page’]-1); else $page=0;
// вычисляем первый оператор для LIMIT
$start=abs($page*$per_page);
// составляем запрос и выводим записи
// переменную $start используем, как нумератор записей.
$sql =»SELECT * FROM `table` ORDER BY field LIMIT $start,$per_page»;
$res = mysql_query($q);
while($row=mysql_fetch_array($res)) echo ++$start.». «.$row[‘field’].»
\n»;
>
// дальше выводим ссылки на страницы:
$sql = «SELECT count(*) FROM table»;
$res = mysqli_query($db, $sql);
$row = mysqli_fetch_row($res);
$total_rows=$row[0];
Разумеется, вышеприведённый код подходит только как учебное пособие. С его помощью становится понятным принцип, но в реальных условиях мы сразу же столкнемся, как минимум, с двумя проблемами:
Во-первых, кроме переменной $page нашему cкрипту явно будут переданы и другие переменные, да и адрес может совсем не совпадать с именем скрипта. А мы это при формировании ссылок не учитываем.
Во-вторых, нормальный современный сайт немыслим без шаблонов. И такая ужасная лапша из SQL запросов, PHP кода и HTML тегов никуда не годится.
Займемся решением этих проблем.
Первая решается очень просто при использовании функции http_build_query()
Вторая — тоже несложно. Шаблонизаторов много, но мы воспользуемся самым универсальным — PHP.
Что же у нас получилось? А получился у нас — рефакторинг! Переделка старого кода в соответствии с требованиями современности, плюс мелкое причесывание:
include ‘safemysql.class.php’ ;
$db = new safeMysql ();
//получаем номер страницы и значение для лимита
$cur_page = 1 ;
if (isset( $_GET [ ‘page’ ]) && $_GET [ ‘page’ ] > 0 )
$cur_page = $_GET [ ‘page’ ];
>
$start = ( $cur_page — 1 ) * $per_page ;
//выполняем запрос и получаем данные для вывода
$sql = «SELECT SQL_CALC_FOUND_ROWS * FROM Board LIMIT ?i, ?i» ;
$data = $db -> getAll ( $sql , $start , $per_page );
$rows = $db -> getOne ( «SELECT FOUND_ROWS()» );
//узнаем общее количество страниц и заполняем массив со ссылками
$num_pages = ceil ( $rows / $per_page );
// зададим переменную, которую будем использовать для вывода номеров страниц
$page = 0 ;