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, порядок действий всегда одинаков:
- Подключиться к базе данных.
- Выполнить оператор
SELECT. - Получить строки из результирующего набора.
- Закрыть соединение (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.