CakePHP5入門【CakePHP5実用編⑭】人物アイコン画像

B美
「人物アイコン画像」関連ってこと
ただ、リファクタリングの続きとして、各Viewファイル内にあるCSS定義を別ファイルにまとめておきたいところね

C菜
ちょっと調べてみますね~
・・・
えっと、「templates/Top」の中の「index.php」と「templates/Chat」の中の「index.php」だけでした~
あと、「templates/layout」の中の「default.php」にもstyleタグがありますけど~

A子
ファイル名を「chat.css」にして作ってみたよ

C菜
具体的には「templates/layout」の中にある「default.php」を書き換えるです~


A子
うまくいかない…
なんで?

B美
(「<?= SENT_COLOR ?>」及び「<?= RECEIVED_COLOR ?>」の箇所)
CSSファイルって、PHPファイルじゃないからね
当然「<?= (定数名) ?>」は効かないわよ

A子

B美
1.「templates/layout/default.php」の中に「CSS変数」を定義する(styleタグ内)
2.「webroot/css/chat.css」内に存在するPHPコードの箇所を「CSS変数」を読み込むコードに変更する |
上記1番の定義としては下記の通り
<style>
:root { --sent-color: <?= SENT_COLOR ?>; --received-color: <?= RECEIVED_COLOR ?>; } </style> |
んで、2番はこんな感じね
.sent {
background-color: var(--sent-color); align-self: flex-end; text-align: right; } .received { background-color: var(--received-color); align-self: flex-start; text-align: left; } .sent::after { content: ""; position: absolute; right: -8px; top: 50%; transform: translateY(-50%); width: 0; height: 0; border-style: solid; border-width: 8px 0 8px 10px; border-color: transparent transparent transparent var(--sent-color); } .received::after { content: ""; position: absolute; left: -8px; top: 50%; transform: translateY(-50%); width: 0; height: 0; border-style: solid; border-width: 8px 10px 8px 0; border-color: transparent var(--received-color) transparent transparent; } |







C菜
よくわかりました~
これって、色々なところに応用できそうなテクニックですよね~

B美
CSSファイルの中でPHPの定数が(「CSS変数」経由で)使えるというのは、知っておくと便利かも…

A子
これって、普通に画像をアップロードするだけじゃダメなの?

C菜
(だってファイル名を「(各ユーザのid).png」にするという仕様でしたし~)

A子
でもまぁ、Viewファイルについては同じだよね
(画像投稿掲示板のViewを流用できそう)
てなわけで、「templates/Users」の中に「change_image.php」というファイルを新規作成してみたよ

↓


C菜

↓


B美
具体的には「src/Controller」の中にある「UsersController.php」に、「changeImage」メソッドを追加します
public function changeImage()
{ if ($this->request->is('post')) { $upload = $this->request->getData('upload'); //オリジナルのファイル名を取得 $original_filename = $upload->getClientFilename(); if ($original_filename != '') { $extension = mb_strtolower(pathinfo($original_filename, PATHINFO_EXTENSION)); //拡張子 if ($extension == 'jpg' || $extension == 'jpeg' || $extension == 'gif' || $extension == 'png') { //一時ファイルのパス $temp_path = $upload->getStream()->getMetadata('uri'); //画像形式に応じて画像作成 switch ($extension) { case 'jpg': case 'jpeg': $image = imagecreatefromjpeg($temp_path); break; case 'gif': $image = imagecreatefromgif($temp_path); break; case 'png': $image = imagecreatefrompng($temp_path); break; } //PNG画像の作成 $webroot = WWW_ROOT; $dst = $webroot.'personal'.DS.$this->identity->id.'.png'; if (imagepng($image, $dst)) { $this->Flash->success(__('人物アイコン画像を変更しました。')); } else { $this->Flash->error(__('人物アイコン画像の変更に失敗しました。')); } //画像データの破棄 imagedestroy($image); return $this->redirect(['controller' => 'Top', 'action' => 'index']); } } } } |
あ、アップロード画像の画像サイズ(縦横のドット数)チェックは、やってないからね



A子
拡張子チェックを通ったあとの処理って、こういう流れかな
1.アップロードした画像ファイルの、一時ファイルとしてのパスを取得する
2.1番を元にして、画像形式に応じた画像を作成する 3.2番を元にして、PNG画像を作成して保存する 4.2番の画像データを破棄する |
てか、コード中に記述されているコメントを参考にしたんだけどさ(苦笑)

B美
ポイントは、(1番の)アップロードした画像ファイルの一時的な置き場所を取得するところね
(それが無いとイメージクリエイトできないのよ)

C菜
それではさっそくテストしてみましょう~

A子
んん?
おかしいな
変わらないよ?

B美
ブラウザとしては(わざわざWebサーバへリクエストせずに)自分の持つキャッシュデータを使うのが当然よね

C菜
つまりは[Ctrl]+[F5]キーの同時押しですね~

A子
てか、今見たら勝手に更新されてたよ
(更新処理してないのに…)

B美
(これは一定時間経過すると行うみたい…よく知らんけど(苦笑))
まぁ、キャッシュデータを使わないようにする画像ファイルへのアクセス方法もあるけどね
うーん、そうねぇ
ヘッダ部分にログインユーザの名前とメールアドレスを表示しているけど、そこにアイコン画像も表示してみましょうか
(画像の強制更新付きで…)

C菜

B美
こんな感じね


C菜


A子

B美
そうすると、ブラウザはキャッシュを使わず、Webサーバへ画像データを取得しに行くってわけ
(だってURLが違うもの)
これを「Cache Busting」と呼んでいるわ

C菜
名前がかっこいいテクニックです~
それでは私のアカウントでログインして、テストしてみますね~

↓

↓


A子

B美

C菜
完璧です~





A子
今は同じアイコン画像じゃないから、発言内容にちょっと違和感が…(苦笑)

C菜
B美部長には感謝ですね~