サーチ…


構文

  • int readfile(文字列$ filename [、bool $ use_include_path = false [、リソース$コンテキスト]])

パラメーター

パラメータ説明
ファイル名読み込まれるファイル名。
use_include_path include_pathでファイルを検索する場合は、オプションの2番目のパラメータを使用してTRUEに設定することもできます。
コンテキストコンテキストストリームリソース。

備考

ファイル名の構文

このトピックの関数に渡されるほとんどのファイル名は次のとおりです。

  1. 自然界の弦。
    • ファイル名は直接渡すことができます。他の型の値が渡された場合、それらはstringにキャストされます。これは、 DirectoryIteratorの反復における値であるSplFileInfoに特に便利です。
  2. 相対的または絶対的。
    • 彼らは絶対的かもしれない。 Unixライクなシステムでは、絶対パスは//home/user/file.txt C:/Users/user/file.txtなどで始まりますが、Windowsでは絶対パスはドライブで始まります(例: C:/Users/user/file.txt
    • それらは相対的でもよく、 getcwdの値に依存し、 chdirによって変更される可能性があります。
  3. プロトコルを受け入れる。
    • 彼らはscheme://管理し、プロトコルラッパーを管理するように指定することができます。たとえば、 file_get_contents("http://example.com")http://example.comからコンテンツを取得します。
  4. スラッシュ対応。
    • WindowsのDIRECTORY_SEPARATORはバックスラッシュで、システムはデフォルトでパスのバックスラッシュを返しますが、開発者は/をディレクトリ区切り文字として引き続き使用できます。したがって、互換性のために、開発者は/をすべてのシステム上のディレクトリ区切り文字として使用できますが、関数によって返される値(たとえばrealpath )にはバックスラッシュが含まれる可能性があることに注意してください。

ファイルとディレクトリの削除

ファイルの削除

unlink関数は、単一のファイルを削除し、操作が成功したかどうかを返します。

$filename = '/path/to/file.txt';

if (file_exists($filename)) {
    $success = unlink($filename);
    
    if (!$success) {
         throw new Exception("Cannot delete $filename");
    }
}

再帰的削除によるディレクトリの削除

一方、ディレクトリはrmdirで削除する必要がありrmdir 。ただし、この関数は空のディレクトリのみを削除します。ファイルを含むディレクトリを削除するには、まずディレクトリ内のファイルを削除します。ディレクトリにサブディレクトリが含まれている場合は、 再帰が必要な場合があります。

次の例では、ディレクトリ内のファイルをスキャンし、メンバーファイル/ディレクトリを再帰的に削除し、削除されたファイル(ディレクトリではない)の数を返します。

function recurse_delete_dir(string $dir) : int {
    $count = 0;

    // ensure that $dir ends with a slash so that we can concatenate it with the filenames directly
    $dir = rtrim($dir, "/\\") . "/";

    // use dir() to list files
    $list = dir($dir);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($dir . $file)) {
            unlink($dir . $file);
            $count++;
        } elseif(is_dir($dir . $file)) {
            $count += recurse_delete_dir($dir . $file);
        }
    }

    // finally, safe to delete directory!
    rmdir($dir);

    return $count;
}

便利な機能

Raw direct IO

file_get_contentsfile_put_contentsは、1回の呼び出しでPHP文字列との間でファイルを読み書きする機能を提供します。

file_put_contentsFILE_APPENDビットマスクフラグと共に使用して、ファイルを切り捨ておよび上書きするのではなく、追加することもできます。これは、 LOCK_EXビットマスクと共に使用して、書き込みに進む間にファイルへの排他ロックを取得します。ビットマスクフラグは、 |ビット単位OR演算子。

$path = "file.txt";
// reads contents in file.txt to $contents
$contents = file_get_contents($path);
// let's change something... for example, convert the CRLF to LF!
$contents = str_replace("\r\n", "\n", $contents);
// now write it back to file.txt, replacing the original contents
file_put_contents($path, $contents);

FILE_APPENDはログファイルへの追加に便利ですが、 LOCK_EXは複数のプロセスからのファイル書き込みの競合状態の防止に役立ちます。たとえば、現在のセッションについてログファイルに書き込むには、次のようにします。

