Ошибка mysql_fetch_array(): параметр 1 должен быть resource — как исправить

Онлайн-тренажер Python для начинающих

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

Начать курс

Введение: «Ваш логотип не работает, а база данных плачет»

Если вы когда-нибудь писали на PHP скрипт, который работает с MySQL, то наверняка сталкивались с этой пугающей фразой:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given.

Давайте сразу договоримся: это не конец света. Это всего лишь сигнал от PHP: «Эй, я не могу взять данные из того, что ты мне подсунул!».

В этом туториале мы разберем, почему возникает ошибка mysql_fetch_array() expects parameter 1 to be resource, как её исправить, и самое главное — как перестать её видеть раз и навсегда (спойлер: перейти на PDO или MySQLi).

Статья написана специально для pythonlib.ru — образовательного портала, где мы учим писать код без боли. Поехали!

Почему PHP кричит на параметр? (причины)

Чтобы понять корень зла, вспомним, как работают старые функции mysql_* (да, те, что устарели ещё в PHP 5.5).

Типичный код новичка выглядит так:

// Подключение
$link = mysql_connect('localhost', 'user', 'password');
mysql_select_db('test');

// Запрос (с ошибкой)
$result = mysql_query("SELECT * FROM users WHERE id = '1");

// Попытка прочитать
while($row = mysql_fetch_array($result)) { // Ошибка!
    echo $row['name'];
}

Что здесь не так? Всё! Но главное: mysql_query() вернул false, а не ресурс (resource). Почему?

  • Синтаксическая ошибка в SQL — кавычка не закрыта.
  • Нет подключения к БД — mysql_connect() вернул false.
  • Не выбрана база — mysql_select_db() не сработала.
  • Таблица не существует.

Когда mysql_query() падает, он возвращает false (логический тип), а не resource. Вы же пытаетесь передать false в mysql_fetch_array(), которая ждет resource. Конфликт! Отсюда и ошибка.

Какие функции страдают?

  • mysql_fetch_array()
  • mysql_fetch_assoc()
  • mysql_fetch_row()
  • mysql_num_rows()
  • mysql_data_seek()

Все они кричат одно и то же: «expects parameter 1 to be resource».

Пошаговое исправление (для старого кода)

Если у вас легаси-проект, и вы пока не можете обновить PHP (хотя очень советую), вот как отловить и починить ошибку.

Шаг 1. Проверяем соединение

$link = mysql_connect('localhost', 'user', 'password');
if (!$link) {
    die('Ошибка соединения: ' . mysql_error());
}

Шаг 2. Проверяем выбор базы

if (!mysql_select_db('my_database')) {
    die('Не удалось выбрать БД: ' . mysql_error());
}

Шаг 3. Делаем запрос с проверкой

$sql = "SELECT * FROM users WHERE id = 1";
$result = mysql_query($sql);

if (!$result) {
    die('Ошибка запроса: ' . mysql_error());
}

// Теперь можно смело использовать
while($row = mysql_fetch_assoc($result)) {
    echo $row['name'];
}

Видите разницу? Мы проверяем каждый шаг. Если mysql_query() вернул false — мы умираем с сообщением об ошибке, а не передаем false дальше.

Почему это всё ещё работает? (исторический контекст)

На Stack Overflow этот вопрос собрав тысячи просмотров. И это неудивительно: до сих пор на многих хостингах крутится PHP 5.x, и куча учебников (даже на YouTube) учат через mysql_*.

Но запомните раз и навсегда: расширение mysql устарело и удалено из PHP 7.0. Если вы пишете новый код — используйте mysqli или PDO.

Современное решение: переходим на PDO

PDO (PHP Data Objects) — это современный, безопасный и удобный способ работы с базами данных. Он поддерживает подготовленные запросы (защита от SQL-инъекций) и не страдает от описанной выше ошибки (потому что использует объекты, а не ресурсы).

Пример правильного кода на PDO

<?php
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8';
$user = 'root';
$password = '';

try {
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('Ошибка подключения: ' . $e->getMessage());
}

// Подготовленный запрос
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => 1]);

// Получаем данные
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['name'];
}

Обратите внимание: ни единого вызова mysql_fetch_array(). Всё чисто, объектно-ориентированно, и никаких «expects parameter 1 to be resource».

Как правильно переписать старый код?

Если у вас есть проект на mysql_*, вот минимальный план миграции:

  • Заменить mysql_connect() на new PDO().
  • Заменить mysql_query() на $pdo->query() или prepare().
  • Заменить mysql_fetch_array() на $stmt->fetch().
  • Заменить mysql_num_rows() на $stmt->rowCount() (но осторожно — с SELECT не всегда работает).

Да, это потребует времени. Но поверьте: один раз переписать — и забыть об ошибках навсегда.

Частые вопросы (FAQ по ошибке)

1. Я проверил подключение, но ошибка всё равно есть

Проверьте регистр имён таблиц и полей. На Linux MySQL чувствителен к регистру. Если таблица называется Users, а вы пишете users — зап

Блоги

Рекомендаций по книгам