在php中进行了大量的mysql_query调用后出现500错误

时间:2010-11-18 03:19:08

标签: php mysql explode fgets

我有一个php脚本,它遍历一个包含制表符分隔文件的文件夹,逐行解析它们并将数据插入到mysql数据库中。由于我的服务器的安全限制,我无法使用LOAD TABLE,因此无法访问配置文件。该脚本可以很好地解析1或2个较小的文件,但是当处理几个大文件时,我得到500错误。似乎没有任何错误日志包含与错误有关的消息,至少没有我的托管服务提供商允许我访问的消息。下面是代码,我也愿意接受有关我需要做的事情的替代方法的建议。最终,我希望每30分钟左右启动一次此脚本,插入新数据并在完成后删除文件。

编辑:在做出更改之后Phil建议,脚本仍然失败,但我现在在我的错误日志中有以下消息“mod_fcgid:在120秒内读取数据超时”,看起来像脚本超时,任何想法我在哪里可以更改超时设置吗?

$folder = opendir($dir);
    while (($file = readdir($folder)) !== false) {
        $filepath = $dir . "/" . $file;

        //If it is a file and ends in txt, parse it and insert the records into the db
        if (is_file($filepath) && substr($filepath, strlen($filepath) - 3) == "txt") {
            uploadDataToDB($filepath, $connection);
        }
    }

function uploadDataToDB($filepath, $connection) {
    ini_set('display_errors', 'On');
    error_reporting(E_ALL);
    ini_set('max_execution_time', 300);

    $insertString = "INSERT INTO dirty_products values(";

    $count = 1;

    $file = @fopen($filepath, "r");

    while (($line = fgets($file)) !== false) {
        $values = "";
        $valueArray = explode("\t", $line);
        foreach ($valueArray as $value) {
            //Escape single quotes
            $value = str_replace("'", "\'", $value);
            if ($values != "")
                $values = $values . ",'" . $value . "'";
            else
                $values = "'" . $value . "'";
        }

        mysql_query($insertString . $values . ")", $connection);
        $count++;
    }

    fclose($file);

    echo "Count: " . $count . "</p>";
}

1 个答案:

答案 0 :(得分:1)

我要做的第一件事是使用预备语句(使用PDO)。

使用mysql_query()函数,您将为每个插入创建一个新语句,并且您可能超出了允许的限制。

如果使用预准备语句,则只在数据库服务器上创建和编译一个语句。

实施例

function uploadDataToDB($filepath, $connection) {
    ini_set('display_errors', 'On');
    error_reporting(E_ALL);
    ini_set('max_execution_time', 300);

    $db = new PDO(/* DB connection parameters */);
    $stmt = $db->prepare('INSERT INTO dirty_products VALUES (
                         ?, ?, ?, ?, ?, ?)');
    // match number of placeholders to number of TSV fields

    $count = 1;

    $file = @fopen($filepath, "r");

    while (($line = fgets($file)) !== false) {
        $valueArray = explode("\t", $line);
        $stmt->execute($valueArray);
        $count++;
    }

    fclose($file);
    $db = null;

    echo "Count: " . $count . "</p>";
}

考虑到您希望按计划运行此脚本,我将完全避免使用Web服务器,并使用cron或主机提供的任何计划服务通过CLI运行脚本。这将帮助您避免在Web服务器中配置任何超时。