「拡張子取得」で何をしたいのかイメージする
まず、ゴールをはっきりさせます。
"/var/www/html/report/sales.csv" → "csv"
"/var/www/html/image/photo.jpeg" → "jpeg"
"https://example.com/files/manual.pdf" → "pdf"
"archive.tar.gz" → "gz"(どう扱うかは設計次第)
"README" → ""(拡張子なし)
やりたいことはこうです。
ファイルパスや URL の文字列から、「拡張子だけ」を安全に取り出したい。
業務だと、アップロードされたファイルの種類チェック、
ダウンロード時の Content-Type 判定、
ログ集計で「どの拡張子が多いか」を見る、などでよく使います。
ここを自前で explode('.') して最後を取る、みたいに書き始めると、
「ドットが複数あるファイル名」「拡張子なし」「URL にクエリ付き」などで、すぐに壊れます。
PHP には、これをかなり安全にやってくれる関数が用意されています。
基本の主役:pathinfo で拡張子を取る
pathinfo のイメージ
PHP には pathinfo という関数があります。
array pathinfo(string $path, int $flags = PATHINFO_ALL)
PHPこれは、
パス文字列を「ディレクトリ名」「ファイル名」「拡張子」などに分解してくれる関数
です。
シンプルな例から見てみます。
$info = pathinfo('/var/www/html/report/sales.csv');
var_dump($info);
PHPだいたいこんな配列になります。
array(4) {
["dirname"] => "/var/www/html/report"
["basename"] => "sales.csv"
["extension"] => "csv"
["filename"] => "sales"
}
PHPこの中の extension が、まさに「拡張子」です。
拡張子だけを直接取り出す書き方
pathinfo は、第2引数にフラグを渡すと、
欲しい要素だけを直接返してくれます。
$ext = pathinfo('/var/www/html/report/sales.csv', PATHINFO_EXTENSION);
echo $ext; // csv
PHPこれが、一番シンプルで実務的な「拡張子取得」です。
URL から拡張子を取りたいときの考え方
URL 全体をそのまま pathinfo に渡すとどうなるか
実は、URL もそのまま pathinfo に渡せます。
$ext = pathinfo('https://example.com/files/manual.pdf', PATHINFO_EXTENSION);
echo $ext; // pdf
PHPただし、クエリやフラグメントが付いているときは注意が必要です。
$ext = pathinfo('https://example.com/download.php?file=report.csv', PATHINFO_EXTENSION);
echo $ext; // ""(空文字)
PHPpathinfo は ? より右側を「パスの一部」とは見なさないので、download.php の拡張子 php は取れますが、file=report.csv の csv は「URL の中のパラメータ」であって「パスの拡張子」ではありません。
つまり、
「URL のパス部分の拡張子」を取りたいのか
「URL の中のパラメータに含まれるファイル名の拡張子」を取りたいのか
で、やることが変わります。
パス部分の拡張子を取りたい場合
これはシンプルです。
/**
* URL から「パス部分の拡張子」を取得する
* 拡張子がなければ空文字
*/
function getExtensionFromUrlPath(string $url): string
{
$path = parse_url($url, PHP_URL_PATH) ?: '';
return pathinfo($path, PATHINFO_EXTENSION) ?? '';
}
PHP使い方の例です。
echo getExtensionFromUrlPath('https://example.com/files/manual.pdf'); // pdf
echo getExtensionFromUrlPath('https://example.com/files/'); // ""
echo getExtensionFromUrlPath('https://example.com/download.php?file=abc'); // php
PHPここでは「パスの最後の要素の拡張子」を見ているだけです。
実務ユーティリティとして関数にまとめる
ファイルパス用:拡張子を小文字で返す
拡張子は、大文字小文字が混ざっていることがあります。
"photo.JPG" → "JPG"
"report.Pdf" → "Pdf"
比較や判定に使うなら、小文字にそろえておくと扱いやすいです。
/**
* ファイルパスから拡張子を取得(小文字で返す)
* 拡張子がなければ空文字
*/
function getExtensionFromPath(string $path): string
{
$ext = pathinfo($path, PATHINFO_EXTENSION);
if ($ext === null || $ext === '') {
return '';
}
return strtolower($ext);
}
PHP使い方の例です。
echo getExtensionFromPath('/var/www/html/report/sales.csv'); // csv
echo getExtensionFromPath('/var/www/html/image/photo.JPG'); // jpg
echo getExtensionFromPath('/var/www/html/README'); // ""
PHPこれで、「JPG でも jpg でも同じ扱い」にできます。
URL 用:パス部分の拡張子を小文字で返す
さっきの URL 版も、小文字にそろえる形にしておくと便利です。
/**
* URL から「パス部分の拡張子」を取得(小文字で返す)
*/
function getExtensionFromUrl(string $url): string
{
$path = parse_url($url, PHP_URL_PATH) ?: '';
$ext = pathinfo($path, PATHINFO_EXTENSION);
if ($ext === null || $ext === '') {
return '';
}
return strtolower($ext);
}
PHPecho getExtensionFromUrl('https://example.com/files/manual.PDF'); // pdf
echo getExtensionFromUrl('https://example.com/files/'); // ""
PHP「複数ドット」のファイル名をどう扱うか
archive.tar.gz は「gz」か「tar.gz」か
pathinfo は、最後のドット以降を「拡張子」と見なします。
$info = pathinfo('archive.tar.gz');
var_dump($info['filename']); // archive.tar
var_dump($info['extension']); // gz
PHPつまり、「拡張子は gz」という扱いです。
実務では、ここをどう扱うかは設計次第です。
- 「とりあえず最後の拡張子だけ見れば十分」
→gzで OK - 「
.tar.gzというセットで扱いたい」
→ 自前で少し工夫する
.tar.gz まで含めて取りたい場合の一例
簡易的に「よくある複合拡張子」を特別扱いする、という手もあります。
/**
* よくある複合拡張子を考慮して拡張子を取得する
* 例: archive.tar.gz → tar.gz
*/
function getSmartExtension(string $path): string
{
$basename = basename($path);
// よくある複合拡張子のパターン
$multi = ['tar.gz', 'tar.bz2', 'tar.xz'];
foreach ($multi as $ext) {
if (str_ends_with($basename, '.' . $ext)) {
return $ext;
}
}
// 通常の拡張子
$ext = pathinfo($basename, PATHINFO_EXTENSION);
return $ext === null ? '' : strtolower($ext);
}
PHPecho getSmartExtension('archive.tar.gz'); // tar.gz
echo getSmartExtension('backup.tar.bz2'); // tar.bz2
echo getSmartExtension('photo.jpg'); // jpg
PHP「どこまでやるか」はプロジェクト次第ですが、
こういう「現実的な妥協」を入れることもあります。
実務での使いどころのイメージ
アップロードされたファイルの種類チェック
典型的なのは、アップロードされたファイルの拡張子チェックです。
$filename = $_FILES['file']['name'] ?? '';
$ext = getExtensionFromPath($filename);
$allowed = ['jpg', 'jpeg', 'png', 'pdf'];
if (!in_array($ext, $allowed, true)) {
// 許可されていない拡張子 → エラー
}
PHPここでのポイントは、
- 「小文字にそろえた拡張子」で判定していること
- 許可リストも小文字でそろえておくこと
です。
ログ集計で「どの拡張子が多いか」を見る
アクセスログに URL が残っているとき、
「どの種類のファイルがよくダウンロードされているか」を集計したいことがあります。
$url = '/files/manual_v3.pdf?download=1';
$ext = getExtensionFromUrl('https://dummy' . $url);
if ($ext !== '') {
// $ext ごとにカウントする
}
PHPhttps://dummy のような適当なスキーム+ホストを付けてから parse_url させるテクニックは、
「パス+クエリだけ」の文字列を扱うときに便利です。
まとめ:今日からの「拡張子取得」ユーティリティ
大事なところだけ、ぎゅっとまとめます。
拡張子取得は、pathinfo($path, PATHINFO_EXTENSION) を使うのが基本。
URL の場合は、parse_url($url, PHP_URL_PATH) でパス部分だけを取り出してから pathinfo に渡す。
比較や判定に使うなら、拡張子は小文字にそろえておくと扱いやすい。archive.tar.gz のような複合拡張子をどう扱うかは設計次第で、「最後の拡張子だけ見る」か「よくある複合拡張子を特別扱いする」かを決める。
核になるコードは、この2つです。
function getExtensionFromPath(string $path): string
{
$ext = pathinfo($path, PATHINFO_EXTENSION);
return $ext === null ? '' : strtolower($ext);
}
function getExtensionFromUrl(string $url): string
{
$path = parse_url($url, PHP_URL_PATH) ?: '';
$ext = pathinfo($path, PATHINFO_EXTENSION);
return $ext === null ? '' : strtolower($ext);
}
PHPもし、あなたのコードの中で「explode('.') して最後を取っているところ」があれば、そこがこのユーティリティの差し替えポイントです。