file_put_contents("logins.log", "{$_SESSION["username"]} logged in", FILE_APPEND | LOCK_EX);

CSV IO

fgetcsv($file, $length, $separator)

fgetcsvは、csvフィールドのオープンファイルチェックから行を解析します。成功FALSE配列のCSVフィールドを返し、失敗したFALSEを返します。

デフォルトでは、CSVファイルの1行だけが読み込まれます。

$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));    
print_r(fgetcsv($file,5," "));
fclose($file); 

contacts.csv

Kai Jim, Refsnes, Stavanger, Norway
Hege, Refsnes, Stavanger, Norway

出力:

Array
(
    [0] => Kai Jim
    [1] => Refsnes
    [2] => Stavanger
    [3] => Norway
)
Array
(
    [0] => Hege,
)

直接stdoutにファイルを読み込む

readfileはファイルを出力バッファにコピーします。 readfile()は大きなファイルを送信してもメモリの問題を表示しません。

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

またはファイルポインタから

代わりに、stdoutにコピーを開始するファイル内のポイントを探すには、代わりにfpassthru使用します。次の例では、最後の1024バイトがstdoutにコピーされます。

$fh = fopen("file.txt", "rb");
fseek($fh, -1024, SEEK_END); 
fpassthru($fh);

ファイルを配列に読み込む

fileは渡されたファイルの行を配列に返します。配列の各要素は、ファイル内の行に対応し、改行はまだ添付されています。

print_r(file("test.txt"));

test.txt

Welcome to File handling
This is to test file handling

出力:

Array 
( 
    [0] => Welcome to File handling 
    [1] => This is to test file handling 
)

ファイル情報の取得

パスがディレクトリかファイルかを確認する

is_dir関数は、引数がディレクトリかどうかを返しますis_fileは、引数がファイルかどうかを返します。それがどちらかであるかどうかを確認するには、 file_existsを使用します。

$dir  = "/this/is/a/directory";
$file = "/this/is/a/file.txt";

echo is_dir($dir) ? "$dir is a directory" : "$dir is not a directory", PHP_EOL,
    is_file($dir) ? "$dir is a file" : "$dir is not a file", PHP_EOL,
    file_exists($dir) ? "$dir exists" : "$dir doesn't exist", PHP_EOL,
    is_dir($file) ? "$file is a directory" : "$file is not a directory", PHP_EOL,
    is_file($file) ? "$file is a file" : "$file is not a file", PHP_EOL,
    file_exists($file) ? "$file exists" : "$file doesn't exist", PHP_EOL;

これは与える:

/this/is/a/directory is a directory
/this/is/a/directory is not a file
/this/is/a/directory exists
/this/is/a/file.txt is not a directory
/this/is/a/file.txt is a file
/this/is/a/file.txt exists

ファイルタイプの確認

filetypeを使用して、 filetypeをチェックします。次のようになります。

  • fifo
  • char
  • dir
  • block
  • link
  • file
  • socket
  • unknown

ファイル名をそのままfiletype渡す:

echo filetype("~"); // dir

filetypeはfalseを返し、ファイルが存在しない場合はE_WARNINGをトリガーします。

読みやすさと書き込み可能性の確認

is_writable関数とis_readable関数にファイル名をis_writableと、ファイルが書き込み可能か読み取り可能かをそれぞれチェックします。

ファイルが存在しない場合、関数は正常にfalse返しfalse

ファイルアクセスの確認/修正

filemtimeおよびfileatimeを使用すると、ファイルの最後の変更またはアクセスのタイムスタンプが返されます。戻り値はUNIXのタイムスタンプです。詳細は日付と時刻の処理を参照してください。

echo "File was last modified on " . date("Y-m-d", filemtime("file.txt"));
echo "File was last accessed on " . date("Y-m-d", fileatime("file.txt"));

fileinfoでパス部分を取得する

$fileToAnalyze = ('/var/www/image.png');

$filePathParts = pathinfo($fileToAnalyze);

echo '<pre>';
   print_r($filePathParts);
echo '</pre>';

