PHP脚本应该在失败时继续工作

PHP脚本应该在失败时继续工作

问题描述:

I know people complain usually about scripts not working, but here is a case where it keeps working even if I want it to stop.

I have a CSV parser that analyzes lines and inserts entries in a DB table. I am using PDO and Zend Framwork for the project. The code works fine.. too fine in fact.

public function save()
{
    $memory_limit = ini_get('memory_limit');
    ini_set('memory_limit', '512M');

    $sql = "
        INSERT INTO my_table (
            date_start,
            timeframe,
            type,
            country_to,
            country_from,
            code,
            weight,
            value               
        ) VALUES (?,?,?,?,?,?,?,?)
        ON DUPLICATE KEY UPDATE 
            weight = VALUES(weight),
            value = VALUES(value)
    ";
    if ($this->test_mode) {
        echo $sql;
        return;
    }
    $stmt = new Zend_Db_Statement_Pdo($this->_db, $sql);
    foreach($this->parsed_data as $entry){
        $stmt->execute(array_values($entry));
        $affected_rows = $stmt->rowCount();
        if ($affected_rows){
            $this->_success = true;
        }
    }
    unset($this->parsed_data, $stmt, $sql);
    ini_set('memory_limit', $memory_limit);
}

The script takes various seconds to complete as I am parsing a big file. The problem appears when I am trying to stop the script, with ESC or even by closing the page. The script does not stop until it finishes to insert all entries. Not even an Apache reload is not fixing this, probably a restart will do it.

I am thinking that this is not normal behaviour and maybe I am doing something wrong so I am asking for suggestions.

Thanks.

UPDATE ignore_user_abort is off (default behaviour) so user abort should be considered..

I'm pretty sure that's standard PHP behaviour - just because the browser goes away doesn't mean it won't stop processing the script. (Although restarting Apache, etc. will achieve this goal.)

To change this behaviour, you can use ignore_user_abort.

That said, "PHP will not detect that the user has aborted the connection until an attempt is made to send information to the client", which I suspect may be the issue you're experiencing.

See the above link and the PHP runtime configuration information for more info.

It is not wrong. Your tries won't work because:

  • ESCape - because it is totally unrelated to the working of a page - most browsers don't actually react to it
  • closing (or refreshing) the page - again, not related - the SERVER is doing something, and PHP will NOT stop when the client-side stops - server can't actually know if the client closed or refreshed a page
  • Apache reload - won't kill the PHP forked process

Restart WOULD do it - this will kill PHP processes and stuff. Although it is kinda troublesome.

Way to do this (if the long execution is undesirable), is to actually set an execution time limit, using PHP function set_time_limit(), or to make the parsing more optimal (if it is not).