2014-03-04 63 views
1

我需要帮助^^ 我需要的是脚本,它将打开并读取文件夹'csv/files'中的所有.csv文件,然后在“if”中执行此操作。那么,当我只有一个文件,它工作得很好。我设法构建了一些脚本,但它没有正常工作,但没有出现“错误行”...... 那么,有人可以看看我的代码并告诉我我做错了什么吗?读取文件夹中的多个csv文件

<?php 
foreach (glob("*.csv") as $filename) { 
    echo $filename."<br />"; 

    if (($handle = fopen($filename, "r")) !== FALSE) { 
     while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) { 
      $url = $data[0]; 
      $path = $data[1]; 

      $ch = curl_init($url); 
      $fp = fopen($path, 'wb'); 
      curl_setopt($ch, CURLOPT_FILE, $fp); 
      curl_setopt($ch, CURLOPT_HEADER, 0); 
      curl_exec($ch); 
      curl_close($ch); 
      fclose($fp); 

     } 
     fclose($handle); 
    } 
} 
?> 
+0

也许脚本只是挂起...读取多个文件或发送HTTP请求是相当沉重和耗时的过程。 – Leri

+0

尝试将glob(“* .csv”)读入变量,然后循环。否则它将以无限循环结束。 – SajithNair

+0

@SajithNair不,它不会:http://stackoverflow.com/a/14854568/1283847 – Leri

回答

2

这是多线程的主要候选人,和这里的一些代码来做到这一点:

<?php 
class WebWorker extends Worker { 
    public function run() {} 
} 

class WebTask extends Stackable { 

    public function __construct($input, $output) { 
     $this->input = $input; 
     $this->output = $output; 
     $this->copied = 0; 
    } 

    public function run() { 
     $data = file_get_contents($this->input); 
     if ($data) { 
      file_put_contents(
       $this->output, $data); 
      $this->copied = strlen($data); 
     } 
    } 

    public $input; 
    public $output; 
    public $copied; 
} 

class WebPool { 
    public function __construct($max) { 
     $this->max = $max; 
     $this->workers = []; 
    } 

    public function submit(WebTask $task) { 
     $random = rand(0, $this->max); 

     if (isset($this->workers[$random])) { 
      return $this->workers[$random] 
       ->stack($task); 
     } else { 
      $this->workers[$random] = new WebWorker(); 
      $this->workers[$random] 
       ->start(); 
      return $this->workers[$random] 
       ->stack($task); 
     } 
    } 

    public function shutdown() { 
     foreach ($this->workers as $worker) 
      $worker->shutdown(); 
    } 

    protected $max; 
    protected $workers; 
} 

$pool = new WebPool(8); 
$work = []; 
$start = microtime(true); 

foreach (glob("csv/*.csv") as $file) { 
    $file = fopen($file, "r"); 

    if ($file) { 
     while (($line = fgetcsv($file, 0, ";"))) { 
      $wid = count($work); 
      $work[$wid] = new WebTask(
       $line[0], $line[1]); 
      $pool->submit($work[$wid]); 
     } 
    } 
} 

$pool->shutdown(); 
$runtime = microtime(true) - $start; 

$total = 0; 
foreach ($work as $job) { 
    printf(
     "[%s] %s -> %s %.3f kB\n", 
     $job->copied ? "OK" : "FAIL", 
     $job->input, 
     $job->output, 
     $job->copied/1024); 
    $total += $job->copied; 
} 
printf( 
    "[TOTAL] %.3f kB in %.3f seconds\n", 
    $total/1024, $runtime); 
?> 

这将创建一个线程池线程的最大数,那么它会通过一个目录中读取输入每行的分号分隔的csv文件;输出时,它将提交任务以读取输入,并将输出异步写入池以供执行,同时主线程继续读取csv文件。

我已经使用了最简单的输入/输出file_get_contentsfile_put_contents,这样就可以看到它是如何工作的,没有cURL

将任务提交给池时选择的工作器是随机的,这可能不是合意的,可以检测到工人是否忙,但这会使示例复杂化。

延伸阅读:

相关问题