この記事を読むのに必要な時間は約 16 分です。
CakePHP Upload プラグインで、これまでにご紹介したように、DB・Model・Controller・View を用意したのに、なぜかアップロードで怒られる!という時にチェックする方法をご紹介します。
[pn-box color=”lgray”]Upload プラグインの動作の解説等は以下をご覧下さい。
→ CakePHP Upload プラグインの動作解説 : 画像のアップロードからサムネイル作成まで手軽にできる CakePHP Uploadプラグイン
導入方法や DB 変更、Model の変更・作成については以下をご覧下さい。
→ CakePHP Upload プラグインの使い方 (1) 導入・DB, Model 変更
View や Controller の修正については、以下をご覧下さい。
→ CakePHP Upload プラグインの使い方 (2) View や Controller の修正
Behavior の設定方法と内容については、以下をご覧下さい。
→ CakePHP Upload プラグインの使い方 (3) Behavior の設定
前提
CakePHP のバージョンが合っているかは事前に確認しましょう。
2015/06 現在、最新の Upload プラグインは、CakePHP 2.x 用です。
CakePHP 3.x では動作しないと思います。
Validation をかけていると、エラーメッセージが分かりづらくなりますので、うまく動かない場合は、一旦外した方が切り分けやすくなるかと思います。
チェック1. プラグインを正しく読み込めているか
NG な場合の症状
プラグインを読み込めていないのに、Model の Behavior に登録している場合、該当の Model を読み込む際に、以下のようなエラーメッセージが表示されます。
Error: The application is trying to load a file from the Upload plugin Error: Make sure your plugin Upload is in the app/Plugin directory and was loaded
こうなれば OK
対象の Model を利用している Controller で、エラーなく何らかの action が動作すれば OK です。
ただし、Model の Behavior に登録できていない場合、その Model は読み込まれない場合には、エラーは表示されません。
考えられる原因
- プラグインが正しく配置できていない
- プラグインを load し忘れている
対応方法
Step 1. プラグインが正しく配置できているかを確認しましょう。
以下のようなディレクトリ構成になっているか確認しましょう。
(CakePHP Root) └ app └ Plugin └ Upload ├ Console ├ Model ├ Lib └ (etc)
Upload 直下に 1つ解凍用のディレクトリが出来ていたりしないか確認しましょう。
Step 2. プラグインの load を忘れていないか確認しましょう。
通常であれば、以下のように、app/Config/bootstrap.php で load します。
CakePlugin::load("Upload");
チェック2. Model の Behavior に Upload プラグインを登録できているか
NG な場合の症状
レコード登録時 (ファイルアップロード時) に、以下のようなエラーメッセージが表示されます。
Notice (8): Array to string conversion [CORE/Cake/Model/Datasource/DboSource.php, line 1009] Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Array' in 'field list'
こうなれば OK
ファイルアップロード無しでレコード登録した際、Controller で、$this->data->request を以下のように受け取れていれば OK です。
[カラム名] => Array ( [name] => [type] => [tmp_name] => [error] => 4 [size] => 0 )[pn-box color=”lgray”]
bake した場合など、登録成功で redirect が走ると、pr() していたものも redirect 先で表示されません。
場当たり的対処ですが、Controller の return $this->redirect(…); をコメントアウトして、return true; に変えて、その前で pr($this->request->data); で確認しています …
多分もっとちゃんとしたやり方はあるかと思います。
[pn-box-close]
考えられる原因
- Behavior の指定のしかた誤り
- カラムの指定誤り
対応方法
Step1. Model クラスの Behavior の記述の仕方を確認しましょう。
Behavior は、Model クラスの$actsAs に登録します。例は以下の通りです。
class HogeModel extends AppModel{ ... public $actsAs = array( "Upload.Upload" => array( /* オプションなしの場合 */ "カラム名1", /* オプションありの場合 */ "カラム名2" => array( "オプション1" => "値1", ), ), ); ... }
特に、$actsAs を $actAs と間違えたりしないように気をつけましょう…。私だけかも知れませんが。
Step 2. カラム名の指定を確認しましょう。
上記 Behavior 指定例の、”カラム名” の部分が、DB のカラム名とずれていないか確認しましょう。
キャメルケースや単数形などの変換は無しで、DB カラム名のままです。
チェック3. アップロード用 View の記述が正しいか
NG な場合の症状
指定していたカラムに、ただファイル名が登録されます。ディレクトリ名のカラム等がブランクになります。
Controller で $this->request->data を見ると以下のようになっています。
[カラム名] => IMAGE01.png
こうなれば OK
Controller で $this->request->data を見た際に、以下のように受け取れていれば OK です。
[カラム名] => Array ( [name] => IMAGE01.png [type] => image/png [tmp_name] => /tmp/phprQQMKF [error] => 0 [size] => 680 )
考えられる原因
- Form タグに対する “type” => “file” 指定のし忘れ
対応方法
Step 1. アップロード用 Form の View を確認しましょう。
Form->create に対して “type” => “file” を指定しているか確認しましょう。
View の例としては、以下の通りです。
echo $this->Form->create("モデル名", array("type" => "file") ); echo $this->Form->input("カラム名", array("type" => "file") );
アップロード用 Form の HTML ソースを確認します。以下のようになっていたら、指定し忘れです。
<form action="/test/Images/add" id="ImageAddForm" method="post" accept-charset="utf-8">
以下のように enctype=”multipart/form-data” が含まれていれば OK です。
<form action="/test/Images/add" id="ImageAddForm" enctype="multipart/form-data" method="post" accept-charset="utf-8">
チェック4. アップロード先のディレクトリが用意できているか
NG な場合の症状
以下のようなエラーメッセージが出たりします。
Warning (2): mkdir(): Permission denied [APP/Plugin/Upload/Model/Behavior/UploadBehavior.php, line 1792] Warning (2): chmod() [function.chmod]: No such file or directory [APP/Plugin/Upload/Model/Behavior/UploadBehavior.php, line 1793] Warning (2): move_uploaded_file(/アップロードベースディレクトリ/作成ディレクトリ/IMAGE01.png) [function.move-uploaded-file]: failed to open stream: No such file or directory [APP/Plugin/Upload/Model/Behavior/UploadBehavior.php, line 357] Warning (2): move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpAJEzOG' to '/アップロードベースディレクトリ/作成ディレクトリ/IMAGE01.png' [APP/Plugin/Upload/Model/Behavior/UploadBehavior.php, line 357] Error: An Internal Error Has Occurred.
こうなれば OK
正常に登録が完了して、ファイルが配置されれば OK です。そりゃそうだ、って話ですが。
考えられる原因
- 用意したディレクトリのパス間違い
- パーミッション不足
対応方法
Step 1. アップロードベースディレクトリがどこになっているかを確認しましょう。
アップロードベースディレクトリがどこになっているかは、エラーメッセージに表示されていれば、すぐに分かります。
もし表示されていない場合は、以下の方法で表示することができます。
Controller で 以下のように pr() します。
pr( $this->モデル名->Behaviors->Upload->settings["モデル名"]["カラム名"] );
配列になっていて、配下の “path” や、“thumbnailPath” に、それぞれのフルパスがセットされています。
注意点としては、パスに含まれるモデル名やカラム名は、小文字になるといったところです。
Step 2. アップロードベースディレクトリに至るパスまでのパーミッションを確認しましょう。
パーミッションがあれば、Upload プラグインは自動的にアップロードベースディレクトリの作成も行ってくれます。
必要に応じて chmod コマンドや FTP を利用して、パーミッション変更をしましょう。
必要なパーミッションは運用次第です。web アクセスで書き込みできるような設定にしましょう。どうしても分からない場合は、低セキュリティになりますが、 777 (rwxrwxrwx) に設定してしまえばいけるでしょう。
また、パスの途中全てで、ディレクトリに入るための実行権限である 1 (x) は最低必要です。
ひとこと
個人的にはまったのは、アップロードベースディレクトリでした。
オーナー と www ユーザーとが別のため、パーミッションの指定をちゃんとできていませんでした。
パーミッションさえあれば、自動的に作成してくれるとは知らず、はまってしまいました。
当記事がお役に立てば幸いです。
[pn-box color=”lgray”]次の記事は、以下になります。良かったら以下もご覧下さい。
しっかり理解する CakePHP Upload プラグインの使い方 (5) アップロードされたファイルをリネームする方法
今回は以上です。
[pn-amzn-cakephp]