2017-01-16 11 views
0

こんにちは、私は同じURLから100のpdfファイルを取得する必要があるプロジェクトを構築してPHPに新しいです。私はこれらのpdfファイルを取得してローカルに保存するためにカールを使用しています。しかし、私のコードはこれらのファイルをフェッチするのに40秒近くかかりますが、要件によると10秒以上かかることはありません。私はドキュメントを読んで、curl-multi-initを見つけました。また、このpostによると、curl_multi_initは時間の半分を取るべきです。しかし、curl-multi-initを使用した後も、それは約40秒かかる。また私はこれを見たquestion。私は長い間、ここから本当に立ち往生しています。これについての助けに感謝します。ここに私のコードです -PHPのカールを使ったマルチスレッド

$output_path = dirname(__FILE__).'/tmp/'; 
$baseUrl = "https://xyz.s3.amazonaws.com/PdfFiles/"; 
$file = fopen("filenames.txt", 'r'); 
if($file){ 
    $fileArr = explode("\n", file_get_contents('filenames.txt')); 
} 
if(!file_exists($output_path)){ 
    mkdir($output_path, 0777, true); 
} 
echo "Started fetching at ". date("h:i:sa"); 
for ($i = 0; $i<count($fileArr); $i+=2){ 
    $url1 = $baseUrl."".$fileArr[$i]; 
    $url2 = $baseUrl."".$fileArr[$i+1]; 
    $file1_path = $output_path."".$fileArr[$i]; 
    $file2_path = $output_path."".$fileArr[$i+1]; 
    $ch1 = curl_init($url1); 
    $ch2 = curl_init($url2); 
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); 
    $mh = curl_multi_init(); 
    curl_multi_add_handle($mh, $ch1); 
    curl_multi_add_handle($mh, $ch2); 
    $running = null; 
    do{ 
     curl_multi_exec($mh, $running); 
    }while($running>0); 
    $result1 = curl_multi_getcontent($ch1); 
    $result2 = curl_multi_getcontent($ch2); 

    file_put_contents($file1_path, $result1); 
    file_put_contents($file2_path, $result2); 
} 
echo "fetched all files at ". date("h:i:sa"); 

私は非常にPHPに新しいです、そして本当にここで立ち往生しました。それについての助け?

+0

エラーは何ですか? FYIこれはマルチスレッドではありません。 –

+0

これはエラーを出すものではありません。しかし、私は 'curl_init'を使用していたのと同じ時間を取っていますが、この記事によれば、" http://arguments.callee.info/2010/02/21/multiple-curl-requests-with-php/ "curl_multi_init curl_initより半分の時間がかかります – Sinscary

+0

時間の半分?それはBSの山です。確かに、ランダムチャンスでは、スピードは半分になるかもしれませんが、ほとんど起こりません – hanshenrik

答えて

0

代わりに(IMO本当の痛みです)PHPでcurl_multiを最適化する(あなたはPHP-pthreadsをサポートできるかどうか、マルチスレッド)、私はむしろ、マルチプロセッシングを示唆

例えば、

$output_path = dirname (__FILE__) . '/tmp/'; 
$baseUrl = "https://xyz.s3.amazonaws.com/PdfFiles/"; 
$file = fopen ("filenames.txt", 'r'); 
if ($file) { 
    $fileArr = explode ("\n", file_get_contents ('filenames.txt')); 
} 
if (! file_exists ($output_path)) { 
    mkdir ($output_path, 0777, true); 
} 
echo "Started fetching at " . date ("h:i:sa"); 
$processes = array(); 
for($i = 0; $i < count ($fileArr); ++ $i) { 
    $url1 = $baseUrl . "" . $fileArr [$i]; 
    $file1_path = $output_path . "" . $fileArr [$i]; 
    $processes [] = proc_open ('php downloader.php ' . escapeshellarg ($url1) . ' ' . escapeshellarg ($file1_path)); 
} 

while (1) { 
    $running=false; 
    foreach ($processes as $processes) { 
     if (proc_get_status ($process) ['running']) { 
      $running=true; 
      break; 
     } 
    } 
    if(!$running){ 
     //all processes has finished 
     break; 
    } 
    sleep(1);//sleep a little to not spam-waste cpu... 
} 
foreach ($processes as $processes) { 
    if (proc_get_status ($process) ['exitcode']!==0) { 
     echo "FIXME, DOWNLOAD ERROR"; // NO TIME TO code now 
    } 
    proc_close($process); 
} 
echo "fetched all files at " . date ("h:i:sa"); 
を試してみてください

このように見えるdownloader.phpを持っています

<?php 
declare(strict_types=1); 
if($argc!==3){ 
    fprintf(STDERR,'wrong number of arguments!\nusage: '.$argv[0].' url savepath'); 
    die(1); 
} 
$url=$argv[1]; 
if(false===filter_var($url,FILTER_VALIDATE_URL)){ 
    fprintf(STDERR,'invalid url'); 
    die(1); 
} 
$savepath=$argv[2]; 
$fp=fopen($savepath,'c');// or use 'w' if you want to truncate instead of append on existing file 
if(false===$fp){ 
    fprintf(STDERR,'unable to open savepath: '.$savepath); 
    die(1); 
} 
$ch=curl_init($url); 
if(!curl_setopt_array($ch,array(
     CURLOPT_FOLLOWLOCATION=>true, 
     CURLOPT_SSL_VERIFYPEER=>false,//or not? 
     CURLOPT_ENCODING=>'', 
     CURLOPT_FILE=>$fp, 
))){ 
    throw new RuntimeException('curl_setopt_array failed. errno:'.curl_errno($ch).' error: '.curl_error($ch)); 
} 
if(!curl_exec($ch)){ 
    throw new RuntimeException('curl_exec failed. errno:'.curl_errno($ch).' error: '.curl_error($ch)); 
} 
curl_close($ch); 
fclose($fp); 
die(0); 
関連する問題