[PHP] Web上の画像ファイル(連番)にアクセスして、リネーム・保存する
ECサイトに登録した商品画像にブラウザでアクセス→リネームしてローカルに保存、という作業をPHPで効率化したときのメモです。
前提
集めたい画像のURLは次のような感じです。
http://www.sampleshop.com/img/{商品番号}/img-{商品番号}-{連番}.jpg
http://www.sampleshop.com/img/itemA/img-itemA-01.jpg
http://www.sampleshop.com/img/itemA/img-itemA-02.jpg
http://www.sampleshop.com/img/itemA/img-itemA-03.jpg
.
.
.
http://www.sampleshop.com/img/itemA/img-itemA-40.jpg
画像の連番は最小01~最大40までで、商品ごとにバラバラです。
01~40まで順番にアクセスして、ローカルに「{商品番号}-{連番}.jpg」という名前で保存していきます。
完成したPHP
次の内容でindex.phpを作成しました。
<?php
$id = 'itemA'; //商品番号
$urlbase = 'http://www.sampleshop.com/img/'; //画像URL(共通部分)
$ext = '.jpg'; //拡張子
$total = 40; //件数
for($i=1; $i<=$total; $i++){
//連番1~9のゼロ埋め
$num = sprintf('%02d', $i);
//アクセスする画像URL
//例:http://www.sampleshop.com/img/itemA/img-itemA-01.jpg
$file_download = $urlbase.$id.'/'.$id.'-'.$num.$ext;
//保存時のファイル名
//例:itemA-01.jpg
$file_save = $id.'-'.$num.$ext;
//アクセス → download/フォルダへ保存
$img = file_get_contents($file_download);
if($img){
file_put_contents('./download/'.$file_save, $img);
}
}
なお、最後に指定しているダウンロードフォルダ「download/」はあらかじめ作っておいてください。
index.phpにアクセスすると、商品番号「itemA」の画像の保存が始まります。
1商品分保存できたら$id='itemA'
を書き換え → index.phpにアクセス…を繰り返して画像を集めました。
以下はソースコード内で使った関数の振り返りです。
sprintf()
$num = sprintf('%02d', $i);
for文のループカウンタ$i
は 1,2,3 … 39,40 と続いていくのに対し、画像ファイル名に使う連番は 01,02,03 … 39,40 としたいです。このゼロ埋めした連番を$num
にセットしています。
ちなみに 001,002,003 … 039,040 と3桁にしたい場合は次のようになります。
$num = sprintf('%03d', $i);
公式ドキュメント:PHP: sprintf – Manual
file_get_contents()
$img = file_get_contents($file_download);
第1引数に指定したファイルの内容を文字列で読み込みます。
公式ドキュメント:PHP: file_get_contents – Manual
file_put_contents()
if($img){
file_put_contents('./download/'.$file_save, $img);
}
第2引数に指定したデータを、第1引数に指定した場所に書き込みます。
なお今回は「連番は最小01~最大40まで」という条件で、商品によっては画像が40個未満だったり、途中で抜けていたりするケースもありました。
そのような場合にfile_put_contents()
を実行すると中身がない破損データが保存されてしまうため、事前にif文で判定を入れています。
ちなみに、file_get_contents()
の実行後は$http_response_header
という変数にレスポンスヘッダが自動で格納されます。
例えば$http_response_header[0]
には「HTTP/1.1 200 OK」のようにステータスコードが入っています。
今回はざっくりとif($img)
という判定で動いたのでヨシとしましたが、 $http_response_header
で判定させるのがより正しい処理と言えそうです。
公式ドキュメント:PHP: file_put_contents – Manual
公式ドキュメント:PHP: $http_response_header – Manual