Почему этот PHP-код зависает при вызовах mysql_query ()? - PullRequest
3 голосов
/ 27 августа 2009

У меня проблемы с этим скриптом PHP, где я получаю сообщение об ошибке

Неустранимая ошибка : максимальное время выполнения 30 секунд превышено в / var / www / vhosts / richmondcondo411.com / httpdocs / place.php в строке 77

Код висит здесь:

function getLocationsFromTable($table){

    $query = "SELECT * FROM `$table`";
    if( ! $queryResult = mysql_query($query)) return null;

    return mysql_fetch_array($queryResult, MYSQL_ASSOC);

}

и здесь (пока):

function hasCoordinates($houseNumber, $streetName){

    $query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";
    $row = mysql_fetch_array(mysql_query($query), MYSQL_ASSOC);
    return ($row) ? true : false;

}

оба в строке с вызовом mysql_query ().

Я знаю, что использую разные стили для каждого фрагмента кода, потому что я играл с первым, пытающимся изолировать проблему.

$table в первом примере - это «школа», то есть таблица, которая определенно существует. Я просто не знаю, почему он сидит там и ждет тайм-аут вместо того, чтобы выдать мне ошибку.

MySQL-запросы от остальной части сайта работают должным образом. Я пытался убедиться, что я был подключен, как это

//connection was opened like this:
//$GLOBALS['dbh']=mysql_connect ($db_host, $db_user, $db_pswd) or die ('I cannot connect to the database because: ' . mysql_error());

if( ! $GLOBALS['dbh']) return null;

и он прошел этот штраф. Есть идеи?

Обновление


Это не размер таблиц. Я попытался получить только пять записей, и это все еще истекло. Также с этой строки:

$query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";

он ищет только одну конкретную запись, и вот где она висит.

Ответы [ 6 ]

3 голосов
/ 27 августа 2009

Похоже, что MySQL занят передачей действительных данных обратно в PHP, но их так много, что нет времени завершить процесс, пока Apache не завершит процесс PHP для превышения максимального времени выполнения.

Действительно ли необходимо выбрать все из этой таблицы? Сколько это данных? Существуют ли BLOB или TEXT столбцы, которые будут учитывать конкретное отставание?

Анализ того, что отбирается и что вам действительно нужно, будет хорошим началом.

2 голосов
/ 27 августа 2009

Время, потраченное на ожидание MySQL запросов для возврата данных, не учитывается во время выполнения. Смотри здесь.

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

1 голос
/ 27 августа 2009

-Если вы увеличили время выполнения до 300, и оно все равно прошло эти 300 секунд, я думаю, что по определению у вас происходит нечто вроде бесконечного цикла.

-Моим первым подозрением будет ваш php-код, поскольку mysql используется для работы с большими наборами данных, поэтому обязательно убедитесь, что вы действительно выполняете запрос mysql (умрите прямо перед ним с сообщением об ошибке или чем-то еще ).

-Если это работает, попробуйте выполнить этот запрос с известными данными в вашей базе данных через некоторый графический интерфейс базы данных или через командную строку, если у вас есть доступ к базе данных, или замените код на известные хорошие числа, если вы не т.

-Если запрос работает сам по себе, я бы проверил наличие случайных SQL-инъекций с переменными $ houseNumber или $ streetName, как упомянул VolkerK.

1 голос
/ 27 августа 2009

Если параметры $ houseNumber и $ streetName для hasCoordinates () уже очищены для запроса MySQL (очень маловероятно), вам необходимо обработать их с помощью mysql_real_escape_string () для предотвращения (преднамеренных или непреднамеренных) SQL-инъекций , Чтобы mysql_real_escape_string () работала правильно (например, если вы изменили кодировку с помощью mysql_set_charset ), вы также должны передать ресурс соединения MySQL в функцию.

Установлено ли сообщение об ошибке на E_ALL, и вы смотрите на error.log веб-сервера (или установили display_erorrs = On)?

Попробуйте это

function hasCoordinates($houseNumber, $streetName) {
  $houseNumber = mysql_real_escape_string($houseNumber);
  $streetName = mysql_real_escape_string($streetName);
  $query = "
    EXPLAIN SELECT
      lat,lng
    FROM
      geocache
    WHERE
      House='$houseNumber'
      AND StreetName='$streetName'
  ";
  $result = mysql_query($query) or die(mysql_error());
  while ( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
    echo htmlspecialchars(join(' | ', $row)), "<br />\n";
  }
  die;
}

и обратитесь к http://dev.mysql.com/doc/refman/5.0/en/using-explain.html для интерпретации выходных данных.

1 голос
/ 27 августа 2009

Я не знаю размер вашего стола, но попробуйте использовать LIMIT 10 и посмотрите, все еще зависает.

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

1 голос
/ 27 августа 2009

Тайм-аут вашего кода пытается подключиться или он подключается и зависает в запросе?

Если ваш код на самом деле проходит вызов mysql_query (даже если ему приходится долго ждать до истечения времени ожидания), вы можете использовать функцию mysql_error, чтобы определить, что произошло:

mysql_query("SELECT * FROM table");
echo mysql_errno($GLOBALS['dbh']) . ": " . mysql_error($GLOBALS['dbh']) . "\n";

Затем можно использовать номер ошибки, чтобы определить подробную причину ошибки: Коды ошибок MySQL

Если ваш код висит на запросе, вы можете попытаться описать и запустить запрос в клиенте командной строки mysql, чтобы увидеть, является ли это проблемой размера данных. Вы также можете увеличить максимальное время выполнения, чтобы запрос мог завершиться и посмотреть, что происходит:

ini_set('max_execution_time', 300); // Allow 5 minutes for execution
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...