この例は次のように出力されます:

Array
(
    [dirname] => /var/www
    [basename] => image.png
    [extension] => png
    [filename] => image
)

次のように使用できます。

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
パラメータ詳細
$パスパースされるファイルのフルパス
$オプション利用可能な4つのオプションのうちの1つ[PATHINFO_DIRNAME、PATHINFO_BASENAME、PATHINFO_EXTENSION、PATHINFO_FILENAME]
  • オプション(第2引数)が渡されない場合、連想配列が返されます。そうでない場合は、文字列が返されます。
  • ファイルが存在することを検証しません。
  • 文字列を部分的に解析します。ファイルの検証は行われません(MIMEタイプのチェックなどはありません)
  • 拡張子は単に$pathの最後の拡張子ですimage.jpg.pngファイルのパスは、技術的には.jpgファイルでも.pngなります。拡張子のないファイルは、配列の拡張要素を返しません。

大容量ファイルを処理する際のメモリ使用量を最小限に抑える

大規模なファイル、たとえば何百万もの行を含む10Mバイト以上のCSVファイルを解析する必要がある場合、 fileまたはfile_get_contents関数を使用して、 memory_limit設定で

XXXXXバイトのメモリサイズを使い果たしました

エラー。次のソースを考えてみましょう(top-1m.csvは100万行あり、約22Mバイトです)

var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));

これは、

int(262144)
int(210501632) 

インタプリタはすべての行を$arr配列に保持する必要があったため、RAMの消費量は約200Mバイトでした。配列の内容については何もしていないことに注意してください。

次のコードを考えてみましょう:

var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL, FILE_APPEND);
        $index++;
    }
    fclose($handle);
}
var_dump(memory_get_usage(true));

どの出力

int(262144)
int(262144)

余分な1バイトのメモリを使用するのではなく、CSV全体を解析し、2番目の列の値を逆にする別のファイルに保存します。これは、 fgetcsv 1行だけを読み込み、すべてのループで$rowが上書きされるためです。

ストリームベースのファイルIO

ストリームを開く

fopenはファイルストリームハンドルをオープンします。ファイルハンドルは、読み取り、書き込み、シーク、およびその他の機能のためにさまざまな機能とともに使用できます。この値はresourceタイプであり、その機能を保持する他のスレッドに渡すことはできません。

$f = fopen("errors.log", "a"); // Will try to open errors.log for writing

2番目のパラメータは、ファイルストリームのモードです。

モード説明
r 読み込み専用モードで開き、ファイルの先頭から開始する
r+ ファイルの先頭から読み書き用に開く
w ファイルの先頭から書き込み専用に開きます。ファイルが存在する場合、ファイルは空になります。存在しない場合は作成しようとします。
w+ ファイルの先頭から読み書き用にオープンします。ファイルが存在する場合、ファイルは空になります。存在しない場合は作成しようとします。
a ファイルの最後から書き込み専用にファイルを開きます。ファイルが存在しない場合、ファイルを作成しようとします
a+ ファイルの最後から読み書き用のファイルを開きます。ファイルが存在しない場合、ファイルを作成しようとします
x 書き込み専用のファイルを作成して開きます。ファイルが存在する場合、 fopen呼び出しは失敗します
x+ 読み書き用のファイルを作成して開きます。ファイルが存在する場合、 fopen呼び出しは失敗します
c 書き込み専用にファイルを開きます。ファイルが存在しない場合は、作成しようとします。ファイルの先頭に書き出しを開始しますが、書き込む前にファイルを空にしません
c+ 読み取りと書き込みのためにファイルを開きます。ファイルが存在しない場合は、作成しようとします。ファイルの先頭に書き出しを開始しますが、書き込む前にファイルを空にしません

Windowsでモードの後ろにt追加すると(例えばa+bwtなど)、ファイルの操作時に"\n"行末が"\r\n"に変換されます。これが意図されていない場合、特にバイナリファイルの場合は、モードの後ろにb追加してください。

