PHPのglob関数の使い方 – ファイル・ディレクトリ一覧取得のパターンと違い

by

カテゴリー:

ウェブ開発やファイル操作において、特定のディレクトリ内のファイルやディレクトリを一括で取得する必要がある場面は多々あります。

PHPには、このような作業を効率的に行うためのツールとして、glob関数が提供されています。

glob関数を使えば、ワイルドカードを駆使して指定ディレクトリ内のファイルやディレクトリを一覧で取得でき、その後の処理に利用することができます。

本記事では、PHPのglob関数を駆使して、ファイルとディレクトリの一括取得を行う方法について詳しく説明します。これにより、効率的なファイル操作やデータ処理を実現するための基本的なスキルを身につけることができるでしょう。

結論:glob関数の最短の使い方

まず結論から。glob()は「パターン」を渡すだけで、マッチしたファイル・ディレクトリのパスを配列で返してくれます。特定ディレクトリの一覧取得なら、次の1〜2行で十分です。

<?php

// カレントディレクトリの .txt ファイルをすべて取得
$files = glob('*.txt');

foreach ($files as $file) {
    echo $file . PHP_EOL; // a.txt, b.txt, c.txt ...
}

// 特定ディレクトリを対象にする場合は絶対パスで指定する
$files = glob(__DIR__ . '/logs/*.log');

戻り値は常に配列(マッチが無ければ空配列、エラー時はfalse)です。opendir()readdir()のようにハンドルを開いてループする必要がなく、拡張子やパターンでの絞り込みをそのまま書けるのがglob()の特徴です。

glob関数の基本とサンプルコード

PHPのglob関数は指定したパターンにマッチしたパスを配列で取得するための関数です。

指定できるパターンはlibcのglob()関数のルールに基づいており、一般的なシェルで使われるルールに似ています。

以下はglob関数を使用するサンプルコードになります。

<?php

/**
現状のディレクトリ構造
.
├── a.txt
├── b.txt
├── c.txt
├── d.csv
├── dir
│   ├── e.txt
│   ├── f.txt
│   ├── g.txt
│   └── sub
│       ├── h.txt
│       ├── i.txt
│       └── j.txt
├── dir2
│   └── k.txt
└── sample.php

4 directories, 12 files
 */


glob(__DIR__ . '/*');
/**
Array
(
    [0] => /path/to/directory/glob/a.txt
    [1] => /path/to/directory/glob/b.txt
    [2] => /path/to/directory/glob/c.txt
    [3] => /path/to/directory/glob/d.csv
    [4] => /path/to/directory/glob/dir
    [5] => /path/to/directory/glob/sample.php
)
 */


glob('*.txt');
/**
Array
(
    [0] => a.txt
    [1] => b.txt
    [2] => c.txt
)
 */


glob('*/*');
/**
Array
(
    [0] => dir/e.txt
    [1] => dir/f.txt
    [2] => dir/g.txt
    [3] => dir/sub
    [4] => dir2/k.txt
)
 */


glob('*', GLOB_ONLYDIR);
/**
Array
(
    [0] => dir
    [1] => dir2
)
 */


glob('{a,b}.txt');
/**
Array
(
)
 */


glob('{a,b}.txt', GLOB_BRACE);
/**
Array
(
    [0] => a.txt
    [1] => b.txt
)
 */

第1引数にはパターンの指定を行い、第2引数にはフラグ指定が可能です。

指定できるフラグには以下があります。

  • GLOB_MARK – 各ディレクトリにスラッシュ (Windows ではバックスラッシュ) を追加します
  • GLOB_NOSORT – ディレクトリに存在するファイルを返します (ソートはされません)。このフラグを使わない場合は、パス名をアルファベット順にソートします。
  • GLOB_NOCHECK – 検索パターンにマッチするファイルが見つからない場合に、 検索パターン自身を返します
  • GLOB_NOESCAPE – バックスラッシュによるメタ文字のクォートを行いません
  • GLOB_BRACE – {a,b,c} を展開し「a」、「b」あるいは「c」のいずれかにマッチさせます
  • GLOB_ONLYDIR – パターンにマッチするディレクトリのみを返します
  • GLOB_ERR – (ディレクトリが読めないなどの) 読み込みエラー時に停止します。デフォルトではエラーは無視されます。
