ホームページ  >  記事  >  バックエンド開発  >  PHPでファイルを読み取る正しい方法

PHPでファイルを読み取る正しい方法

巴扎黑
巴扎黑オリジナル
2016-11-24 15:05:071478ブラウズ

PHP のさまざまなファイル関数の使用方法を学びます。 fopen、fclose、feof などの基本的なファイル関数を確認し、fgets、fgetss、fscanf などの読み取り関数について学習します。そして、1 行または 2 行のコードでファイル全体を処理する関数を見つけました。

方法が何通りあるか数えてみましょう

PHP のような最新のプログラミング言語を使用する楽しみの 1 つは、利用可能なオプションが膨大にあることです。特にファイル処理に関しては、PHP は Perl のモットーである「方法は複数ある」を簡単に勝ち取ります。しかし、非常に多くのオプションが利用可能であるため、その作業に最適なツールはどれでしょうか?もちろん、実際の答えはファイル解析の目的によって異なるため、時間をかけてすべてのオプションを検討する価値があります。


伝統的な fopen メソッド

fopen メソッドは、元 C および C++ プログラマーにとっておそらく最もよく知られているものです。なぜなら、これらの言語を使用したことがあれば、それらは多かれ少なかれ何年も自由に使えるツールだからです。これらの方法のいずれでも、リスト 1 に示すように、ファイルは fopen (データの読み取りに使用される関数) を使用する標準的な方法で開かれ、その後 fclose を使用して閉じられます。

リスト 1. fgets を使用してファイルを開いて読み取る
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
echo $line;
}
fclose($file_handle);

長年のプログラミング経験を持つほとんどのプログラマーはこれらの関数に精通していますが、詳しく説明してみましょう。次の手順を効果的に実行します:
ファイルを開きます。 $file_handle には、ファイル自体への参照が保存されます。
ファイルの最後に到達したかどうかを確認してください。
ファイルの終わりに達するまでファイルの読み取りを続け、読み取られた各行を出力します。
ファイルを閉じます。

これらの手順を念頭に置いて、ここで使用されるすべてのファイル関数を確認していきます。

fopen

fopen 関数はファイルへの接続を作成します。 「接続を作成する」と言ったのは、fopen はファイルを開くだけでなく、URL も開くことができるからです: $fh = fopen("http://127.0.0.1/", "r");

この行のコードにより、上記のページへの接続が作成され、ローカル ファイルであるかのように読み取りを開始できるようになります。

注: fopen で使用される「r」は、ファイルを読み取り専用で開くように指示します。ファイルへのデータの書き込みはこの記事の範囲外であるため、その他のオプションはすべてリストしません。ただし、クロスプラットフォーム互換性のためにバイナリ ファイルから読み取る場合は、「r」を「rb」に変更する必要があります。この例については後で説明します。

feof

feof コマンドは、ファイルの終わりに到達したかどうかを検出し、True または False を返します。リスト 1 のループは、ファイル「myfile」の終わりに到達するまで続きます。注: URL の読み取り中に、読み取るデータがなくなってソケットがタイムアウトした場合にも、feof は False を返します。

fclose

リスト 1 の最後までスキップすると、fclose は fopen の逆を行い、ファイルまたは URL への接続を閉じます。この関数を実行すると、ファイルまたはソケットから情報を読み取ることができなくなります。

fgets

リスト 1 の数行前に戻ると、ファイル処理の核心、つまり実際にファイルを読み取ることができます。 fgets 関数は、最初の例で使用する武器です。ファイルからデータ行を抽出し、文字列として返します。その後、データを印刷したり、その他の方法で操作したりできます。リスト 1 の例では、ファイル全体が正常に出力されます。

処理されるデータチャンクのサイズを制限する場合は、fgets にパラメータを追加して行の最大長を制限できます。たとえば、行の長さを 80 文字に制限するには、次のコードを使用します。 $string = fgets($file_handle, 81);

「」を思い出してください。注: この関数の例では、fopen とは若干異なるパラメーターがすでに使用されています。バイナリ データを扱うときは、常に fopen に b オプションを含めることを忘れないでください。この点をスキップすると、Microsoft® Windows® システムでは改行の処理方法が異なるため、ファイルが正しく処理されない可能性があります。 Linux® システム (または他の UNIX® バリアント) を扱っている場合、これは重要ではないように思えるかもしれません。ただし、Windows 用に開発していない場合でも、そうすることでクロスプラットフォームの保守性が向上するため、従うべき良い習慣です。

上記のコードは 4,096 バイト (4 KB) のデータを読み取ります。注: 指定したバイト数に関係なく、fread は 8,192 バイト (8 KB) を超えることはありません。

ファイル サイズが 8 KB 以下であると仮定すると、次のコードはファイル全体を文字列に読み取ることができるはずです。 $fh = fopen("myfile", "rb");
$data = fread($fh, filesize("myfile"));
fclose($fh);

