2014-03-04 59 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

將任務提交給池時選擇的工作器是隨機的,這可能不是合意的,可以檢測到工人是否忙,但這會使示例複雜化。

延伸閱讀:

相關問題