[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Общее FAQ
neadekvat
Вниманию лентяев новичков и других.
Ошибки, выдаваемые php, содержат не только слова "Warning" и "Fatal error", в них есть и текст ошибки, который прямым текстом говорит о причине своего появления. Правда, на английском языке.
Также часто информацию о причинах ошибки можно найти в официальной документации (php.net, если кто-то еще не знает), правда, и она по большей части на английском.
А так как не смотря ни на что просьбы о помощи появляются регулярно, и помощникам откровенно задолбалось из раза в раз повторять одно и то же, ниже я предлагаю собрать коллекцию часто задаваемых вопросов, просьб, проблем и т.п., чтобы вместо очередного "Бла-бла" давать ссылку сюда.

Ожидаю участие всех: от обычных пользователей до администрации.

P.S. Слова о "ненужности" и т.д. не принимаю - faq нужен. Будем его делать.

Содержание:
  • 1. Warning: mysql_fetch_array()/или mysql_fetch_assoc()/mysql_fetch_row(): supplied argument is not a valid MySQL result resource in %script_address% on line %line_num%
  • 2. 1064 - You have an error in your SQL syntax
  • 3. Cannot modify header information - headers already sent
  • 4. session_start() [function.session-start]: Cannot send session cookie
  • 5. Parse error: syntax error, unexpected $end in %script_address% on line %line_num%
  • 6. Обработка данных
  • 7. Динозавры или "использую ereg*, HTTP_*_VARS, а надо мной все смеются"
  • 8. Кракозябры при выводе из MySQL
  • Благодарности
Вопрос №1: Warning: mysql_fetch_array()/или mysql_fetch_assoc()/mysql_fetch_row(): supplied argument is not a valid MySQL result resource in %script_addres% on line %line_num%

Свернутый текст
Для начала кое-что поясню. Функция mysql_query(), которой вы делаете запрос, может вернуть два значения: указатель на результаты запроса или ресурс (точнее - дескриптор), далее с помощью этого указателя можно вытаскивать непосредственно строки из базы данных. В случаи же, если произошла какая-то ошибка*, функция вернет false.
* Следует заметить, что имеется в виду ошибка синтаксиса в запросе. Если же в бд нет строк, удовлетворяющих запросу, все равно вернется ресурс.

Только ленивый не знает, что функция mysql_fetch_array в качестве параметра принимает именно ресурс, а следовательно, результатом появления описанной ошибки является неверный синтаксис. Узнать, что именно не так в запросе, можно таким способом:
$sql = "..."; // Текст запрос
// В случаи ошибки сценарий прекратит выполнение и выведет на экран текст ошибки.
// Эту ошибку возвращает уже сама бд.

$query = [SPAN=darling]mysql[/SPAN]_query($sql) or die("Error in SQL:<pre>$sql</pre>". [SPAN=darling]mysql[/SPAN]_error());

Опыт показывает, что чаще других появляется ошибка, описанная в следующем пункте.

Совет.
Используйте функцию mysql_fetch_assoc вместо mysql_fetch_array, т.к. последняя в общем случаи возвращает лишний массив, а к оперативной памяти надо относится бережно и загружать в нее только то, что действительно необходимо.



Вопрос №2: 1064 - You have an error in your SQL syntax

Свернутый текст
Для того, чтобы понять, что же не так в запросе, надо его увидеть. Для этого рекомендуется все сложные запросы выделять в отдельную переменную - это облегчает отработку ошибок в приложении:
$sql = "INSERT INTO `tbl` (`user_name`, `user_age`) VALUES ($user_name, $user_age)";
// Выводим запрос с подставленными переменными
// и станавливаем выполнение сценария

$query = [SPAN=darling]mysql[/SPAN]_query($sql) or die("Error in SQL:<pre>$sql</pre>". [SPAN=darling]mysql[/SPAN]_error());

Дальше придется смотреть глазами и вспоминать, как должен выглядеть запрос.
В данном примере пропущены кавычки.

Совет.
Бывает так, что найти ошибку в запросе (особенно в сложном запросе) довольно затруднительно. В этом случаи рекомендую разбивать запрос на несколько строк, ведь в сообщении бд есть указание строки, в которой допущена ошибка:
$sql = "INSERT INTO `tbl`
(`user_name`, `user_age`)
VALUES
(
$user_name, $user_age)";

Теперь в конце сообщения мы увидем номер строки: "You have ... at line 4", а это сильно сужает круг поиска.



Вопрос №3: Cannot modify header information - headers already sent
Вопрос №4: session_start() [function.session-start]: Cannot send session cookie

Свернутый текст
Немного теории. На запрос браузера сервер отвечает в два этапа: первым отправляется заголовок с информацией о странице (статус ответа, кодировка, значения устанавливаемых кукисов (!) и многое другое), а уж только затем отправляется само содержание страницы (обычно - html код).

По этой причине модификация заголовка (с помощью функций header и в частности setcookie) возможна только до того, как скрипт отправит в поток какой-либо символ, даже если пробел.

Таким образом, описанная ошибка может появится в двух случаях:
1. Ошибка логики приложения: вы сначала отправляете html-код (например, начало разметки), а потом пытаетесь поставть кукисы:
<html>
<
head>
<
title>Тут модный заголовок</title>
</
head>
<
body>
<?[SPAN=darling]php[/SPAN]
/*
* Открываем сессию для наших любимых пользователей
*/

session_start();
/*
* Блин, я забыл указать кодировку страницы, ну да ладно
* Я ее отправлю в заголовке, круче будет!
*/

header("Content-type: text/html; charset=utf-8");

echo 'WTF';


2. Программист случайно поставил пробел или перенос строки в самое начало файла:
*я пробел* <?[SPAN=darling]php[/SPAN]
session_start();


3. Файл сохранен в кодировке "UTF-8 with BOM". PHP не имеет корректно работать с этим самым "BOM", кодировка должна быть UTF-8 без BOM.

Совет.
Вот пример полного сообщения об ошибке:
Цитата
Warning: Cannot modify header information - headers already sent by (output started at W:\home\localhost\www\test\index.php:6) in W:\home\localhost\www\test\index.php on line 15

Обратите внимание на информацию в скобках. Дословно: "заголовки были отправлены было в W:\home\localhost\www\test\index.php:6", где последняя цифра - номер строки, где появился "левый" символ, который вынудил сервер отправить заголовок.



Вопрос №5: syntax error, unexpected $end in %script_address% on line %line_num%

Свернутый текст
В большинстве случаев это означает одно: программист забыл закрыть фигурную скобку.
if ($d > 0) {
$d *= 5;

if ($d == 0) {
$d -= 13;
}

Интерпритатор посчитает, что последняя закрывающаяся скобка относится к выражению ($d == 0), но ведь и ($d > 0) надо закрыть.
Стоит заметить, что в качестве строки php скорее всего укажет на строку, которой в файле даже нет (говоря точнее: максимальная строка + 1). Можно это расценить как надежду PHP до последнего встретить эту закрывающую скобку.
Тут ваш лучших помощник - редактор с подсветкой, который умеет искать парные скобки, отступы в коде и ваша внимательность.

Совет.
Как уже было сказано, отступы имеют важное значение в понимании кода и в поиске ошибок:
if ($d > 0) {
$d = $d - 5;

if ($d == 0) {
$d *= 5;

if ($d > 0) {
$d -= 13;
}

}
else if ($d < 0) {
$d = -$d;
}

Правда, стоит признать, что в поиске парных скобок никакая внимательность не сравнится с хорошим редактором.



Вопрос №6: "Как обрабатывать данные, приходящие от пользователя?", "А как обрабатывать данные, отдаваемые пользователю?"

Свернутый текст
Если ответ нужен здесь и сейчас, то вкратце:

1. Данные пользователя должны хранится именно в том виде, в котором их ввел пользователь. То есть, никаких модификаций. Запомните это.

2. Бывает так, что в тексте пользователя встречаются кавычки, и если подставить такие данные в запрос - как минимум, база данных отвергнет запрос и вернет ошибку. В худшем случаи - это будет сделано специально, с целью навредить. Читать подробнее про sql-инъекции.
Уберечься от этого можно следующим способом: если данные представляют собой строку, то их следует обработать функцией mysql_real_escape_string, которая экранирует кавычки, если же данные - это числа, то их следует привести к соответствующему формату:
$user_name = [SPAN=darling]mysql[/SPAN]_real_escape_string($_POST['user_name']);
$user_age = (int) $_POST['user_age'];
$sql = "INSERT INTO `tbl` (`user_name`, `user_age`) VALUES ('$user_name', $user_age)";
$query = [SPAN=darling]mysql[/SPAN]_query($sql);

Обратите внимание на запрос: числовые данные не обрамляются кавычками.

3. При выводе, дабы сохранить целостность html-разметки и максимально уберечь от всяких пакостей, данные следует обрабатывать функией htmlspecialchars():
$sql = "SELECT * FROM `tbl` LIMIT 1";
$query = [SPAN=darling]mysql[/SPAN]_query($sql);
$arr = [SPAN=darling]mysql[/SPAN]_fetch_assoc($query);
// На случай, если имя пользователя содержит < или >
echo 'Имя пользователя:'. htmlspecialchars($arr['user_name']);
// Числовые данные обрабатывать дополнительно смысла нет
echo 'Возраст:'. $arr['user_age'];


Тем, кто действительно хочет чему-то научиться, разобраться в тонкостях работы с данными, рекомендую решить [URL=http://phpforum.ru/index.php?showtopic=19168'>вот эту</a> задачу. Будем рады оценить ваш вариант.



Вопрос №7: использую ereg*, HTTP_*_VARS, а надо мной все смеются

Свернутый текст
Потому что вы используйте устаревшие функции. Их немало. Список таких функций можно найти, например, здесь.



Вопрос №8: strpos, strlen и прочие str* работают некорректно с русскими буквами

Свернутый текст
Скорее всего, вы используете многобайтовую кодировку (например, UTF-8), для работы с которыми в php.ini необходимо подключить расширение php_mbstring.dll (Multibyte String, список функций).



Благодарности

За участие в создании faq объявляется благодарность kirik'у, inpost'y, alex12060, Trianon'у и twin'y:)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.