ファイルの長さがこの値より大きい場合、ループを使用して残りを読み取ることしかできません。

fscanf

文字列処理に戻ると、fscanf も従来の C ファイル ライブラリ関数に従います。慣れていない方のために説明すると、fscanf はフィールド データをファイルから変数に読み取ります。 list ($field1, $field2, $field3) = fscanf($fh, "%s %s %s");

この関数で使用される書式文字列は多くの場所 (PHP.net など) に記載されているため、 、ここではこれ以上の詳細は説明しません。文字列の書式設定は非常に柔軟であると言えば十分でしょう。すべてのフィールドが関数の戻り値に配置されることに注意してください。 (C では、これらはすべて引数として渡されます。)

fgetss

fgetss 関数は従来のファイル関数とは異なり、PHP の能力をより深く理解するのに役立ちます。この関数は fgets 関数と同様に機能しますが、見つかった HTML タグまたは PHP タグがすべて削除され、プレーン テキストのみが残ります。以下に示す HTML ファイルを表示します。

リスト 2. サンプル HTML ファイル「Cause there ain't no one for to give you no pain」





を選択し、fgetss 関数でフィルタリングします。

リスト 3. fgetss の使用
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
echo = fgetss($file_handle);
}
fclose($file_handle) ;



以下は出力です: 私のタイトル

「Cause there ain't no one for to give you no pain」
の意味が理解できたら、あなたは America というバンドを聞きすぎています



fpassthru 関数

ファイルの読み取り方法に関係なく、fpassthru を使用して残りのデータを標準出力チャネルにダンプできます。 fpassthru($fh);


また、この関数はデータを出力するため、データを取得するために変数を使用する必要はありません。

非線形ファイル処理: スキップアクセス

もちろん、上記の機能ではファイルのシーケンシャル読み取りのみが可能です。より複雑なファイルの場合は、ファイルの別の部分に行ったり来たりする必要がある場合があります。ここで fseek が役に立ちます。 fseek($fh, 0);


上記の例は、ファイルの先頭に戻ります。正確に返す必要がない場合は、キロバイトを返すように指定できます: fseek($fh, 1024);


PHP V4.0 以降、追加のオプションがいくつかあります。たとえば、現在位置から 100 バイト前にジャンプする必要がある場合は、次のコードを使用してみてください: fseek($fh, 100, SEEK_CUR);


同様に、次のコードを使用して 100 バイト前にジャンプできます: fseek( $fh, -100, SEEK_CUR);


ファイルの終わりの 100 バイト前に戻る必要がある場合は、SEEK_END を使用する必要があります。 fseek($fh, -100, SEEK_END);


新しい場所に到達したら、fgets、fscanf、またはその他のメソッドを使用してデータを読み取ることができます。

注: fseek は、URL を参照するファイル処理には使用できません。


ファイル全体を抽出します

ここで、PHP のよりユニークなファイル処理機能のいくつかについて触れていきます。それは、大きなデータの塊を 1 行または 2 行で処理することです。たとえば、ファイルを抽出してその内容全体を Web ページに表示するにはどうすればよいでしょうか?さて、ループを使用した fget の例を見ました。しかし、どうすればこのプロセスを簡単にできるでしょうか?このプロセスは、ファイル全体を文字列に入れる fgetcontents を使用すると非常に簡単です。 $my_file = file_get_contents("myfilename");
echo $my_file;


これはベストプラクティスではありませんが、このコマンドは次のようにより簡潔に書くことができます: echo file_get_contents("myfilename");

この記事では主にローカル ファイルを処理する方法について説明しますが、これらの関数を使用して他の Web ページを抽出、エコー、解析することもできることに注意してください。 echo file_get_contents("http://127.0.0.1/");

このコマンドは次と同等です: $fh = fopen("http://127.0.0.1/", "r");
fpassthru($fh) ;


このコマンドを見て、「それでも大変すぎる」と思うはずです。 PHP 開発者もあなたに同意します。したがって、上記のコマンドは次のように短縮できます: readfile("http://127.0.0.1/");

readfile 関数は、ファイルまたは Web ページの内容全体をデフォルトの出力バッファーにダンプします。デフォルトでは、このコマンドは失敗するとエラー メッセージを出力します。この動作を回避するには (必要に応じて)、 @readfile("http://127.0.0.1/"); を試してください。

もちろん、本当にファイルを解析する必要がある場合は、file_get_contents によって返される単一の文字列は少し長くなる可能性があります。圧倒的な。最初の直感は、split() 関数を使用して分割することかもしれません。 $array = split("n", file_get_contents("myfile"));

しかし、それをやってくれる便利な関数がすでにあるのに、なぜこんな苦労をするのでしょうか? PHP の file() 関数はこれを 1 ステップで実行し、行に分割された文字列の配列を返します。 $array = file("myfile");

