質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.10%

move_uploaded_file()処理時のエラー解決策について

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 567

score 22

お世話になっております。
兼ねてより制作中のWEBサイトで画像の保管をする際に使用している
move_uploaded_file()で下記エラーの解消がしきれず困っております。

Warning (2): move_uploaded_file(webroot/files/Ices/image_file/20200103113922DSC_0002.JPG): failed to open stream: No such file or directory [APP/Controller/IcesController.php, line 119]
Warning (2): move_uploaded_file() [<a href='https://secure.php.net/function.move-uploaded-file'>function.move-uploaded-file</a>]: Unable to move '/tmp/php6xMSmE' to 'webroot/files/Ices/image_file/20200103113922DSC_0002.JPG' [APP/Controller/IcesController.php, line 119]
Warning (512): Unable to emit headers. Headers sent in file=/home/ec2-user/environment/my_pt_lesson/vendor/cakephp/cakephp/src/Error/Debugger.php line=853 [CORE/src/Http/ResponseEmitter.php, line 51]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/ec2-user/environment/my_pt_lesson/vendor/cakephp/cakephp/src/Error/Debugger.php:853) [CORE/src/Http/ResponseEmitter.php, line 152]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/ec2-user/environment/my_pt_lesson/vendor/cakephp/cakephp/src/Error/Debugger.php:853) [CORE/src/Http/ResponseEmitter.php, line 185]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/ec2-user/environment/my_pt_lesson/vendor/cakephp/cakephp/src/Error/Debugger.php:853) [CORE/src/Http/ResponseEmitter.php, line 185]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/ec2-user/environment/my_pt_lesson/vendor/cakephp/cakephp/src/Error/Debugger.php:853) [CORE/src/Http/ResponseEmitter.php, line 185]


▽エラー発生時に取得できている内容(一部抜粋です)▽
※line 119の取得内容の一部

$file = [
    'tmp_name' => '/tmp/php6xMSmE',
    'error' => (int) 0,
    'name' => 'DSC_0002.JPG',
    'type' => 'image/jpeg',
    'size' => (int) 170153
]
$filePath = 'webroot/files/Ices/image_file/20200103113922DSC_0002.JPG'
$size = (int) 170153
$ext = 'image/jpeg'


上記情報取得時のコード(下記IcesController全体のコード中"処理B"の部分)

                move_uploaded_file($_FILES['image_file']['tmp_name'], $filePath);
         ※↑line119がここになります


エラーメッセージの内容から、本サイト、他のネット記事を参考に、
"パスの指定方法の誤り"が大方の原因であることはある程度理解できたため、
自身の環境にあわせ指定をしたところ、一旦は解決できました(パスの記載内容は丁度この内容で解決してました)。
ただ、その後、少し時間をあけてから同様の操作をすると、
同じエラーが出てしまいます。その根本の解決策の模索中です。

