PHP ファイル名はわかっているが拡張子がjpgかpngかわからない画像の対処

はい、またわけのわからないタイトルを付けてしまいましたが、どういうシチュエーションかと言いますと、例えば元々何かしらの画像をjpgで保存していた時、ある日を境に、やっぱ透過pngを使おうと思ったりしたりすることってありますよね。
そんな場合に、拡張子は変わるけれどもファイル名は同じと言うこともあったりして、それを繰り返しているとjpgとpngが混在したディレクトリができます。

拡張子まで把握していれば、直接 ディレクトリ/ファイル名.xxx と指定すればよいだけなので問題はありません。ただ、画像を作っている人が違ったりしていると、どれをどの拡張子にした?とわざわざ聞かねばならず管理が大変になります。
まぁファイル全部をpngにしてしまったりjpgにすれば特別問題はないのですが、そうならない場合もあったりすることもあるんじゃないでしょうか?
あるかな?…まぁあることにしましょう(笑)

こういう説明をする時に便利なのがAKBです。こんなことが考えられます。

AKBのメンバー画像一覧は現在透過pngになっていますが、SKEやその他のグループはjpgだったとします(多分そうだったように思います)。
移籍や兼任があったりして、元々AKBのメンバーの画像はjpgだったけれども、pngになった、あるいは兼任のメンバーはそのグループではjpgだけれどもAKBの画像もあり、そこではpngで存在する。こういうのが前提になってます。

メンバーの画像を調べる時、データには例えば、

このようなデータベースがあって、画像ファイルは、

こんなふうになっていた場合、各個人に与えられている画像ファイルのID(あるいはファイル名)はグループが違うだけで共通になっています。違うのは拡張子。この時にどうすれば画像ファイルを抽出できるかなんです。

まず、僕が考えた方法が、画像のファイル名(拡張子を除く)はグループが違うだけで共通。ということは、その人の画像は、まずグループを選別することで絞れると言うのがまずひとつ。そこで、別のデータに、

このようにして、グループとチームのデータをもたせます。画像を調べる時は、このデータからグループを取り出せば良いので、仮にデータが、

このようになっていれば、$member[“島崎遥香”][group]で出せます。まぁここに画像のファイル名も入れておけばよいのですが、AKBの場合は他にも色々と設定がある(過去のチームやユニットその他諸々)ので、だいたいこんな感じとしておきます。ここから画像のディレクトリを見つける時は、

となります。

ディレクトリの画像一覧を配列にしておく

次に、「特定のディレクトリの中にある画像で拡張子がjpgとpngとあり、ファイル名しかわからない」という前提なので、そのディレクトリにある画像をまず一覧で取得して配列にしておきます。

まぁopendirなどでやっても良いのですが、ディレクトリの中にまたフォルダがあったりするとそれを条件分岐で弾かないと面倒なので、globを利用します。
上記の$checkDirの部分は例えば、../images/akb/、 ../images/ske/と言うような感じになっています。
$fileの部分で’*.{jpg,png}’になっています。ここでjpgとpngを抽出しているわけです。
この時、’*.{jpg, png}’とjpgのカンマの後にスペースを開けるとうまく抽出できないので注意が必要です。

作成する配列は、
[akb] => [../images/akb/akb001.png, ../images/akb/akb002.png, …, ../images/akb/ske001.png],
[ske] => [../images/ske/ske001.jpg, ../images/ske/ske001.jpg, …, ../images/ske/skexxx.jpg],

こんな感じになります。

予めこのようにして配列を作っておくことで各画像ファイルの拡張子がわからずともファイル名だけで抽出することが可能になります。

本題: 作成した配列からファイル名で検索して画像ファイルを抽出する

ようやく本題になります。
元々、ファイル名しかわからず、拡張子が混在している場合に、その拡張子をどのようにして判別するかなのですが、当初file_exists()などで調べてみたもののうまく動作しなかったので、それじゃget_headersだと意気込んでみましたがこれもなんかうまく行かずにいました。
つまりは、「画像のパス/ファイル名.jpg」でそのファイルがあるかどうかチェックして、無ければ.pngに変えるというような事をしようとしたわけです。しかしどれもパッとせずだったので、結局、「拡張子がわからないのであれば、そのディレクトリの画像一覧の配列を作っておいて、ファイル名で検索したらいいじゃん」という結論になり、ここに至っています。

で、使用するのがpathinfoとなるのです。この関数は、そのパスの情報を返してくれます。

オプション 説明
PATHINFO_DIRNAME ディレクトリパス
PATHINFO_BASENAME ファイル名(拡張子付き)
PATHINFO_EXTENSION 拡張子
PATHINFO_FILENAME ファイル名(拡張子無し)(PHP 5.2.0 以降)

この関数は、オプションを指定しない場合は連想配列でその情報を返してくれます。「ディレクトリの画像一覧を配列にしておく」で、$imgsと言う配列を作りました。そして各メンバーのデータから、画像のディレクトリも調べられます。
こういう状況から以下のようなプログラムを作ったというわけです。

foreachで、$imgsのグループの中身であるパス(../images/akb/akb001.png, …)を$mImgにしておきます。
pathinfoで$mImg(画像一覧のパス)を調べてファイルのパス情報を連想配列にしておきます。
もし、pathinfoのfilenameが、調べたいメンバーのファイル名と一致した場合、$mImg(調べてる画像パス)を変数$urlImgに入れます。

このようにすることで、ファイル名だけわかっていて、拡張子がわからない場合でもパスで調べてるので間違いなく抽出することが可能なわけです。

長々と書きましたがもしかすると、もっとエレガントでスムースな抽出方法があるかも知れません。ただ、毎回画像ファイルを抽出するプログラムよりは、予め配列にパスを入れておくことで、比較的軽めに抽出ができるんじゃなかろうかと思った次第です。

実際の所、こういうシチュエーションがあるかどうかが問題なんですけどね(笑)

スポンサーリンク

シェアする

フォローする