https://www.php.net/manual/ja/function.glob.php

よく使うglobパターン一覧

実際の開発で使用頻度の高いパターンを表にまとめました。目的に応じてパターンとフラグを組み合わせて使います。

やりたいこと書き方取得結果
すべてのファイル・ディレクトリglob('*')隠しファイルを除く全項目
特定の拡張子だけglob('*.txt').txt ファイルのみ
複数の拡張子glob('*.{jpg,png,gif}', GLOB_BRACE)画像ファイルをまとめて取得
ディレクトリだけglob('*', GLOB_ONLYDIR)ディレクトリのみ
サブディレクトリを1階層ぶんglob('*/*')1階層下のファイル・ディレクトリ
特定ディレクトリを対象glob(__DIR__ . '/logs/*.log')logs 内の .log ファイル
ディレクトリに印を付けるglob('*', GLOB_MARK)ディレクトリ末尾に / が付く
先頭1文字が任意glob('?.txt')a.txt, b.txt など1文字名

*(任意の文字列)、?(任意の1文字)、[...](文字クラス)、{...}GLOB_BRACE指定時の候補展開)といったワイルドカードを組み合わせられます。なお*は隠しファイル(.で始まるファイル)にはマッチしない点に注意してください。

globと他のファイル一覧取得方法の違い

PHPでファイル・ディレクトリの一覧を取得する方法はglob()だけではありません。それぞれ得意な場面が異なるため、違いを押さえておくと選びやすくなります。

方法戻り値パターン絞り込み再帰向いている用途
glob()パスの配列◎(ワイルドカード)×(自前実装が必要)拡張子・パターンで手軽に一覧取得
scandir()ファイル名の配列××1ディレクトリの全項目を単純に列挙
opendir() / readdir()ハンドルを1件ずつ××大量ファイルを逐次処理してメモリ節約
DirectoryIteratorSplFileInfoオブジェクト××ファイル情報(サイズ・更新日時等)も扱う
RecursiveDirectoryIteratorSplFileInfoオブジェクト×サブディレクトリまで再帰的に走査

ざっくり整理すると、拡張子やパターンでサッと絞り込みたいならglob()単にディレクトリ内をすべて列挙したいならscandir()サブディレクトリまで潜って再帰的に集めたいならRecursiveDirectoryIteratorが基準になります。scandir()...も結果に含まれるため、glob()のように不要なエントリを気にせず拡張子指定できる点はglob()の利点です。

globを使うときの注意点

  • マッチが無いときは空配列、権限エラーなどの失敗時はfalseを返します。foreach前にif ($files === false)で確認しておくと安全です。
  • デフォルトでは結果がアルファベット順にソートされます。ソートが不要ならGLOB_NOSORTで高速化できます。
  • *.で始まる隠しファイルにマッチしません。.envなどを取得したい場合はパターンを明示する必要があります。
  • 再帰的な走査はできないため、サブディレクトリまで潜る場合はRecursiveDirectoryIteratorの利用を検討してください。

終わりに

以上、PHPのglob関数の使い方について解説しました。

シェルの操作に慣れていればパターンの設定がわかりやすい、シンプルな関数かと思います。

こちらの情報が皆さんのプロジェクトに活用できましたら幸いです。

ホーム » 記事一覧 » 技術メモ » 開発 » PHP開発 » PHPのglob関数の使い方 – ファイル・ディレクトリ一覧取得のパターンと違い

投稿者

ここまで読んでいただき、ありがとうございます。

このサイトでは、私自身が関わっていることや、興味を持って試していることをそのまま置いています。

内容を見ていて、
「少し話を聞いてみたい」
「協業できる部分がありそう」
と感じる点があれば、下記のお問い合わせフォームからご連絡ください。状況を確認したうえで、必要な範囲でお返事します。

特に、以下のWordPressサイトに関する相談にも対応しているのでご興味ありましたらご相談ください。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です