情弱エンジニアのなかのblog

一人前のエンジニアになる為のブログです

CakePHP画像のアップロード

ファイル形式の指定とフォルダを移動して保存するまで

CakePHPでのアプリ制作で画像のアップロードを実装したので手順等を記載致します。

1.addでファイルをアップロード

まず最初にやることは当然addでファイルのアップロードを出来るようにすることです。 こちらはaddに少し記述するだけで済みます。

<?php
echo $this->Form->input('image', array(
    'label' => false,
    'type' => 'file','multiple'));
?>

これでaddを確認するとファイルのアップロードが出来るようになっていると思います。

f:id:nonaka-katuma-hal:20170531202624j:plain

2.アップロードファイルの情報確認方法

では早速アップロードしたファイルを扱っていく、、、前にですね アップロードしたファイルの情報を見る方法をご紹介します。

今後ファイルパスやファイル名を確認するのに必須になってくるものなので使い方を覚えましょう! と言っても確認方法は簡単です。

addからファイルをアップロードした後にControllerで

//中身をみたい変数などあれば確認できます。
debug();
//処理をここで止めます
return;

こう記述することで記述した場所で処理を止めることが出来ます。 これを書いて実行しまして右上のケーキのマークを押します。

するとビロビロと出てくるので「Request」をおすとアップロードしたファイルの情報を見ることができます。

f:id:nonaka-katuma-hal:20170531203943j:plain

「image」の中身を見てもらうと

「name」がアップロードしたファイルのファイル名になります。

「type」がファイルの拡張子になります。

「tmp_name」がアップロードしたファイルの一時的なパスになります。 この一時的なパスはファイルを識別するために与えられるものでして、 コードでファイル自体を扱いたいときはこのパスを指定することになるので覚えておいてください。

3.受け取ったファイルを保存する、パスを指定する

続いてControllerでDBにファイルの保存して、特定のフォルダに画像ファイルを保存していきます。

1.ファイルの保存先を指定

2.ファイルのパスを保存

3.ファイルの名前を取得

4.ファイルの保存

//保存先のパスを保存、WWW_ROOT はwebrootを示します。
$path = WWW_ROOT . "upimg/";

//アップロードしたファイルの一時的なパスを取得します
$img = $this->request->data('Article.image.tmp_name');

//アップロードしたファイル名を取得します
$name = $this->request->data('Article.image.name');

//現在ある記事のidの最大値を取得します
$box = $this->Article->find('first', array("fields" => "MAX(Article.id) as max_id"));
$id = $box[0]['max_id'];

//今回追加する記事番号にします
$id++;

$uploadfile = $path .  "$id.jpg";

//画像のフォルダとファイル名を指定して保存します
if(!move_uploaded_file($img,$uploadfile)) {
    $this->Flash->error(__('画像ファイル保存できませんでした'));
    return $this->redirect(array('action' => 'index'));
}

//DB保存用にファイル名を保存します
$this->request->data['Article']['image'] = $name;

こちらまでがファイル自体の保存になります この場合画像は「webroot/upimg」というフォルダに保存されます。

続いてDBへの保存がこちらになります。

if ($this->Article->save($this->request->data)) {
    $this->Flash->success(__('記事の追加が出来ました!'));

    return $this->redirect(array('action' => 'index'));

} else {
        $this->Flash->error(__('記事の追加でエラー'));
}

これで保存は完了です。

4.拡張子をチェックして画像以外をはじく

続いてはアップロードされたファイルが本当に画像ファイルかチェックしていきます。 悪意のあるファイルでもアップされたら大変ですからね!

書き方は「jpeg」「jpg」「gif」「png」以外のファイルがアップロードされたら別のビューに移動して はじくというものになります。

//アップロードしたファイルの拡張子を取得します
$extension = $this->request->data('Article.image.type');

//アップロードを許可するファイルの拡張子を代入します
$check_array = array(1 => 'image/jpeg', 2 => 'image/jpg', 3 => 'image/gif', 4 => 'image/png');

//アップロードされたファイルが画像ファイルかどうかチェックします
if(!array_search($extension , $check_array)) {
    $this->Flash->error(__('画像ファイルを入れて下さい'));
    return $this->redirect(array('action' => 'index'));
}

これで画像ファイルだけがアップロードされます。 なぜ配列が 1 => からなのか気になる方はこちらのサイトを見てみてください。

【array_search関数】は戻り値に注意!! | HANGOUT - ハングアウトエンジニアブログ

5.GitHubにアップするときの注意

さて機能としてはこれで完成なのですがGitHubなどバージョン管理ツールにアプリをアップするときは画像を保存しているファイルをアップしないように注意しましょう。 と言っても方法は簡単でgitignoreに「app/webroot/upimg」と記載すればオーケーです。

さてこれで一通りの画像アップロードが出来ます。 もっと効率的な方法など見つけたらまたアップします。それでは