こんにちは!エンジニアのノムラです。
Webアプリでファイルのアップロードを必要とすることは少なくありません。
CakePHPで開発していている際もしばしばそういった場面に遭遇します。
ただ、もともとファイルのアップロードのAPI自体はPHPに備わっているのです。
そこで、ここでは
- PHPでのファイルのアップロード
- ファイル名の指定
- ファイルが正しくアップロードされたかのチェック
といったファイルアップロードに関する基本的なことから、
- CakePHPでのファイルアップロード
- ファイルをアップロードする際の注意点
といった流れで、実用的な使い方について説明していきます。
PHPでのファイルのアップロード
はじめに、PHPでファイルをアップロードの仕組みを理解しましょう。
流れとしては、アップロードフォームからファイルをアップロードし、move_uploaded_file関数で、指定したディレクトリにファイルをコピーしています。
ファイルをアップロードする
それでは実際に、サンプルコードを見ながらファイルのアップロードを行っていきましょう
まずは、HTMLでファイルアップロードのフォームを作成します。
ここで重要なのが、フォームの設定です。
フォームには必ず、enctype=”multipart/form-data”を設定してください。
また、methodがPOSTでなくてはならないという点にも注意する必要があります。
inputの部分では、type=”file”にすることを忘れないでください。
nameには任意の名前を設定しましょう。
次にPHP側の処理をみていきます。
ファイルの保存先のパスを指定し、アップロードを行います。
file_uploadには、フォームのinputで指定したnameを指定しましょう。
$_FILESは連想配列で以下のような形式になっています。
$_FILES[アップロードフォームのinputのname][アップロードされたファイルの情報]
アップロードされたファイルの情報として、以下の5つの項目があります。
項目 | 内容 |
---|---|
name | 元のファイル名 |
tmp_name | サーバーに一時保存されたファイル名 |
error | エラー内容 |
type | ファイルタイプ |
size | ファイルサイズ |
例えば、今回の場合でエラー内容を確認する場合は、$_FILES[‘file_upload’][‘error’]と指定できます。
ファイル名を変更する
先ほどのサンプルコードでは、アップロードされた元のファイル名がそのままつけられていますが、すでにアップロードされたファイル名とかぶってしまう可能性があります。
そのため、ファイル名はプログラム側で指定しましょう。
PHPファイルを変更します。
サンプルでは、元のファイル名の先頭にアップロード時の日時を加えました。
2018年5月15日18時30分20秒にtest.txtをアップロードすると、指定したディレクトリに「20180515183020-test.txt」というファイルがアップロードされることになります。
CakePHPでのファイルのアップロード
ここまでフレームワークを使わず、ファイルのアップロードを解説してきましたが、より実践に近づけるためCakePHPでのアップロード方法も紹介したいと思います。
ここでは一枚の画像を指定したフォルダにアップロードする方法をみていきましょう。
まずは、bakeを使ってUploadCotrollerおよび、それに該当するテンプレートを作ってください。
cake bake controller upload
なお、bakeについては別記事で紹介していますので、内部リンクも紹介してください。
続いて、以下のようにテンプレートとコントローラーを書き換えます。
アップロード先のフォルダですが、今回は環境依存などを簡単に回避するために、webrootフォルダに直接画像を保存する仕様としました。webrootフォルダはcake appフォルダの直下にあります。
簡便性とのトレードオフでなかなか行儀の悪いものになっているため、実際に使う際はwebrootフォルダにupload_imgのようなフォルダを作り、そちらに画像を格納するといった工夫が必要になりますね。
Template/Upload/index.ctp
<h1>ファイル追加</h1> <!-- 入力フォーム --> <p><?= $message; ?></p> <?= $this->form->create('UploadData', array('enctype' => 'multipart/form-data','url' => '/upload','type' => 'post')); ?> <?= $this->form->input('UploadData.img_name', array('type'=>'file' )); ?> <?= $this->form->button('画像を保存'); ?> <?= $this->form->end(); ?>
Controller/UploadController.php
class UploadController extends AppController { public function index() { $this->set("message","読み込むファイルを選んでください。"); if (isset($this->request->data['UploadData'])) { //アップロードするファイルの場所 $uploaddir = WWW_ROOT; $uploadfile = $uploaddir.basename($this->request->data['UploadData']['img_name']['name']); //echo $uploaddir."<br/>".$uploadfile."<br/>"; //画像をテンポラリーの場所から、上記で設定したアップロードファイルの置き場所へ移動 if (move_uploaded_file($this->request->data['UploadData']['img_name']['tmp_name'], $uploadfile)){ //成功したら、Successを表示 $this->set("message","読み込み成功です"); }else{ //失敗したら、errorを表示 $this->set("message","読み込み失敗です"); } } } }
フォームに関しては、FormHelperを使っています。
なお、FormHelperについては、以下で詳しく説明しているので、参考にしてみてください。
これを実行すると、以下のような画面が出ます。
「ファイルを選択」ボタンを押すと、ファイル選択ダイアログが出たらファイルを選択してください。
最後に「画像を保存」ボタンを押してみてください。画像がアップロードされます。
成功すると、「読み込み成功です」というメッセージが画面にあらわれます。UploadController.phpで指定したフォルダの中を確認してみてください。
選択したファイルがアップロードできるのが確認できます。
例えば、スクリーンショット.pngという画像ファイルをアップロードした場合、下の図のようにスクリーンショット.pngが保存されます。
ファイルをアップロードする際の注意点
以上が、CakePHPを用いてファイルのアップロードの仕組みです。
ほとんどの機能がPHPおよびHTMLに記述されているので、実装は非常に楽です。
ただし、気軽に出来るからといって実際のシステムに組み込むときには、そうは行きません。
このままだと、どんなファイルでもアップロードできてしまうため、ウィルスなどのファイルも簡単にアップロードできてしまいます。
そのため、アップロードする前に、ファイルの種類を限定するなど、なんらかのフィルタリングをする必要があります。
また、大きさなどの制限も無いので、ファイルの大きさに宣言を加えるなどといった処理も必要です。
つまり、ファイルのアップロードは簡単にできますが、気をつけなくてはならない点が非常に多いのです。
まとめ
この記事では、CakePHPでファイルアップデートを行う方法について以下の手順で説明しました。
・ファイルをアップロードする方法
・複数のファイルをアップロードする方法
・ファイルをアップロードする際の注意点
サンプルコードを見れば判りますが、ファイルのアップロード自体は難しいことではありません。
ただ、実際にファイルアップデートをするということは、そのファイルをサーバー内に取り込むということですから、そこで問題が起こらないように十分な注意が必要です。
システムを作る際には、システムそのものの仕組みもはもちろんのこと、そういった点にも気をつけましょう。