Цикл запроса mysql в php

Когда я запускаю этот скрипт, apache использует всю доступную память, и сервер перестает отвечать на запросы:

$db = new mysql();
$result = $db->query($sql);
while($row = $db->query($sql)) ...

Почему ограничение PHP не ограничивает процесс apache? PHP работает как mod_php с apache itk.

У меня установлен лимит PHP в php.ini, и я вижу этот лимит в phpinfo(). Я не установил никаких ограничений в PHP-скрипте.


person user134880    schedule 03.02.2014    source источник
comment
Я думаю, он понимает свою ошибку (он описал ее как несчастный случай в первой строке). Его вопрос заключался в том, почему сервер никогда не убивал сценарий, потому что он зацикливался. Возможно, этот вопрос лучше задать на сайте администрирования сервера, например. serverfault.com.   -  person Barmar    schedule 03.02.2014
comment
Ну... у OP уже есть доступ к ресурсу запроса, поэтому он должен повторяться. Похоже, кто-то недостаточно старается   -  person planestepper    schedule 03.02.2014


Ответы (1)


Как вы уже знаете, while($row = $db->query($sql)) вызывает бесконечный цикл; он просто запускает запрос снова и снова, пока сервер не умрет или не убьет процесс. Вам нужно сделать while($row = $result->fetch()) или while($row = $result->fetch_assoc(...)).

Также, пожалуйста, не используйте mysql_* ; функции mysql_* устарели, устарели и небезопасны. Используйте MySQLi или PDO вместо этого.

Редактировать: сначала я не понял вашего вопроса. Вот в чем проблема: mod_php работает внутри Apache, то есть запрашивает память через процесс Apache. Таким образом, память, требуемая $db->query(), используется Apache, а не отдельным процессом mod_php. Существуют некоторые известные проблемы с памятью в функциях mysql_*. Например, как описано здесь, mysql_query() буферизует все данные из запроса. Однако mod_php, по-видимому, не отслеживает это, потому что вы никогда не присваиваете эти данные переменным PHP. Таким образом, объем памяти Apache продолжает расти, но mod_php этого не осознает, поэтому ограничение памяти php.ini никогда не срабатывает.

Как я сказал выше, вам следует избегать функций mysql_* и класса MySQL и использовать либо MySQLi, либо PDO. Такое ошибочное поведение является одной из веских причин для этого. Удачи!

person elixenide    schedule 03.02.2014
comment
Может быть, мой английский плохой, но я повторюсь. Я знаю, почему код не работает, я знаю, как это решить. Я спрашиваю об ограничениях php. Почему php limit не работает в этом случае. - person user134880; 03.02.2014
comment
Сначала я неправильно понял ваш вопрос; Я отредактировал свой ответ, чтобы указать, почему PHP игнорирует ограничение памяти. - person elixenide; 03.02.2014
comment
Значит, проблема не в том, чтобы присвоить результат переменной? Это ошибка php? Похоже, это так. Таким образом, в этой ситуации пользователь может обойти ограничения php и отключить сервер. - person user134880; 03.02.2014
comment
Меньше ошибки PHP как таковой, больше ошибки mod_php/ошибки старой библиотеки MySQL. Пользователь не может обойти ограничения PHP, если в вашем коде нет ошибки; если бы ваш код не попал в бесконечный цикл, он бы использовал гораздо меньше памяти и не вышел бы из-под контроля. Конечно, злоумышленник всегда может перегрузить сервер с помощью DDoS-атаки (отправляя слишком много трафика на сервер с множества адресов), но это не имеет ничего общего с PHP; это правда, независимо от того, какие технологии вы используете. - person elixenide; 03.02.2014
comment
Не сравнивайте DDoS-атаку и простой цикл :) Я обновил PHP и MySQL до последних версий, использовал библиотеку mysqli и получил тот же результат. Ограничение памяти не работает в этом сценарии. - person user134880; 07.02.2014
comment
Я не знаю, что вам сказать, кроме как не создавать бесконечные циклы. :) Ясно, что Apache выделяет дополнительную память на каждый запрос, но mod_php не определяет превышение лимита. - person elixenide; 07.02.2014