上記 2 つの例には若干の違いがあることに注意してください。 Split コマンドでは新しい行が削除されますが、file コマンド (fgets コマンドと同様) を使用すると、配列内の文字列に新しい行が追加されたままになります。

しかし、PHP のパワーはそれをはるかに超えています。 parse_ini_file を使用すると、1 つのコマンドで PHP スタイルの .ini ファイル全体を解析できます。 parse_ini_file コマンドは、リスト 4 に示すようなファイルを受け入れます。

リスト 4. サンプル .ini ファイル
; コメント
[個人情報]
名前 = "アーサー王"
クエスト = 聖杯を探すために
好きな色 = ブルー

[その他のもの]
サミュエル クレメンス = マークトウェイン
Caryn Johnson = Whoopi Goldberg

次のコマンドは、このファイルを配列にダンプし、配列を出力します: $file_array = parse_ini_file("holy_grail.ini");
print_r $file_array;

次の出力は結果です:
リスト 5. 出力
Array
(
[名前] = & gt; アーサー王
[クエスト] = & gt; 聖杯を求める
[好きな色] = & gt; 青
[サミュエル クレメンス] = & gt ; Mark Twainar [Caryn Johnson] => Whoopi Goldberg
)

もちろん、このコマンドによりパーツが結合されることに気づくかもしれません。これはデフォルトの動作ですが、ブール変数である 2 番目の引数を parse_ini_file: process_sections に渡すことで簡単に修正できます。 process_sections を True に設定します。 $file_array = parse_ini_file("holy_grail.ini", true);
print_r $file_array;

すると、次の出力が得られます:

リスト 6. 出力(
[名前] => アーサー王
[サミュエル・クレメンス] =>

これは、PHP ファイル処理の氷山の一角にすぎません。 tiny_parse_file や xml_parse などのより複雑な関数は、それぞれ HTML ドキュメントと XML ドキュメントの処理に役立ちます。これらの特別な関数の使用方法の詳細については、「リソース」を参照してください。これらの種類のファイルを扱う場合、これらのリファレンスは一見の価値がありますが、この記事で説明した、遭遇する可能性のあるすべてのファイルの種類について深く考える必要はなく、これまでに説明した一般的なルールの関数を操作するのに適したリファレンスをいくつか紹介します。

ベスト プラクティス

プログラム内のすべてが計画どおりに実行されるとは決して想定しないでください。たとえば、探しているファイルが移動されてしまったらどうなるでしょうか?権限が変更され、その内容を読み取ることができなくなった場合はどうすればよいでしょうか? file_exists と is_readable を使用して、これらの問題を事前に確認できます。

リスト 7. file_exists と is_readable を使用する
$ Filename = "MyFile";
IF (File_exists ($ FILENAME) && Is_Readable ($ FILENAME)) {
$ fH = FOPEN ($ ") ; R # Processing
FClose ($fh) ;
}

ただし、実際には、そのようなコードを使用するのは面倒すぎる可能性があります。 fopen の戻り値の処理がより簡単かつ正確になります。 if ($fh = fopen($filename, "r")) {
# Processing
fclose($fh);
}

fopen は失敗時に False を返すため、これによりファイルは次の場合にのみ実行されることが保証されます。ファイルは正常に開かれました。もちろん、ファイルが存在しないか読み取り不可能な場合は、負の戻り値が予想されます。これにより、発生する可能性のあるすべての問題を検査で確認できるようになります。さらに、開くのに失敗した場合は、プログラムを終了するか、プログラムにエラー メッセージを表示させることができます。

fopen 関数と同様に、file_get_contents、file、readfile 関数はすべて、開くのに失敗した場合、またはファイルの処理に失敗した場合に False を返します。 fgets、fgetss、fread、fscanf、および fclose 関数も、エラー時に False を返します。もちろん、fclose を除くこれらすべての関数の戻り値を処理したことがあるかもしれません。 fclose を使用する場合、ファイル処理が正常に閉じられなくても何も行われないため、通常は fclose の戻り値を確認する必要はありません。

選択はあなた次第です

PHP には、ファイルを読み取って解析する効率的な方法がたくさんあります。ほとんどの場合、fread のような典型的な関数が最良の選択かもしれません。あるいは、readfile がそのタスクに最適な場合には、readfile のシンプルさに惹かれるかもしれません。それは実際に何が行われているかによります。

大量のデータを扱う場合は、fscanf がその価値を発揮し、split コマンドや sprintf コマンドで file を使用するよりも効率的です。逆に、わずかな変更だけで大量のテキストをエコーし​​たい場合は、file、file_get_contents、または readfile を使用する方が適切な場合があります。これは、キャッシュまたは一時的なプロキシ サーバーの作成に PHP を使用する場合に当てはまります。

PHP は、ファイルを処理するためのツールを多数提供します。これらのツールの詳細を確認し、取り組んでいるプロジェクトにどれが最適であるかを確認してください。すでに多くのオプションがあるので、それらを活用して PHP でのファイルの操作を楽しんでください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。