• ベストアンサー

◆速い、ファイル読み込みは?

いつもお世話になっております。 $all_listには1000以上のURLが含まれています。 それを1ページずつ読み込みある単語を探すという処理を作っています。 しかし、file関数が遅い。。。その為、サーバがダウンしないか心配。 phpのfile関数は極端に遅いという事が他の書き込みでもあるのですが、他に良い関数や他の方法のアイディアがある方がいればご教授下さい。 fopen等も試してみましたが。。。 for($a = 0; $a < ($num - 1); $a++) { $html = @file("$all_list[$a]"); if($html){ foreach( $html as $key => $value ){ $rcd = ereg("$search", $value); if($rcd){ $INFO[][url] = $all_list[$a] } } } } @fclose($html);

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

file()が遅いというか、httpでアクセスするのですからオーバーヘッドが あるのは仕方ないでしょう。 もし気になるようであればPEARのHTTP_Requestなどで処理してみては いかがでしょうか? また、並行処理的な手法でアプローチするのも手かもしれません

gogovamos
質問者

補足

>また、並行処理的な手法でアプローチするのも手かもしれません バックエンド側でfile()を実行させるということでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.6

どんな案件か知らないので具体的にはあれですけど、 結局やることがDLとページ検索なら HyperEstraierでもいれて、DLと検索両方やらせては?と思いました。 自前サーバで実行時間に問題ないならPHPでもいいと思いますが PHPの通信はあまり信用してないのでPHPのcurl関数?とか使用しては?という意味です。 先にDLしてても1000ファイルの文字検索だとまだ時間かかるのでは? 単に集計用途で週1回のアクセスとかならもうそのままでもいいと思いますが、 やっぱり目的が不明なのでなんとも。

gogovamos
質問者

補足

環境はPHP + (一応Mysqlと自前サーバです)。 (1)あるサイトの全自リンクを全て取得。 (2)そのURLリストを解析し、検索単語を見つける。 (3)そのURLを抜き出す。 (2)(3)の時に時間を要していたので、今回の質問に至りました。 皆さんのアドバイスを受け、バックエンドでの処理を考えています。 1000ファイル以上の検索でも、バックエンド側ならある程度時間がかかってもサーバのタイムアウト等の心配はない(ですよね...)。 PHPはかじる程度でしたので、今回の質問で色々勉強になりました。

全文を見る
すると、全ての回答が全文表示されます。
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.5

クローラとかでよいならそれこそ、シェルでwgetでも定期的に 走らせればよいのでは?

全文を見る
すると、全ての回答が全文表示されます。
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.4

#3 あら、HTTP通信の話でしたか? PHP実行1発で1000のURLにアクセスするのはきつい仕様ですね。 タイムアウトがきかない環境であれば異常に時間もかかります。 libcurlとか多言語を使うとか、並列で取得しにいくとか、 外部のクローラとかで先にDLしておくとか。

gogovamos
質問者

補足

>libcurlとか多言語を使うとか、並列で取得しにいくとか、 バックエンドで処理するということでしょうか? >外部のクローラとかで先にDLしておくとか。 こちらの詳細を教えていただけますか?

全文を見る
すると、全ての回答が全文表示されます。
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.3

file()は配列を生成する分遅いのは仕方ないかと。 へぼPCでベンチマークに挑戦。 データは 100文字x1000行x4ファイル 1. file() 2. fopen() fread() 3. readfile() ob_get_contents() 4. include() //データ形式は <?php return ''; 普通はfopenでいいと思いますが、データ更新より読み込みの方が多いのであれば、 4. みたいにキャッシュ的なことをするのが速度改善になるかと。 <?php for ($i = 1, $data = ''; $i<= 4 ; $i++) {  if ($mode == 1) { // 0.0330sec   $file = 'data/data' . $i . '.dat';   $tmp = file($file);   $data .= implode('', $tmp);  } else if ($mode == 2) { // 0.0082sec   $file = 'data/data' . $i . '.dat';   $fp = fopen($file, 'r');   while (!feof($fp)) {    $data .= fread($fp, 8192);   }   fclose($fp);  } else if ($mode == 3) { // 0.0099sec   $file = 'data/data' . $i . '.dat';   //ob_start();   readfile($file);   $data .= ob_get_contents();   ob_clean();  } else if ($mode == 4) { // 0.0062sec   $file = 'data2/data' . $i . '.dat';   $data .= include $file;  } }

全文を見る
すると、全ての回答が全文表示されます。
  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.2