▽環境▽
AWS Cloud9:無料枠
MySQL:ver5.7.26
CakePHP:ver3.8.2
PHP:ver7.2.19
※以前の質問記事(https://teratail.com/questions/230485)から大きく変更した点
A:画像投稿はmove_uploaded_file()で処理(今回はこの部分についてのご相談です)
B:以前使用していたプラグイン"FriendsOfCake/cakephp-upload"は無効化
C:画像データ自体はAmazon S3へ保管(他はMySQLへ)

▽"AWS Cloud9:無料枠"のディレクトリ構成です▽
※"image_fileフォルダ"の直下に画像データが入っていました。
※move_uploaded_file()を使用してから下記ディレクトリ構成に変更はありません。
イメージ説明

▽画像登録時のコード全体像(IcesController)▽

public function add()
    {
        $ice = $this->Ices->newEntity();
        if ($this->request->is('post')) {
            $ice = $this->Ices->patchEntity($ice, $this->request->getData());
            $file = $this->request->getData('image_file'); 
            $filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];
            //特定の拡張子かつ800KB未満でないとアップできないようにする
            $size = $file['size'];//容量を取得
            $ext = $file['type'];//拡張子を取得
            if($ext ==='image/jpg' && $size < 819200)//処理A
            {
                $file = $this->request->getData('image_file'); 
                $filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];
                move_uploaded_file($_FILES['image_file']['tmp_name'], $filePath);//Storage to directry to photo data.
            }elseif($ext ==='image/jpeg' && $size < 819200){//処理B
                $file = $this->request->getData('image_file'); 
                $filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];
                move_uploaded_file($_FILES['image_file']['tmp_name'], $filePath);
            }elseif($ext ==='image/png' && $size < 819200){//処理C
                $file = $this->request->getData('image_file'); 
                $filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];
                move_uploaded_file($_FILES['image_file']['tmp_name'], $filePath);
            }elseif($ext ==='image/gif' && $size < 819200){//処理D
                $file = $this->request->getData('image_file'); 
                $filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];
                move_uploaded_file($_FILES['image_file']['tmp_name'], $filePath);
            }else{//処理E
                $this->Flash->error(__('種類はjpg,jpeg,png,gif,サイズは800KBまでで登録をお願いします'));
                return $this->redirect(['controller' => 'ices', 'action' => 'add']);
            }
            $data = array(
               'manufacturer' => $this->request->getData('manufacturer'),
               'ice_name' => $this->request->getData('ice_name'),
               'ice_fraver' => $this->request->getData('ice_fraver'),
               'price_no_tax' => $this->request->getData('price_no_tax'),
               'buy_year' => $this->request->getData('buy_year'),
               'buy_month' => $this->request->getData('buy_month'),
               'simple_comment' => $this->request->getData('simple_comment'),
               'desc_comment' => $this->request->getData('desc_comment'),
               'image_file' => date("YmdHis") . $file['name'],
               'repeat_rate' => $this->request->getData('repeat_rate'),
               'stock_rate' => $this->request->getData('stock_rate'),
        ); 
            $ice = $this->Ices->newEntity($data); 
            $ice->user_id = $this->Auth->user()['id'];
            if ($this->Ices->save($ice)) {//Storage to DB
            //to AWSs3[upload]
            // if(isset($ice)){
            // $this->setAction('upload',$ice);
            // };
            $this->Flash->success(__('アイスの登録ができました'),['key' => 'positive']);
            return $this->redirect(['controller' => 'users', 'action' => 'view', $this->Auth->user()['id']]);
            }
            $this->Flash->error(__('アイスの登録ができませんでした'));
        }
       //一部略
}


・アップロード対象の画像ファイルの拡張子、容量を元に処理A~Eに分けられるように記述し、
アップロードができるようになるまでに使用したファイルが"処理B"に振られたため、
そこでパスの調整をし、できるようになったのが、下記の記載でした。

$filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];

・その後、他の想定ファイルでもアップできることを確認し、
記載内容や作業環境の整理の一環とし、下記の作業を行っています。
1、//debug();や、他の不要なコメントアウトの削除。
2、不要な空行をCtrl+Deleteで詰める
3、image_fileに収納された画像データの削除
4、phpMyAdminより検証で増えたレコードを一括削除
5、$filePath = 'webroot/files/Ices/image_file/'.date("YmdHis").$file['name'];を処理A~Eまでに記述

...といった内容ですが、どこか今回のエラーに繋がる要因があるのでしょうか。
また、そもそものパスの指定方法自体も、改めて勉強中ですが、
画像投稿処理ができた時点のコードをそのまま保存し、
翌日に試しても同様のエラーが出る、といった状況がまばらに続いており、
困惑しているところもありますが、何か解決の糸口となるご提示を
していただけると非常に助かります。
お手数おかけしますが、どうぞご教示をお願いいたします。

