Вопрос или проблема
Я пытаюсь получить количество строк, чтобы проверить, есть ли уже тот же электронный адрес в базе данных или нет. Я пробовал несколько механизмов, но безуспешно. Когда я выполняю свой запрос напрямую в базе данных, он возвращает количество строк, но через выполнение PDO он показывает 0.
Я использовал метод fetchAll для ручного подсчета, даже использовал метод rowCount, который также не работает.
$sql="SELECT count(*) FROM inbox WHERE uid = ? AND from_email = ?";
$result = $link->prepare($sql);
$result->execute([$email_number,$email_f]);
$number_of_rows = $result->fetchColumn();
Проблема заключается в этом $email_f, он содержит HTML.
SELECT count(*) FROM inbox WHERE uid = "6961"
AND from_email = "abc Offers <[email protected]>"
Это запрос, который я напечатал из $sql, и когда я выполняю его в базе данных напрямую в phpmyadmin, он работает нормально. Он возвращает количество 3, но через выполнение я получаю 0.
Прежде всего, вам нужно принять тот факт: если ваш запрос не нашел никаких строк, это означает, что совпадений нет, даже если вы можете поклясться, что данные в порядке. Поэтому вам нужно выяснить, почему совпадений нет.
Проблемы, вызванные ошибками SQL
Сначала убедитесь, что ваш запрос действительно выполняется без ошибок, поскольку “отсутствие результата” может означать ошибку в запросе. Обратитесь к этим ответам для получения деталей: pdo и mysqli.
Если ошибка говорит “нет такой таблицы/базы данных”, смотрите случай “учетные данные подключения” ниже.
Проблемы, вызванные условиями
Проверьте ваши условия. Есть взаимно исключающие условия, такие как WHERE col=1 AND col=2
. Они никогда не вернут никаких строк. Попробуйте упростить условие, пока оно не начнет возвращать строки, а затем уточните условия, чтобы получить желаемый результат.
Но все в порядке, нет ошибок, условия правильные, и вы можете поклясться, что в таблице есть данные, соответствующие вашему запросу. Тем не менее, есть некоторые подводные камни:
Проблемы, вызванные данными
Прежде всего, если переменная участвует, убедитесь, что она существует и действительно содержит какое-то значение.
Затем проверьте само значение. В входных данных (или базе данных) могут быть преобразованные или непечатаемые символы. Например, символ переноса строки или странно закодированный символ, или некоторые символы, такие как <
и >
, преобразованные в HTML-сущности. В результате запрос, содержащий <[email protected]>
, никогда не совпадет с текстом <[email protected]>
. Для быстрого проверки вы можете использовать функцию rawurlencode()
, она преобразует все непечатные символы в коды, тем самым делая их видимыми.
Проблема в том, что это всего лишь предположение, и никто не может сказать вам, в чем конкретно проблема, потому что это ваша база данных, ваши входные данные, и только вы можете найти проблему.
Я написал статью, которая объясняет как отладить ваши проблемы с PDO.
Для отладки конкретной проблемы вам нужно:
- убедиться, что полная отчетность об ошибках включена как для PDO, так и для PHP. Это действительно помогает, показывая вам случайные типографические ошибки, ошибки написания и тому подобное;
- тщательно проверить как данные в базе данных, так и ввод, чтобы найти различия. Функция
urlencode()
поможет раскрыть все непечатаемые и преобразованные символы как в базе данных, так и в вводе.
Проблемы, вызванные учетными данными подключения
Еще одна частая проблема возникает, когда у вас несколько баз данных, и вы подключаетесь к неправильной, которая не содержит запрашиваемых данных. Эта проблема похожа на эту, поэтому просто следуйте той же процедуре, только проверяя не список таблиц, а строки данных.
Проблемы, вызванные набором символов/кодировкой
Это редкий случай, но просто на всякий случай следуйте контрольному списку из этого отличного ответа.
Ответ или решение
Проблема с соответствием строк в базе данных, часто возникающая у разработчиков, требует внимательного подхода к диагностике. Давайте разберем ваш случай, в котором вы не можете получить ожидаемое количество строк при использовании PDO, несмотря на то, что прямой SQL-запрос в phpMyAdmin успешно возвращает необходимые данные.
Контекст проблемы
Вы выполняете запрос:
SELECT count(*) FROM inbox WHERE uid = ? AND from_email = ?;
с использованием переменных $email_number
и $email_f
. Однако при выполнении этого запроса через PDO вы получаете 0
строк, хотя вы уверены, что данные существуют.
Анализ проблем
-
Ошибки SQL:
Чтобы убедиться, что ваш запрос выполняется без ошибок, следует проверить выполнение команды. Обычно это можно сделать с помощью обработки исключений в PDO:try { $result = $link->prepare($sql); $result->execute([$email_number, $email_f]); } catch (PDOException $e) { echo "Ошибка выполнения SQL: " . $e->getMessage(); }
-
Проблемы с условиями:
Тщательно проверьте условия вашего запроса. Например, убедитесь, что переменные$email_number
и$email_f
содержат необходимые значения и корректные типы данных. Убедитесь, чтоuid
действительно равен6961
и что значениеfrom_email
точно совпадает с тем, что хранится в базе данных. -
Проблемы с данными:
Проверьте, что ваши данные не содержат лишних символов или проблем с кодировкой. Обратите внимание, что HTML-сущности могут зависеть от контекста. Например, если ваше значениеfrom_email
выглядит как"abc Offers <[email protected]>"
, а в базе данных хранится как"abc Offers <[email protected]>"
, то они не совпадут.Используйте такие функции, как
trim()
для удаления лишних пробелов, илиhtml_entity_decode()
для декодирования HTML-сущностей:$email_f = html_entity_decode($email_f);
-
Проблемы с соединением:
Убедитесь, что вы подключаетесь к правильной базе данных, в которой находится таблицаinbox
с необходимыми данными. Иногда можно случайно подключаться к другой базе данных, где данные отсутствуют. -
Проблемы с кодировкой:
Проверьте, что у вас установлена правильная кодировка для соединения с базой данных. Вы можете сделать это следующим образом:$link->exec("SET NAMES 'utf8'");
Подход к отладке
Для дальнейшей диагностики рассмотрите возможность вывода значений переменных перед выполнением запроса:
echo "Email Number: " . $email_number . "\n";
echo "Email From: " . $email_f . "\n";
Это поможет вам убедиться, что значение email_f
действительно соответствует тому, что вы ожидаете.
Кроме того, для быстрой проверки сделайте запрос, не используя параметры:
$sql = "SELECT count(*) FROM inbox WHERE uid = '6961' AND from_email = 'abc Offers <[email protected]>'";
$result = $link->query($sql);
$count = $result->fetchColumn();
echo $count;
Заключение
Каждая из вышеперечисленных предложений поможет вам выявить проблему с вашим запросом. Если все эти шаги не решат проблему, попробуйте последовательно отключать условия в запросе, чтобы определить, какое из них не выполняется. Убедитесь, что данные введены правильно и соответствуют ожидаемым значениям. Работая в таком ключе, вы сможете более точно идентифицировать источник проблемы и ее причины.