W3docs

PHP MySQL Select: Полное руководство

Используйте SQL SELECT в PHP — фильтрация через WHERE, сортировка ORDER BY, пагинация LIMIT, безопасное чтение строк через mysqli и PDO.

SELECT — это SQL-оператор, который читает данные из базы данных. Вы будете использовать его чаще любого другого. Это руководство охватывает синтаксис SELECT, предложения, формирующие результат, и два PHP-расширения (mysqli и PDO), с помощью которых выполняется запрос и перебираются возвращённые строки.

Если вы ещё не подключались к базе данных, начните с PHP MySQL Connect; чтобы сначала добавить строки в таблицу, смотрите PHP MySQL Insert.

Что делает оператор SELECT

SELECT извлекает строки из одной или нескольких таблиц. В простейшем виде вы указываете нужные столбцы и таблицу, из которой их читать:

SELECT column1, column2, ...
FROM table_name;

Используйте *, чтобы выбрать все столбцы. Это удобно для быстрого просмотра, но в коде приложения лучше явно указывать столбцы — так быстрее, понятнее и код не сломается, когда кто-то добавит новый столбец в таблицу.

-- All columns (fine for the mysql console, avoid in app code)
SELECT * FROM users;

-- Only what you need (preferred)
SELECT id, name, email FROM users;

SELECT всегда возвращает результирующий набор: ноль или более строк, каждая из которых состоит из запрошенных столбцов. PHP предоставляет этот набор в виде структуры, по которой можно итерироваться.

Формирование результирующего набора

Форма «столбцы из таблицы» — лишь начало. Пять предложений позволяют фильтровать, сортировать, группировать и объединять данные. При использовании нескольких из них они должны идти именно в таком порядке:

ПредложениеЧто делаетПодробнее
WHEREОставляет только строки, соответствующие условиюMySQL WHERE
GROUP BYОбъединяет строки в группы для агрегатов вроде COUNT()
HAVINGФильтрует группы (как WHERE, но для агрегатов)
ORDER BYСортирует строкиMySQL ORDER BY
LIMITОграничивает количество возвращаемых строкMySQL LIMIT

Фильтрация с WHERE

Вернуть только пользователей с именем John:

SELECT name, email
FROM users
WHERE name = 'John';

Сортировка с ORDER BY

Отсортировать по имени в алфавитном порядке. ASC — по возрастанию (по умолчанию), DESC — по убыванию:

SELECT name, email
FROM users
ORDER BY name ASC;

Ограничение строк с LIMIT

Получить только 10 новейших пользователей — это необходимо для пагинации и чтобы не загружать миллион строк в память:

SELECT name, email
FROM users
ORDER BY created_at DESC
LIMIT 10;

Объединение таблиц

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

SELECT users.name, orders.order_id
FROM users
JOIN orders ON users.id = orders.user_id;

Выполнение SELECT из PHP

Чтобы получить данные в код PHP, порядок действий всегда одинаков:

  1. Подключиться к базе данных.
  2. Выполнить оператор SELECT.
  3. Получить строки из результирующего набора.
  4. Закрыть соединение (PHP также закрывает его автоматически в конце запроса).

Всегда используйте подготовленные запросы для пользовательских данных

Никогда не вставляйте переменную напрямую в строку запроса. Если $name получен из формы, злоумышленник может внедрить SQL и прочитать или уничтожить всю вашу базу данных:

// DANGER: SQL injection. Never do this with untrusted input.
$result = $conn->query("SELECT name, email FROM users WHERE name = '$name'");

Подготовленный запрос отправляет запрос и данные раздельно, поэтому значение никогда не может быть интерпретировано как SQL. Это самая важная привычка при чтении данных, поступающих от пользователя. Подробнее — в MySQL Prepared Statements.

С mysqli

$conn = mysqli_connect("localhost", "username", "password", "database");
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

$stmt = $conn->prepare("SELECT name, email FROM users WHERE name = ?");
$name = "John";
$stmt->bind_param("s", $name);   // "s" = the parameter is a string
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
    }
} else {
    echo "0 results";
}

$stmt->close();
mysqli_close($conn);

fetch_assoc() возвращает каждую строку в виде ассоциативного массива с ключами по именам столбцов ($row["name"]). Используйте fetch_array(), если нужны также числовые ключи, или fetch_all(MYSQLI_ASSOC), чтобы сразу получить все строки в массив.

С PDO

Для новых проектов PDO, как правило, является лучшим выбором: у него единый API для MySQL, PostgreSQL, SQLite и других СУБД, а подготовленные запросы удобно читать.

$pdo = new PDO("mysql:host=localhost;dbname=database;charset=utf8mb4", "username", "password");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare("SELECT name, email FROM users WHERE name = ?");
$stmt->execute(["John"]);

foreach ($stmt as $row) {
    echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}

Установка PDO::ERRMODE_EXCEPTION заставляет неудавшиеся запросы выбрасывать исключения вместо тихого сбоя — оборачивайте обращения к базе данных в try/catch, чтобы проблемы всплывали, а не исчезали бесследно.

Типичные ошибки

  • num_rows возвращает количество строк, а не булево значение. Проверяйте > 0 (mysqli), прежде чем считать, что данные получены.
  • Выборка * с последующим чтением одного столбца всё равно передаёт все столбцы по сети. Выбирайте только то, что используете.
  • Забытый LIMIT на больших таблицах может загрузить огромные результирующие наборы в память. Используйте пагинацию.
  • Сравнение строк в WHERE по умолчанию нечувствительно к регистру в распространённых сортировках MySQL — 'john' совпадёт с 'John'.

Заключение

SELECT — рабочая лошадка любого PHP/MySQL-приложения. Указывайте столбцы явно, формируйте результат с помощью WHERE, ORDER BY, LIMIT и JOIN, и всегда читайте пользовательский ввод через подготовленные запросы (mysqli или PDO), чтобы защититься от SQL-инъекций. Далее изучите изменение данных с помощью MySQL Insert и MySQL Update.

Практика

Практика
Какой правильный синтаксис для получения данных из базы MySQL с помощью PHP?
Какой правильный синтаксис для получения данных из базы MySQL с помощью PHP?
Was this page helpful?