▼以下、2020/1/4 追記分です▼
1/3にいただいたコメントより、公式ドキュメント
(https://book.cakephp.org/3/ja/core-libraries/file-folder.html)を
元に上記質問内容内"IcesController.php"の"//処理B"内を
下記のように書き換え実行すると、"image_file"ディレクトリの直下にファイルが
保存されることまでは確認ができました。
ただ、その"保存されるファイル"というのが、"size"が"0"となっており、
画像ファイルとして閲覧することはできない状態で保存されています。

---以下、書き換えた内容---
▽IcesController.phpの処理B内

$time = Time::now('Asia/Tokyo'); //時刻をTokyoに指定し
$time = $time->i18nFormat('yyyyMMddHHmmss');//時間取得
$file = $this->request->getData('image_file'); //★A:ファイル情報取得
$file = new File(WWW_ROOT.'/files/Ices/image_file/'.$time.$file['name']);
$file->create();//★B:image_fileディレクトリへ新規ファイルとして画像ファイル作成 

この書き換えた内容の★Aのすぐ下でdebug($file);をした場合、
sizeは投稿しようとするファイルの容量を表示しています

[
'tmp_name' => '/tmp/phplCeijU',
'error' => (int) 0,
'name' => 'DSC_0002.JPG',
'type' => 'image/jpeg',
'size' => (int) 170153
]


また、★Bの下でdebug($file);してみると下記のように表示されています。

object(Cake\Filesystem\File) {
Folder => object(Cake\Filesystem\Folder) {
path => '/home/ec2-user/environment/my_pt_lesson/webroot/files/Ices/image_file'
sort => false
mode => (int) 493
[protected] _fsorts => [
'name' => 'getPathname',
'time' => 'getCTime'
]
[protected] _messages => []
[protected] _errors => []
[protected] _directories => null
[protected] _files => null
}
name => '20200104130459DSC_0002.JPG'
info => []
handle => null
lock => null
path => '/home/ec2-user/environment/my_pt_lesson/webroot/files/Ices/image_file/20200104130459DSC_0002.JPG'
}


今の時点で容量も含めての保存処理が必要なことは検討がついているのですが、
どのように記述すればよいかというところで手詰まりな状態です。
保存処理の方針に対しての過不足、上記記述内容のお気づきの点等ありましたら、
改めてご教示いただけると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • Ryota.I

    2020/01/04 13:13

    先日はありがとうございました。
    いただいた情報(https://book.cakephp.org/3/ja/core-libraries/file-folder.html)
    元に上記質問内容内"IcesController.php"の"//処理B"内を
    下記のように書き換え実行すると、"image_file"ディレクトリの直下にファイルが
    保存されることまでは確認ができました。
    ただ、その"保存されるファイル"というのが、"size"が"0"となっており、
    画像ファイルとして閲覧することはできない状態で保存されています。

    ---以下、書き換えた内容---
    $time = Time::now('Asia/Tokyo'); //時刻をTokyoに指定し
    $time = $time->i18nFormat('yyyyMMddHHmmss');//時間取得
    $file = $this->request->getData('image_file'); //★A:ファイル情報取得
    $file = new File(WWW_ROOT.'/files/Ices/image_file/'.$time.$file['name']);
    $file->create();//★B:image_fileディレクトリへ新規ファイルとして画像ファイル作成 
    ---書き換えた内容ここまで---

    この書き換えた内容の★Aのすぐ下でdebug($file);をした場合、
    sizeは投稿しようとするファイルの容量を表示しています
    [
    'tmp_name' => '/tmp/phplCeijU',
    'error' => (int) 0,
    'name' => 'DSC_0002.JPG',
    'type' => 'image/jpeg',
    'size' => (int) 170153
    ]
    また、★Bの下でdebug($file);してみると下記のように表示されています。
    object(Cake\Filesystem\File) {
    Folder => object(Cake\Filesystem\Folder) {
    path => '/home/ec2-user/environment/my_pt_lesson/webroot/files/Ices/image_file'
    sort => false
    mode => (int) 493
    [protected] _fsorts => [
    'name' => 'getPathname',
    'time' => 'getCTime'
    ]
    [protected] _messages => []
    [protected] _errors => []
    [protected] _directories => null
    [protected] _files => null
    }
    name => '20200104130459DSC_0002.JPG'
    info => []
    handle => null
    lock => null
    path => '/home/ec2-user/environment/my_pt_lesson/webroot/files/Ices/image_file/20200104130459DSC_0002.JPG'
    }
    今の時点で容量も含めての保存処理が必要なことは検討がついているのですが、
    どのように記述すればよいかというところで手詰まりな状態です。
    保存処理の方針に対しての過不足、上記記述内容のお気づきの点等ありましたら、
    改めてご教示いただけると幸いです。

    キャンセル

  • m.ts10806

    2020/01/04 13:36

    質問編集して追記してください

    キャンセル

  • Ryota.I

    2020/01/04 13:48

    m.ts10806様。ご指摘ありがとうございます。
    質問内容本文内に追記いたしました(そのためコメントに追記済みの本質問内容は削除リクエスト済みです)。
    お手数をおかけしますが、もしよろしければ、改めてご確認、ご教示お願いいたします。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る