PHP ファイル処理のスニペット集

このページは、PHP の ファイル処理のスニペットなどをまとめる予定のページです。

目次

注意

  • コードのライセンスは CC0 (クレジット表示不要、改変可、商用可) です。

スニペット

ディレクトリの生成

サブディレクトリも含めて生成
$path = '/path/to/dir';
if (!is_dir($path)) {
    mkdir($path, 0777, true);
}

ファイルの削除

$path = '/path/to/dir/test.txt';
unlink($path);

パス情報の取得

$path = '/path/to/test.txt';
$dir = pathinfo($path, PATHINFO_DIRNAME); // フォルダ名取得 (dirname($path)と同じ))
$basename = pathinfo($path, PATHINFO_BASENAME); // ファイル名取得 (basename($path)と同じ)
$name = pathinfo($path, PATHINFO_FILENAME); // ファイル名(拡張子なし)取得
$ext = pathinfo($path, PATHINFO_EXTENSION); // 拡張子取得
パスのファイル名の取得
$path = '/path/to/test.txt';
$filename = basename($path);
パスの親ディレクトリの取得
$path = '/path/to/test.txt';
$dirPath = dirname($path);

file_get_contents()

単純なファイル読み込み
$path = '/path/to/test.txt';
$data = @file_get_contents($path);
GET リクエスト
$responseString = @file_get_contents('http://example.com/?key=value');
GET リクエスト (追加設定込み)
$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);
$context = stream_context_create(array(
    'http' => array(
        'timeout' => 10, // タイムアウトの秒数
    ),
    'ssl' => array(
        'verify_peer'      => false, // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
        'verify_peer_name' => false, // ピア名検証をしない (同上)
    )
));
$responseString = @file_get_contents($url . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986), false, $context); // 応答データ取得
POST リクエスト
$url = 'https://example.com'; // リクエスト先のURL
$query = array( // パラメータ
    'key' => 'value',
);
$context = stream_context_create(array(
    'http' => array(
        'method'  => 'POST', // POST送信
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => http_build_query($query, '', '&', PHP_QUERY_RFC3986), // 送信データをセット
        'timeout' => 10, // タイムアウトの秒数
    ),
    'ssl' => array(
        'verify_peer'      => false, // リクエスト先が https の場合、証明書検証をしない (環境によって動作しない場合があるため)
        'verify_peer_name' => false, // ピア名検証をしない (同上)
    )
));
$responseString = @file_get_contents($url, false, $context); // 応答データ取得

file_put_contents()

単純なファイル書き込み
$path = '/path/to/test.txt';
$data = 'test';
file_put_contents($path, $data);
追記
$path = '/path/to/test.txt';
$data = 'test';
file_put_contents($path, $data, FILE_APPEND);

ファイル・ディレクトリパス一覧取得

再帰取得
$path = '/path/to/dir';
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iter as $entry) {
    // echo $entry->getPathname() . PHP_EOL;
}
再帰取得 (PNG, GIF, JPEG のみ)
$path = '/path/to/dir';
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
$iter = new RegexIterator($iter, '#\.(?:png|gif|jpe?g)\z#');
foreach ($iter as $entry) {
    // echo $entry->getPathname() . PHP_EOL;
}

ファイルのダウンロード

<?php
$file = 'モンキー.gif'; // ファイルパス (フォルダパスを含めても可)
$name = mb_substr(mb_strrchr('/' . str_replace('\\', '/', $file), '/'), 1); // (ダウンロードファイル名。basename()だとロケール等によって正常に取得できない場合がある)

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $file = mb_convert_encoding($file, 'SJIS-win', 'UTF-8'); // サーバがWindowsの場合SJISに変換

if (file_exists($file)) {
    header('Content-Type: image/gif'); // ファイルに合わせて適切に変更
    header('Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($name)); // エンコード
    header('Cache-Control: no-store');
    header('Content-Length: ' . filesize($file));

    while (ob_get_level() > 0) ob_end_clean(); // バッファクリア
    readfile($file);
    exit;
}
?>
  • php.netのサンプル に以下を追加・変更しています。
    • サーバーが Windows の場合ファイルパスを SJIS に変換
      (file_exists() が false になるのを防ぐ。プログラムと他のサーバーの文字エンコーディングは UTF-8 想定です)
    • ファイル名が日本語でも対応できるようにする
      (filename* 形式。IE9以降のブラウザでは基本的に対応されています)
    • 出力バッファ (output_buffering の設定や ob_start()) が有効な場合でもダウンロードができるようにするようにバッファクリアする
      (出力バッファ有効時に容量の大きなファイルを readfile するとダウンロード時に出力バッファが詰まってダウンロードファイルのサイズが0バイトになる)
    • レスポンスヘッダの変更
      • Content-Description: 必須ではないので削除
      • Content-Type: application/octet-stream → 適切なMIMEタイプを設定するよう変更
      • Cache-Control: キャッシュを残さないように no-store に変更 (must-revalidate + Expires: 0 より直感的)
      • Pragma: HTTP/1.0 用で今は不要なので削除

ユーティリティ関数

ZIP圧縮

/**
 * 指定ディレクトリまたはファイルをZIP圧縮します。
 *
 * @param string|array $source ZIP圧縮するディレクトリパスまたはファイルパス (複数の場合は配列)
 * @param string $dest ZIPファイルの保存先のパス
 * @return bool 成功した場合 true, 失敗した場合 false
 */
function zip($source, $dest) {
    if ((!is_array($source) && strlen($source) == 0) || (is_array($source) && empty($source)) || strlen($dest) == 0) return false;
    if (!is_array($source)) $source = array($source);
    $zip = new ZipArchive();
    if ($zip->open($dest, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) return false;
    $result = true;
    foreach ($source as $entry) {
        if (is_dir($entry)) {
            $subEntryArray = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($entry, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
            foreach($subEntryArray as $subEntry){
                $relativePath = substr($subEntry, strlen(dirname($entry)) + 1);
                $added = (is_dir($subEntry)) ? $zip->addEmptyDir($relativePath) : $zip->addFile($subEntry, $relativePath);
                if (!$added) {
                    $result = false; break;
                }
            }
            if (!$result) break;
        }
        else if ($zip->addFile($entry) === false) {
            $result = false; break;
        }
    }
    $result = $zip->close() && $result;
    if (!$result) @unlink($dest);
    return $result;
}

// zip('/path/to/dir', 'dir.zip');