画像名に日本語が入っていると画像が上手く表示されない

画像名に日本語が入っていると画像が上手く表示されないということがありました。

CakePHP関係なく、WordPressなどでもそうらしいです。

最初は「PCで上げた画像がスマホで表示されない」と悩んでいたんですが、それは厳密には違いました。

PCのスクリーンショットの画像は「スクリーンショット+[日時].jpeg」みたいな名前になります。

これがスマホでは画像名に日本語(「スクリーンショット」というカタカナ)が入っているので表示できないということでした。

当時めちゃくちゃ焦りましたが、解決できたので書いていきます。

【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7

画像名に日本語を使わないでIDなどを使うようにする

結論として「画像名に日本語を使わないでIDなどを使うようにする」ようにしました。

例えば命名規則が単純に「日時+[画像名].拡張子」だと日本語が混じる可能性があります。

なので「日時+[画像名].拡張子」みたいにしてしまいます。

自分の実際のコードは以下です。

// POST送信時の処理
        if($this->request->isPost()){
            // 画像ファイル名称の先頭に時間をつけて/webroot/imgに移動させる
            $upload_file = $this->request->getData('name');
            $filePath_pc = WWW_ROOT.'img/'.date("YmdHis").$this->Auth->user('id').'.'.pathinfo($upload_file['name'])['extension']; // 注目する行
            $filePath_sp = WWW_ROOT_SP.'img/'.date("YmdHis").$this->Auth->user('id').'.'.pathinfo($upload_file['name'])['extension']; // 注目する行
            if(is_uploaded_file($upload_file['tmp_name']) && copy($upload_file['tmp_name'],$filePath_pc) && move_uploaded_file($upload_file['tmp_name'],$filePath_sp)){
                // photoにフォームの送信内容を反映
                $data = [
                    'name' => date("YmdHis").$this->Auth->user('id').'.'.pathinfo($upload_file['name'])['extension'], // 注目する行
                    'user_id' => $this->request->getData('user_id'),
                ];
                $photo = $this->Photos->newEntity($data);
                // photoに保存する
                if($this->Photos->save($photo)){
               (中略)

コードの一部なので、見辛いかもしれません。

まず前提として、PC画像とスマホ画像でパスを分けています。

「注目する行」と書いたところを見ていただきたいです。

この3つの行で画像を命名しています。

一番分かりやすいところで最後のDBに格納する名前の値の部分ですが、以下になっています。

'name' => date("YmdHis").$this->Auth->user('id').'.'.pathinfo($upload_file['name'])['extension'], // 注目する行

まずdate("YmdHis")(日時)、次に$this->Auth->user('id')(ユーザーID)、最後に拡張子です。

※pathinfoファンクションは拡張子などが取れるファンクションです。

これで命名に日本語を避けています。

ユーザーID以外にもいろんな方法があると思うので、好きな方法を取ってください。

終わりに

以上となります。

とにかく画像名は日本語を避けたほうが無難かと思います。

画像が命のサービスなので、そこは気をつけました。

他にも良い方法があったら教えていただきたいです。

ありがとうございました。