PHPアプリケーションは、 Too many open filesエラーを防ぐために使用されなくなったときに、 fcloseを使用してストリームをクローズする必要があります。これは、(リソースリークを防止するための練習として、それでも必要があります )Webサーバに、それは必要ないかもしれないということを意味ストリームを閉じます-ランタイムのシャットダウン時にストリームのみ閉じているので、これは、CLIプログラムでは特に重要ですプロセスが長時間実行されることを期待していない場合、多くのストリームを開くことはありません。

読書

freadを使うと、指定されたバイト数がファイルポインタから読み込まれるか、またはEOFが満たされるまで読み込まれます。

行を読む

fgetsを使用すると、EOLに達するか、指定された長さが読み取られるまでファイルが読み込まれます。

freadfgets両方は、読み込み中にファイルポインタを移動します。

残りのすべてを読む

stream_get_contentsを使用すると、ストリーム内の残りのすべてのバイトが文字列に変換され、返されます。

ファイルポインタの位置を調整する

最初にストリームを開いた後、ファイルポインタはファイルの先頭にあります(または、モードaが使用されている場合は最後です)。 fseek関数を使用すると、ファイルポインタが次の3つの値のいずれかを基準にして新しい位置に移動します。

  • SEEK_SET :これがデフォルト値です。ファイル位置のオフセットはファイルの先頭からの相対的な値になります。
  • SEEK_CUR :ファイル位置のオフセットは、現在の位置からの相対的なオフセットになります。
  • SEEK_END :ファイルの位置のオフセットは、ファイルの終わりを基準にして相対的になります。この値には、負のオフセットを渡すことが最も一般的です。ファイルの終わりの前に指定されたバイト数にファイルの位置を移動します。

rewindfseek($fh, 0, SEEK_SET)便利なショートカットです。

ftellを使用すると、ファイルポインタの絶対位置が表示されます。

たとえば、次のスクリプトは最初の10バイトをスキップし、次の10バイトを読み込み、10バイトをスキップし、次の10バイトを読み込み、次にfile.txtの最後の10バイトを読み込みます。

$fh = fopen("file.txt", "rb");
fseek($fh, 10); // start at offset 10
echo fread($fh, 10); // reads 10 bytes
fseek($fh, 10, SEEK_CUR); // skip 10 bytes
echo fread($fh, 10); // read 10 bytes
fseek($fh, -10, SEEK_END); // skip to 10 bytes before EOF
echo fread($fh, 10); // read 10 bytes
fclose($fh);

書き込み

fwriteを使用すると、指定された文字列が現在のファイルポインタから始まるファイルに書き込まれます。

fwrite($fh, "Some text here\n");

ファイルとディレクトリの移動とコピー

ファイルのコピー

copyは、第1引数のソースファイルを第2引数のcopyコピーします。解決された宛先は、すでに作成されたディレクトリ内にある必要があります。

if (copy('test.txt', 'dest.txt')) {
    echo 'File has been copied successfully';
} else {
    echo 'Failed to copy file to destination given.'
}

再帰を伴うディレクトリのコピー

ディレクトリのコピーはディレクトリの削除とほぼ同じですが、 unlinkではなくファイルのcopyが使用されunlinkが、ディレクトリではrmdirではなくmkdirが使用されます。

function recurse_delete_dir(string $src, string $dest) : int {
    $count = 0;

    // ensure that $src and $dest end with a slash so that we can concatenate it with the filenames directly
    $src = rtrim($dest, "/\\") . "/";
    $dest = rtrim($dest, "/\\") . "/";

    // use dir() to list files
    $list = dir($src);

    // create $dest if it does not already exist
    @mkdir($dest);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($src . $file)) {
            copy($src . $file, $dest . $file);
            $count++;
        } elseif(is_dir($src . $file)) {
            $count += recurse_copy_dir($src . $file, $dest . $file);
        }
    }

    return $count;
}

名前の変更/移動

ファイルやディレクトリの名前を変更/移動する方がはるかに簡単です。 rename機能を使用して、単一の呼び出しでディレクトリ全体を移動またはrenameます。

  • rename("~/file.txt", "~/file.html");

  • rename("~/dir", "~/old_dir");

  • rename("~/dir/file.txt", "~/dir2/file.txt");



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow