读取大文本文件并将每行存储在数据库中

时间:2012-04-22 17:15:13

标签: php mysql

我编写了一个PHP脚本,它运行一个文本文件(实际上它是来自imdb的'list'文件)并将其存储在我的本地MySQL数据库中。

public static function updateMovies( $list ) {
    $offset = 15;               // movies.list start with movie names at line 16
    $handle = fopen($list, "r") or die("Couldn't get handle");
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle);
            if($offset!=0)
                $offset--;
            else
                if($buffer[0] != '"'){
                    $title = trim( substr( $buffer, 0, strpos( $buffer, '(' ) ) );
                    $year = intval(trim( substr( $buffer, strpos( $buffer,'(' )+1, 4 ) ));
                    Movie::create( $title, $year );
                }
        }
        fclose($handle);
    }
}

由于这些列表文件高达200MB,因此需要花费大量时间。默认情况下,PHP的MAX_EXECUTION_TIME设置为30秒。

我将此值设置为300只是为了尝试它是否有效。例如,我的'movies.list'文件大约是80MB,使用这个脚本300秒在我的数据库中创建了大约25000行。这不起作用,因为我甚至没有以“B”开头的电影。

我知道我可以将MAX_EXECUTION_TIME设置为0(无限制),但将来我不希望这个数据库在我的localhost上。我希望它在我的网络服务器上,据我所知,我的网络服务器主机MAX_EXECUTION_TIME设置为90.

你有什么想法来处理这个问题吗?

2 个答案:

答案 0 :(得分:1)

您可以: 使用set_time_limit(sec) 或者(更好)从command line通过cron条目运行脚本。这样你就可以避免许多其他非PHP相关的超时问题。

答案 1 :(得分:1)

我认为你没有把这种大型文件直接加载到你的数据库中的想法...特别是当它需要很长时间才能得出结论

我的建议

在本地将文件拆分为较小的块..然后在远程服务器上将其上传到您的数据库

示例(文档:http://en.wikipedia.org/wiki/Split_%28Unix%29

 exec('split -d -b 2048m ' . $list . ' chunks');

对于纯PHP实现,请参阅

http://www.php.happycodings.com/File_Manipulation/code50.html

define('CHUNK_SIZE', 1024*1024);
function readfile_chunked($filename, $retbytes = TRUE) {
    $buffer = '';
    $cnt =0;
    // $handle = fopen($filename, 'rb');
    $handle = fopen($filename, 'rb');
    if ($handle === false) {
      return false;
    }
    while (!feof($handle)) {
      $buffer = fread($handle, CHUNK_SIZE);
      echo $buffer;
      ob_flush();
      flush();
      if ($retbytes) {
        $cnt += strlen($buffer);
      }
    }
    $status = fclose($handle);
    if ($retbytes && $status) {
      return $cnt; // return num. bytes delivered like readfile() does.
    }
    return $status;
  }