下記URLのサイトをもとに、画像アップロードの実装をおこなっております。
https://blog.s-giken.net/325.html
画像のアップロード、削除までは、実装できましたが、
編集を行う際、画像の差し替えを行った場合に、新たにアップロードした画像が
DBに反映されません。同様に、指定したディレクトリにも画像が格納されません。
編集を実行してもエラーメッセージなどは表示されず、保存されたというメッセージが出力されます。
丸3日ほど、色々と修正を試みましたが、解消はされませんでした。
CakePHPにお詳しい方のお力をお借りしたく存じます。
宜しくお願い致します。
DBデーブル
CREATE TABLE `news` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `title_date` date NOT NULL, `title` varchar(255) NOT NULL, `body` text, `file_name` text, `created` datetime NOT NULL, `modified` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
edit.ctp
<?php $this->assign('title','Edit Post'); ?> <h1>編集画面</h1> <?= $this->Html->link('戻る',['action'=>'index'],['class'=>['pull-right','fs12']]); ?> <?= $this->Form->create($news); ?> <?= $this->Form->textarea('title_date'); ?> <?= $this->Form->textarea('title'); ?> <?= $this->Form->textarea('body'); ?> <!--画像の修正--> <?php //image」の有無をチェックすることで、ファイルがアップロードされているか否かをチェック if($news->file_name){ echo $this->Html->image("/upload_img/".str_replace('\','/',$news->file_name)); echo $this->Form->input("file_before",["type"=>"hidden", "value"=>$news->file_name]); echo $this->Form->input("delete",["type"=>"submit", "name"=>"file_delete", "value"=>"delete"]); }?> <?=$this->Form->control('file_name1',["type"=>"file"]);?> <?= $this->Form->button('submit'); ?> <?= $this->Form->end(); ?>
NewsController.php
<?php namespace App\Controller; use App\Controller\AppController; use Cake\Filesystem\Folder; use Cake\Filesystem\File; use RuntimeException; class NewsController extends AppController { public function index() { $news = $this->paginate($this->News); $this->set(compact('news')); } ////編集////////////////////////////////////////////////////////////////////// public function edit($id = null) { //変数newsの中に、DBから取得したデータを入れる $news = $this->News->get($id, [ 'contain' => [] ]); //PATCH 一部分を更新したい場合。POST 新規に追加する場合。 PUT 丸ごと更新する場合。 //リクエストがPATCH、POST、PUT である時の処理 if ($this->request->is(['patch', 'post', 'put'])) { //patchEntityこれは、データの更新するときに使用する。具体的には、更新処理。 //patchEntity 複数のレコードのデータを一括して更新してくれる //テーブルnewsのデータを取得 $news = $this->News->patchEntity($news, $this->request->getData()); //アップロードするファイルを保存するフォルダを指定 $dir = realpath(WWW_ROOT . "/upload_img"); // deleteボタンがクリックされたか、いかなの判定 if($this->request->getData('file_delete')){ try { //フォルダを作成して、そこに差し替えまえのファイルを移動させる $del_file = new File($dir . "/". $this->request->getData('file_before')); // ファイル削除処理実行 Fileクラスで削除処理対象のファイルを指定して削除を実行 if($del_file->delete()) { $news['file_name'] = ""; } else { //削除できなかった時の処理 $news['file_name'] = $this->request->getData('file_before'); throw new RuntimeException('ファイルの削除ができませんでした.'); } //エラー処理 } catch (RuntimeException $e){ $this->Flash->error(__($e->getMessage())); } } else { //submitボタンを押した時の処理。 // ファイルが入力されたとき、ファイルをアップロードする if ($this->request->getData('file_name.name')) { $limitFileSize = 10240 * 10240; //アップロードするファイルを保存するフォルダを指定 $dir = realpath(WWW_ROOT . "/upload_img"); try { //ファイルの入力項目の値「$this->request->data['file_name']」と指定した値を引数として渡して、関数を実行 $news['file_name'] = $this->file_upload($this->request->getData('file_name1'), $dir, $limitFileSize); } catch (RuntimeException $e){ $this->Flash->error(__('ファイルのアップロードができませんでした.')); $this->Flash->error(__($e->getMessage())); } catch (RuntimeException $e){ // アップロード失敗の時、既登録ファイルがある場合はそれを保持 if ($this->request->getData('file_before')){ $news['file_name'] = $this->request->getData('file_before'); } $this->Flash->error(__('ファイルのアップロードができませんでした.')); $this->Flash->error(__($e->getMessage())); } } else { // ファイルは入力されていないけど登録されているファイルがあるとき if ($this->request->getData('file_before')){ $news['file_name'] = $this->request->getData('file_before'); } } } if ($this->News->save($news)) { $this->Flash->success(__('The news has been saved.')); if($this->request-> getData('file_delete')){ $this->set(compact('news')); return $this->redirect(['action' => 'edit', $id]); } else { return $this->redirect(['action' => 'index']); } } $this->Flash->error(__('The news could not be saved. Please, try again.')); } $this->set(compact('news')); $this->set('_serialize', ['news']); } ///////////////////////////////////////////////////////////////////////////// ////実際にファイルアップロードを行う処理/////////////////////////////////// public function file_upload ($file = null,$dir = null, $limitFileSize = 10240 * 10240){ try { // ファイルを保存するフォルダ $dirの値のチェック if ($dir){ if(!file_exists($dir)){ throw new RuntimeException('指定のディレクトリがありません。'); } } else { throw new RuntimeException('ディレクトリの指定がありません。'); } // 未定義、複数ファイル、破損攻撃のいずれかの場合は無効処理 if (!isset($file['error']) || is_array($file['error'])){ throw new RuntimeException('Invalid parameters.'); } // エラーのチェック switch ($file['error']) { case 0: break; case UPLOAD_ERR_OK: break; case UPLOAD_ERR_NO_FILE: throw new RuntimeException('No file sent.'); case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: throw new RuntimeException('Exceeded filesize limit.'); default: throw new RuntimeException('Unknown errors.'); } // ファイル情報取得 $fileInfo = new File($file["tmp_name"]); // ファイルサイズのチェック if ($fileInfo->size() > $limitFileSize) { throw new RuntimeException('Exceeded filesize limit.'); } // ファイルタイプのチェックし、拡張子を取得 if (false === $ext = array_search($fileInfo->mime(), ['jpg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif',], true)){ throw new RuntimeException('Invalid file format.'); } // ファイル名の生成 //そのままのファイル名を使用 $uploadFile = $file["name"] . "." . $ext; $uploadFile = sha1_file($file["tmp_name"]) . "." . $ext; // ファイルの移動 if (!@move_uploaded_file($file["tmp_name"], $dir . "/" . $uploadFile)){ throw new RuntimeException('アップロードしたファイルの移動ができませんでした'); } // 処理を抜けたら正常終了 // echo 'File is uploaded successfully.'; } catch (RuntimeException $e) { throw $e; } return $uploadFile; } ///////////////////////////////////////////////////////////////////////////// }
NewsTabele.php
<?php namespace App\Model\Table; //クラスをまえもって呼び出しておく use Cake\ORM\Table; //画像拡張子を指定するためのバリデーションを使えるようにする use Cake\Validation\Validator; $validator = new Validator(); class NewsTable extends Table { //初期化しておく public function initialize(array $config) { $this->setTable('news'); $this->primaryKey('id'); $this->setDisplayField('dir'); //$this->addBehavior('Timestamp'); } }
情報
phpバージョン:7.2.19 cakePHPバージョン:3.7.8 画像格納先:webroot/upload_img/