Выполнение запроса в цикле приводит к завершению работы скрипта после первой итерации - PullRequest
0 голосов
/ 02 февраля 2010

озадачен здесь .... Этот код:

$qry = sprintf("INSERT INTO news_sites_homepage_grab 
                VALUES ('', %d, '%s', NOW(), NOW())", 
                        $site_id, mysql_real_escape_string($html));

... выполняется в цикле, где $html изменяется каждый раз. Этот код выполняется один раз, но в следующий раз сценарий просто умирает. Нет предупреждений / ошибок, ничего. $html - это строка, представляющая веб-страницу, поэтому она может быть очень длинной. Я увеличил предел памяти в PHP до 32M и установил max_allowed_packet в MySQL до 16M, но ничего.

У кого-нибудь есть идеи? Спасибо!

ОБНОВЛЕНИЕ: вот функция, которая вызывается в цикле.

function save_html($site_id, $html) {
global $db;
try {
    $qry = sprintf("INSERT INTO site_grab VALUES ('', %d, '%s', NOW(), NOW())",
                   $site_id,
                   mysql_real_escape_string($html));

    $db->insert($qry);

}
catch(Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

return;
}

Ответы [ 2 ]

3 голосов
/ 02 февраля 2010

Я бы рекомендовал отказаться от устранения этой проблемы и переключиться на PDO . Он поддерживает подготовленные операторы , которые не подвержены внедрению SQL при использовании параметров и намного более производительны для повторных запросов.

Вот простой рефакторинг вашей функции, который предполагает, что $db содержит экземпляр PDO:

function save_html($site_id, $html) {
    global $db;
    static $insert = Null;
    if (isnull($insert)) {
        /* explicitly name the columns, in case you later add more to the table
           or change their order. I'm also guessing `id` is auto-incrementing,
           so I'm leaving it out.
         */
        $insert = $db->prepare("INSERT INTO site_grab (sid, site_text, date_added, date_modified) VALUES (?, ?, NOW(), NOW())");
    }
    try {
        $insert->execute(array($site_id, $html));
    } catch(Exception $e) {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }

    return;
}

Если date_added имеет тип TIMESTAMP, вы можете установить его значение по умолчанию CURRENT_TIMESTAMP и оставить его вне вставки. Или добавьте свойство ON UPDATE CURRENT_TIMESTAMP в столбец date_modified, что означает, что вам не нужно явно устанавливать поле при обновлении строки. Если вставка будет более распространена, чем обновление, сделайте первое; в противном случае сделайте последнее.

Вы также можете хранить подготовленные операторы в объекте, чтобы они были доступны из нескольких функций, и заменить глобальный $db на какой-то локатор службы (самый простой способ - использовать статическую функцию или свойство некоторого класса) или используйте внедрение зависимостей (см. « Инверсия контейнеров управления и шаблон внедрения зависимостей »).

0 голосов
/ 02 февраля 2010

Я предпочитаю использовать PDO и подготовленные операторы, но чтобы (попытаться) ответить на ваш вопрос, попробуйте добавить $ db в качестве идентификатора ссылки в функцию mysql_real_escape_string ().

Это помогает? Если нет, попробуйте повторить вывод функции mysql_error ().

Извините за отсутствие форматирования, я мобильный банкомат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...