ある単語を探す部分に、正規表現を使うと、 その分付加がかかります。可能なら 単純なSTR処理関数に置き換えれば、早くなるかも(保障無し) <ベンチマークテストが必要>

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PHP[ereg_replace]1文字の置き換え

    現在「abcdefga1u2r3」などランダムな文字列の中から aをcにcをaにbをvにといった文字列の置き換えを検討しています。 結果:「cvadefgc1u2r3」となってほしいのですが 下記のコードですと 「avadefga1u2r3」と置き換えた文字を さらに置き換えてしまいます。 結果と同様に同時に置き換えて完結できるプログラムは どのように書けばよろしいのでしょうか。 ================= $rcd = "abcdefga1u2r3"; for($i=0;$i<sizeof($rcd);$i++){ $rcd[$i] = ereg_replace("a", "c", $rcd[$i]); $rcd[$i] = ereg_replace("c", "a", $rcd[$i]); $rcd[$i] = ereg_replace("b", "v", $rcd[$i]); $result[$i]=$rcd[$i]; $i=$i+1; } $fp = fopen("text.txt","w"); foreach($result as $newdata){ fwrite($fp, $newdata); } fclose($fp);

    • ベストアンサー
    • PHP
  • CSVファイルを更新する処理

    CSVに追加や削除、一覧表示、更新をする処理を書いたのですが 更新処理だけうまくいかずに躓いています。 readメソッドのreturn $files;のところで下記の syntax error, unexpected '$files' (T_VARIABLE)というエラーが出てしまいます。 なぜエラーが出ているか教えていただけるとありがたいです。 <?PHP function con($hantei, $num, $name, $age, $address){ $data = [ $num, $name, $age, $address ]; $datas = [$data]; // 追加 if($hantei === 'add'){ $fp = fopen('data.csv', 'a'); foreach($datas as $data) { $line = implode(',' , $data); fwrite($fp, $line . "\n"); } fclose($fp); //更新 } elseif ($hantei === 'update') { function read() { $FILENAME = 'data.csv'; $file = fopen($FILENAME, 'r'); while($data = fgetcsv($file)) { $files[] = $data; }   fclose($file);   return $files; } function replace($num, $name, $age, $address) { // read() $files = read(); $arr = array(); foreach($files as $key => $el) { // [0][a, b, c, d] // [1][a, b, c, d] if ($el[0] == $num) { // $arr[0][0] = $num ... $arr[$key] = array($num, $name, $age, $address); } else { $arr[$key] = array($el[0], $el[1], $el[2], $el[3]); } }    return $arr; } replace(); function write($arr){   $FILENAME = 'data.csv'; $file = fopen($FILENAME, 'w');   foreach ($arr as $v) {    fputcsv($file,$v); }    fclose($file); } $arr = replace($num, $name, $age, $address); write($arr); //削除 } elseif ($hantei === 'dalete') { $file = file('data.csv'); unset($file[$num]); file_put_contents('data.csv', $file); //一覧表示 } elseif ($hantei === 'list') { $fp = fopen('data.csv', 'r'); $readed = fread($fp, filesize('data.csv')); print_r($readed); fclose($fp); } } con('update', 1, 'name', 3, 'address');

    • 締切済み
    • PHP
  • file関数とファイルポインタ

    ファイルの内容を(書き換えるために一旦)読み込む時に、 fgets関数と違ってfile関数は fopen関数を使わなくても済む、ということで 便利なので使ってみようと思っているのですが、 ちょっと躓いています。 set_file_bufferやflock、rewindが必要なのですが、 これらはどれも引数にファイルポインタを使います。 fopen関数を使っていないのでコレがないのですが、 どうすればいいのでしょうか? fopenのあとにfileを使う? fopenを使わなくても閉じる時にはfcloseが必要? でもfcloseもファイルポインタを使うし… よろしくお願いします。

    • ベストアンサー
    • PHP
  • array をつかってcsv ファイルを作る

    もとになるcsvファイルから、いらない行を削除して新しいcsvファイルを作りたいです。 そこで、このようにしてみました。 $fptemp = fopen('data-temp.csv', "a+"); if (($handle = fopen('data.csv', "r")) !== FALSE) { while (($data= fgetcsv($handle)) !== FALSE) { if(条件){ $list = array($data); fputcsv($fptemp, $list); } } } fclose($handle); fclose($fptemp); ところが、結果の行にはすべてArray とだけ出力されます。 もとの行をそのまま出すにはどうしたら良いでしょうか?

    • ベストアンサー
    • PHP
  • アクセスログの解析スクリプト

    アクセスログの解析スクリプト Googleからの訪問者の検索ワード集計を行いたいと思っております。 本当はperlで書きたかったのですが、 全く知識がないためphpにしました。 それに正規表現について全くわかっていませんが、 以下までは何とか辿り着く事が出来ました。 <?php $fp_in = fopen("./access_log", "r"); $fp_out = fopen("./out.log", "a"); $pattern = "http:\/\/www\.google\.co(.*)\/search\?(.*)$". "(/[-.!~*\d\w;/?:@&=+$,%#]+)?"; while (!feof($fp_in)) {   $data = fgets($fp_in, 65536);   if (ereg ( $pattern, $data, $url )) {     $ary = split('&', $url[2]);     foreach ($ary as $value) {       if (strstr ($value, 'q')) {         if (!fwrite($fp_out, $value)) {           print "Cannot write to file ($filename)";           exit;         }       }     }   } } fclose($fp_in); fclose($fp_out); ?> 「q」で始まる配列をout.logに出力しております。 ここから文字列を分割して行こうと思っているのですが、 検索ワードは半角・全角スペースが混在しているため、 どのようにしたら良いかつまずきました。 手詰まり状態&もっと効率的なロジックがあると思っています。 どうかアドバイスをお願いいたします。

    • 締切済み
    • PHP
  • 新規ファイルを作成する

    にはどうしたらいいのでしょうか? <?php $file='gomi.dat'; $in=isset($_POST['in'])?$_POST['in']:'bad'; if(file_exists("$file")) { $a=file("$file"); foreach($a as $value) { echo "$value<br/>"; } } $fp=fopen("$file","w"); // <-------------- fwrite($fp,"$in\n"); fclose($fp); ?> <form method="post" action="<?= $_SERVER['PHP_SELF'] ?>"> <input type="text" name="in"/> <input type="submit" value="send"/> </form> は動きませんが $fp=fopen("$file","w"); // <-------------- を $fp=fopen("$file","r+"); // <-------------- としてあらかじめ空の gomi.dat (モード777)を作っていれば動きます どうしたら $fp=fopen("$file","w"); // <-------------- にしても動くようになるでしょうか?

    • ベストアンサー
    • PHP
  • ファイルを読み込み一部を書き換え

    ファイルを読み込み一部を書き換えたいです。 a.phpを読み込み$newという配列渡し、abcという文字があったら $dataのbbbに書き換えたいのですうまくいきません。 $data = "bbb"; $handle = @fopen("a.php", "r+"); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle, 4096); $new = ereg_replace("abc", $data, $new); fwrite($fp,$new); } } fclose($handle); 助言お願いします。

    • ベストアンサー
    • PHP
  • C言語のファイルの読み書き

    以下のようなプログラムを作成したいのですが、どうしても作成できません。 さまざまなサイトを参考にしたのですが、まったく理解できませんでした。 具体的なプログラム式をご教授願います。 よろしくおねがいします…。 1)複数の学生の情報を読み取り配列を行う struct student a [LIST_SIZE_A] 2)配列に代入した情報をファイルに書き込む fopen("…","w"); … fclose() 3)配列に代入した情報をファイルに追加する fopen("…","a"); … fclose() 4)ファイルの内容を表示する fopen("…","r")

  • PHPでのファイル操作

    Phpで一覧画面を作成しています。 フォームからの情報をリストごと各行でテキストファイルに書き込ませています。 管理画面で削除、変更を行いたいんですが、特定のファイルの行数を削除できないので困っています。 $garls_list = file("./dat/garls_list.php"); $fp = fopen("./dat/garls_list.php", "w"); foreach ($garls_listt as $dat_line => $new_list) { if ($dat_line == $_POST["list"]) { // 何も書き込まない→この行を削除したと同一 } else { fwrite($fp, $new_list); } } fclose($fp); これだとファイルが真っ白になってしまいます。 詳しい方がいらっしゃいましたらご教授お願いします。 . グレード この質問に補足する.

    • 締切済み
    • PHP
  • 複数ファイルの同時読み込みの方法と脱初心者向け参考書

    ループにて、複数のファイル(.txt)を同時に読み込む方法はあるのでしょうか。(厳密に言えば、完全に同時ということではなく、時間差をつけてということ)。以下のプログラムではループ自体が行われていないようでした。while分とfreadの使い方に問題があると思うのですが… ~略~ int a,b; FILE *fp1,*fp2; fp1 = fopen(…,"r"); if(fp1 == NULL) {・・・;} fp2 = fopen(…,"r"); if(fp2 == NULL) {・・・;} while((a = fread(…,1,8,fp1)) != 0) { while(fread(…,1,8,fp2)) { ~略~ } } fclose(fp1); fclose(fp2); 以下略~ また、2つ目のwhileを削除し次のようにすると1つ目のファイル(fp1)は読み込めるのですが、2つ目のファイル(fp2)が読み込めていないようでした。 ~略~ while((a = fread(…,1,8,fp1)) != 0) { b = fread(…,1,8,fp2); 以下略~ 解決方法を教えていただけないでしょうか。 次にいわゆる脱初心者向け(?)ともいえる参考書について。 初心者向けの入門書に載っている関数についての説明などは、どれも最も基本的な機能についてのものがほとんどで、少し応用したものは載ってません。 また、多少上級向けになると、例えば「int sprintf(char *buf,const char *format,…)」や、「int printf(const char *format,…)」といった具合にいかにも専門書らしくなっています。また使用例も、他に見たこともない関数が同時に出てきてまるで手がつけられません。 それはそれで重要なことであるのはわかるのですが、「sprintf(s,"%d%d",a,b) s文字配列、a,b整数値」という理解しやすい書き方をあわせて載せてある、「関数辞典」みたいな参考書とかは市販されているのでしょうか。私の理想通りの物とまでは言いませんが、お薦めのものを推薦していただければ幸いです。 よろしくお願いします。