HTML/CSS/PHPの練習 実践 雑多な記録

CSSは無くともよい場合も(サーバ側だし)。WordPressを使ってブログやECサイト作成もいいが、
これはこれで基本だけでも平行してやっておくかな。WordPressのカスタマイズにはJavaScript
よりも必要なようだし。
練習場
http://slack150memo.blog.example.com/homepage/ (自分PCのローカルアドレス)
エディタ
https://vscode.dev/
Emacs PHP Modeユーザーマニュアル (Draft) (emacs php-mode、でググった)
https://qiita.com/tadsan/items/a76768439869f00a4e89
(どーも今はそこまで頑張る気になれないなあ。困った。今は補完が便利でVSCode使ってるけど、
\JSもPHPも慣れたらいづれはEmacsに戻っていく気がする)
こっちでInstしてEmacsに戻った。(2023.07)、web-modeも以下でInstした。(2024.09)
https://shirakawa.weblike.jp/blog-page/2023/07/18…

/*************************************************************************************/
気づけばプロ並みPHP(参考書籍1)
Chapter 1 いろいろ準備編 (2022.03)
(自分の練習環境はLinuxだし、既にLAMP環境も入れてる https://shirakawa.weblike.jp/blog-page/2022/03/13… ので不要。.htaccessでutf8設定も必要なかった)
Chapter 2 お店のスタッフは誰?
2-1 データベースを作成しよう!:
$ mkdir /myproj/slack150memo/homepage
$ sudo elvis /etc/httpd/extra/httpd-vhost.conf (以下を追加)
\<Directory “/myproj/slack150memo/homepage”>
\ AllowOverride None
\ Options None
\ Require all granted
\</Directory>
\<Directory “/myproj/slack150memo/phpMyAdmin”>
\ AllowOverride None
\ Options None
\ Require all granted
\</Directory>
$ grep hosts /etc/nsswitch.conf
hosts: files dns
$ sudo ifconfig lo 127.0.0.1 netmask 255.0.0.0
$ sudo sh /etc/rc.d/rc.httpd start
$ sudo sh /etc/rc.d/rc.mysqld start
ブラウザで http://slack150memo.blog.example.com/phpMyAdmin/ (自分PCの..)にアクセス。
データベース「shop」をutf8_unicode_ciで作成した。
2-2 スタッフを追加する画面を作ろう!:
http://slack150memo.blog.example.com/homepage/staff/staff_add.php (自分PCの..)
実行した。ここまではhtmlのみ。
2-3 スタッフ情報の入力チェック画面を作ろう!:
(phpて一部のみ間違っていても途中まで実行することなく全滅?、スクリプトだがインタプリタ
\ではないから?。<form>をprintし忘れただけでまっ白。そこは通らないのに。コンパイラの様な
\チェック用のツールがありそう。ググるか)
(タグの属性を操作できるのはJSだけかと思っていたら、value=”‘.$staff_name.'”って何だよphp
\もできるのか。違った勘違い、text編集してるだけ。そりゃPerlでもできるか。変数と固定は’.’
\でつなげるらしい)
2-4 情報の追加を完了させる画面を作ろう!:
$dsn = ‘mysql:dbname=shop; host=localhost; charset=utf8’;
(DBアクセスの1行目では要注意。=前後に半角スペースを入れると失敗。これはハマる)
2-5 情報の追加を完了させる画面を作ろう!:
2-6 スタッフ情報の修正画面を作ろう!:
2-7 好きな画面に分岐ジャンプさせよう!:
2-8 スタッフの削除画面と参照画面を作ろう!:
Chapter 3 お店に商品を並べよう!(2022.04)
3-1 商品を追加する画面を作ろう!:
http://slack150memo.blog.example.com/homepage/product/pro_add.php (自分PCの..)
(DBでVARCHARの初期値に何も入れないとINSERT_INTOでエラーになる。DB設定でNULLにした)
(正規表現の’+’は直前の文字の1回以上の繰返し)
(chmod a+rwx homepage/product/gazou か chown apache しないとfileをDLできない)
3-2 ほかの画面を一気に作っちゃおう!:
3-3 ワクワク♪ 商品の画像を追加しましょう!:
Chapter 4 関係者以外立ち入り禁止!
4-1 ログイン画面を作ろう!:
http://slack150memo.blog.example.com/homepage/staff_login/staff_login.html (自分PCの..)
4-2 ユーザー認証の仕組みを作ろう!:
4-3 ログアウト画面を作ろう!:
https://www.php.net/manual/ja/function.session-name
session_name() 関数は、 セッションの状態をチェックするようになりました。 これより前のバージョンでは、 クッキー の状態をチェックするだけでした。 そのため、古い session_name() 関数は session_start() 関数の後に session_name() 関数をを呼び出すことを許して しまっており、それが PHP のクラッシュや不具合を起こす可能性がありました。
https://www.php.net/manual/ja/function.session-destroy.php
警告 すぐにセッションを削除してしまうと、 望まない結果が起こる可能性があります。 、、、こうした事象を防ぐためには、 $_SESSION に削除時のタイムスタンプを設定し、 それより後のアクセスを拒否するようにしなければなりません。 もしくは、アプリケーションが同時に 複数のリクエストを受け付けないようにすることです。
Chapter 5 遊びでスキルアップ!
5-1 季節の野菜サイトを作ろう!:
5-2 あの星は!: (参考書籍1)
5-3 学生に戻ろう!: (参考書籍1)
5-4 プログラミングの楽しさの真髄!:
(制御文はCに同じ、関数はJSに同じ、変数や文字列の扱いはPerlに近い、という感じ?)
5-5 遊びで身に付けた技術を使って!:
Chapter 6 憧れのショッピングカートを作ろう!
6-1 まずは商品を表示しよう!:
http://slack150memo.blog.example.com/homepage/shop/shop_list.php (自分PCの..)
6-2 「カートに入れる」機能を作ろう!:
(VSCodeで<?php~?>の間を書いていたら、foreachも補完された。PHPも補完できるのか。とはいえ
\コピペだけで作っていたら補完はいらないという、、が、初めて使うタグとかコマンドには効果大)
6-3 カートの中身を見る画面を作ろう!:
これが必殺技var_dump()だ!(WordPressのデバッグでも結構使うらしい)
6-4 カートを空にする画面を作ろう!:
6-5 商品の購入数を変える機能を追加しよう!:
6-6 カートから商品を削除する機能を作ろう!:
6-7 大切なお客様のために!:
Chapter 7 注文を受け付けよう!
7-1 注文フォームの画面を作ろう!:
7-2 注文チェックの画面を作ろう!:
7-3 注文登録の画面を作ろう!:
(mb_send_mail()実行してもメール飛ばないな、と思ったらPHPはLinuxのメールシステム使ってるか、
\そりゃそうか。こっちにまとめる)
https://shirakawa.weblike.jp/blog-page/2022/04/26…
7-4 注文情報をデータベースに追加しよう!:
http://slack150memo.blog.example.com/phpMyAdmin/ (自分PCの..)アクセス、テーブル追加。
(郵便番号を5桁以上にできてしまう。DBにINSERT_INTOする時にエラーになる)
7-5 もっと安全にしよう!:
Chapter 8 Excelで注文管理したい!(2022.05)
8-1 注文データを日付で選べるようにしよう!:
http://slack150memo.blog.example.com/homepage/staff_login/staff_top.php (自分PCの..)
(year/month/dayを関数化する時に、そのままprint無しで関数化して動かそうとしてしまった。こりゃ
\確かにPHPで関数化するよりJSで関数化した方が早いわけだ。作る側としては。クライアント重くなる
\かもしれんけど)
8-2 注文データをダウンロードしよう!:
(GnumericがSlackのpkgには無かったのでZaurusので確認した。OKだった)

これまでの総復習中。(2024.09)
これまでのフロー図または画面遷移図をDrawioで書いてみる。
とりあえずHPがないので、HPは以下とした。Apacheのリンク可の設定もした。
$ ln -s shop/shop_list.php index.php
ECサイトのアカウントをマジメに考える。https://shirakawa.weblike.jp/blog-page/2024/01/27…
\
CSSもマジメに考える。
PHPやLaravelを使う場合、CSSの設計はどのように行うか?
PHPやLaravelを使う場合、CSSの設計にはいくつかの方法がありますが、プロジェクトの規模や要件に応じて最適な方法を選ぶことが重要です。以下は一般的なCSS設計のアプローチです。
### 1. **シンプルなCSSの設計**
\- 小規模なプロジェクトでは、基本的なCSSファイルを直接使用できます。`public/css`フォルダにCSSファイルを配置し、ビュー(Bladeテンプレートなど)でリンクを張ります。
\- スタイルの管理がしやすいように、CSSファイルをコンポーネントやページごとに分割するとよいでしょう。
### 2. **BEM(Block Element Modifier)を用いた設計**
\- BEMは、CSSクラス名を「ブロック」「エレメント」「修飾子」の形式で命名する方法です。これにより、CSSが再利用しやすく、スコープが明確になります。
\- 例: `.button–primary`, `.nav__item–active`
### 3. **SassやLessの使用**
\- Laravelでは、Sass(またはLess)を使用してスタイルシートを管理することができます。これにより、変数、ネスト、ミックスイン、関数などの機能を利用して、CSSをより効率的に記述できます。
\- Laravel Mixを使用して、Sass/SCSSファイルをコンパイルし、最適化されたCSSファイルを生成します。
### 4. **Tailwind CSSの導入**
\- LaravelとTailwind CSSを組み合わせることで、ユーティリティファーストのアプローチを使用してスタイルを設計できます。Tailwind CSSは、あらかじめ定義されたユーティリティクラスを使用して、迅速にレスポンシブデザインを作成できます。
\- `tailwind.config.js`でカスタマイズしたテーマを設定し、Laravel Mixを使用してビルドします。
### 5. **Atomic Designの採用**
\- 大規模なプロジェクトでは、Atomic Designの原則を適用することで、スタイルの再利用性とメンテナンス性を向上させることができます。
\- UIコンポーネントを原子(Atom)、分子(Molecule)、有機体(Organism)などの単位に分割し、それぞれに対応するスタイルを定義します。
### 6. **CSSフレームワークの使用**
\- BootstrapやFoundationなどのCSSフレームワークを使用することで、既存のコンポーネントやグリッドシステムを活用して、迅速にレスポンシブなデザインを作成できます。
\- Laravelでは、これらのフレームワークと簡単に統合できます。
### 7. **Laravel Mixの利用**
\- Laravel Mixは、Webpackの設定を簡素化するためのツールで、CSSやJavaScriptのコンパイル、圧縮、バンドルをサポートします。SassやLess、PostCSSなどのプリプロセッサと連携させることができます。
### 8. **モジュール化されたCSS**
\- 各コンポーネントやページに特化したCSSを作成し、それをモジュールとして分けることで、スタイルが混在しないようにします。これにより、スタイルのスコープが明確になり、CSSの管理が容易になります。
これらのアプローチの中から、プロジェクトの特性やチームのスキルセットに最も適したものを選んでください。

Chapter 9 お客様に会員になってもらおう! (2024.09)
9-1 会員登録の画面を作ろう!:
9-2 会員ログインの仕組みを作ろう!:
9-3 会員だけの特典「かんたん注文」の仕組みを作ろう!:
(終わってしまった。楽しかった)

/*************************************************************************************/
JS(FW)のDBへのAPIを作る。(2022.06)
HTML/CSS/JavaScriptの練習 実践 雑多な記録3
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/HTML/CSS/JavaScript%a4%ce%ce%fd%bd%ac%20%bc%c2%c1%a9%20%bb%a8%c2%bf%a4%ca%b5%ad%cf%bf%a3%b3
で、BackboneJSでデータの永続化をするため、MySQL(MariaDB)を使うのにPHPでAPIを作ることにした。
https://qiita.com/naga3/items/cacb8182ad79dbbf6e64
https://medium.com/@scottdixon/backbone-js-with-php-mysql-362b07dad844
https://shusatoo.net/programming/php/backbone-mode…
https://mawatari.jp/archives/backbonejs-todos-with…
https://qiita.com/hidepy/items/42220523cb2b3eb2c451 (php file_get_contents php //input、でググった)
(PHPもRubyもJS(FW含む)のAPIとしてしか使わないなら、(PHPやRubyの)FWまでは要らないんじゃないか?
\って気がするが、サーバとクライアントの負担のバランスを考えると必要になることもあるのか?、
\AIとか使わないビジネスロジックも(今のところ)サーバ側でやる事が多い?、交通整理が要る?)
を参考にする。
$ sudo ifconfig lo 127.0.0.1 netmask 255.0.0.0
$ sudo sh /etc/rc.d/rc.httpd start
$ sudo sh /etc/rc.d/rc.mysqld start
http://slack150memo.blog.example.com/phpMyAdmin/ (自分PCの..)アクセス、新しいDB作って、
テーブル追加。1カラム目は(index?)codeにして後は、firstName、lastName、email、を追加。
phpMyAdmin_SQL$ INSERT INTO mst_people (firstName,lastName,email) VALUES (“Alice”,”Henderson”,”alice@example.com”) //残りも同様に実行.
JS(FW)からはPATHも含めたphpファイル名(と引数)を指定することでAPIを使用している。
上でやった練習ファイルコピペして作るか。後で使うのでGET以外も最初から入れとこう。
$ cp ~/myproj/slack150memo/homepage/staff/staff_list.php contacts.php
VSCode(クラウド版)で編集した。FC2には*.phpを置けないので*.smpにrenameして置いた。

/*************************************************************************************/
PHPフレームワーク Laravel入門(参考書籍4)
やろうかと思ったけど、目次見たらスゲー量だ。基本だけやって後は辞書的な使い方ってできない
だろか。必要になったら見る、とか。そうしよう。基本的な使い方を1,2パターンやったら、後は、
できる事をざっくり覚えておくか。

参考書籍1をLaravel化する事で、実践的な書き方への変更、セキュリティの向上を計る。(2024.09)
Laravel化はAIにやらせてみる。
以下の小規模な、野菜屋のECサイトの商品一覧(shop_list.php)を、サニタイズやバリデーションを考慮してLaravelで書き直し、シンプルなCSSを追加せよ。
(コードのメモは省略)
以下に、PHPのコードをLaravelに書き直し、サニタイズを考慮した上でシンプルなCSSを追加します。LaravelではBladeテンプレートを使用し、クエリビルダやEloquent ORMを利用することで、より安全で簡潔なコードを書けます。フォーム入力は無いのでバリデーションは含まれていません。
\
ステップ 1: コントローラーの作成
まず、ShopControllerというコントローラーを作成し、商品一覧を取得してビューに渡す処理を行います。
$ cd /myproj/60-nouen2
$ php artisan make:controller ShopController
Could not open input file: artisan (何とLaravelをInstしてなかった)
こっちでInstする。https://seesaawiki.jp/lifewithslackzaurus_15_0/d/Laravel
$ cd /myproj
Laravelプロジェクトを作成する。(プロジェクトファイルも作成してなかった)
$ PATH=$PATH:/usr/local/laravel-composer/:~/.config/composer/vendor/bin/ composer create-project –prefer-dist laravel/laravel 60-nouen2
プロジェクトファイルを作成しないとLaravelはInstされないので、ログはこっちにメモした。
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/Laravel
$ cd 60-nouen2
$ ls -l
\合計 356
\-rw-r–r– 1 ore root 3958 4月 12 2022 README.md
\drwxr-xr-x 7 ore root 4096 4月 12 2022 app
\-rwxr-xr-x 1 ore root 1686 4月 12 2022 artisan
\drwxr-xr-x 3 ore root 4096 4月 12 2022 bootstrap
\-rw-r–r– 1 ore root 1745 4月 12 2022 composer.json
\-rw-r–r– 1 ore root 288283 9月 3 xx:yy composer.lock
\drwxr-xr-x 2 ore root 4096 4月 12 2022 config
\drwxr-xr-x 5 ore root 4096 4月 12 2022 database
\-rw-r–r– 1 ore root 473 4月 12 2022 package.json
\-rw-r–r– 1 ore root 1202 4月 12 2022 phpunit.xml
\drwxr-xr-x 2 ore root 4096 4月 12 2022 public
\drwxr-xr-x 6 ore root 4096 4月 12 2022 resources
\drwxr-xr-x 2 ore root 4096 4月 12 2022 routes
\-rw-r–r– 1 ore root 569 4月 12 2022 server.php
\drwxr-xr-x 5 ore root 4096 4月 12 2022 storage
\drwxr-xr-x 4 ore root 4096 4月 12 2022 tests
\drwxr-xr-x 43 ore root 4096 9月 3 xx:yy vendor
\-rw-r–r– 1 ore root 559 4月 12 2022 webpack.mix.js
$ PATH=$PATH:/usr/local/laravel-composer/:~/.config/composer/vendor/bin/ php artisan make:controller ShopController (再実行した)
Controller created successfully.
$ ls -l app/Http/Controllers/
合計 8
\-rw-r–r– 1 ore root 361 4月 12 2022 Controller.php
\-rw-r–r– 1 ore root 121 9月 7 xx:yy ShopController.php
次に、ShopControllerに以下のコードを追加します。
$ emacs app/Http/Controllers/ShopController.php
(コードのメモは省略)
ステップ 2: ルートの設定
routes/web.phpにルートを追加します。
(コードのメモは省略)
ステップ 3: ビューの作成
次に、Bladeテンプレートとしてresources/views/shop_list.blade.phpを作成し、以下の内容を追加します。
$ emacs resources/views/shop_list.blade.php
Warning (emacs): php-mode is NOT support blade template. Please install `web-mode’ package (上の方で入れた)
(コードのメモは省略)
ステップ 4: CSSの作成
シンプルなスタイルシートを作成します。public/css/style.cssに以下の内容を追加します。
$ mkdir public/css
$ emacs public/css/style.css
(コードのメモは省略)
ステップ 5: データベース接続の設定
Laravelの.envファイルにデータベース接続情報を設定します。
$ emacs .env
(接続情報のメモは省略)
\
完成したコードの動作
この構成では、/shop_listにアクセスすると、ユーザーのログイン状態に応じてメッセージを表示し、商品一覧を表示します。また、すべての出力は適切にサニタイズされており、CSRFやXSS攻撃を防ぐことができます。CSSで基本的なスタイリングが適用され、シンプルで使いやすいデザインになります。

https://seesaawiki.jp/lifewithslackzaurus_15_0/d/PHP%2d8%2e2
を参考に、/etc/httpd/extra/httpd-vhosts.conf
\<VirtualHost localhost:443>
\ ServerAdmin ore@60-nouen2.com
\ DocumentRoot /myproj/60-nouen2/public
\ ServerName 60-nouen2.com
\ ServerAlias www.60-nouen2.com
\ SSLEngine on
\ SSLCertificateFile /etc/httpd/server.crt
\ SSLCertificateKeyFile /etc/httpd/server.key
\ # PHP-FPM
\ <FilesMatch \.php$>
\ SetHandler “proxy:fcgi://127.0.0.1:9000”
\ </FilesMatch>
\ <Directory “/myproj/60-nouen2/public”>
\ AllowOverride All
\ Options Indexes FollowSymLinks
\ Require all granted
\ </Directory>
\ ErrorLog /var/log/httpd/60-nouen2.com-error_log
\ CustomLog /var/log/httpd/60-nouen2.com-access_log common
\</VirtualHost>

httpdを動かしているapacheが書き込みできず、
UnexpectedValueException
The stream or file “/myproj/60-nouen2/storage/logs/laravel.log” could not be opened in append mode: Failed to open stream: Permission denied The exception occurred while attempting to log: The stream or file “/myproj/60-nouen2/storage/logs/laravel.log” could not be opened in append mode: Failed to open stream: Permission denied The exception occurred while attempting to log: The stream or file “/
$ sudo chown -R apache /myproj/60-nouen2/storage
$ sudo chown -R apache /myproj/60-nouen2/bootstrap/cache

https://60-nouen2.com/shop_list
へのアクセスでshop_list.phpからの変換分が表示できた。ステップ2で、/shop_listをルーティング
設定していた(というか”完成したコードの動作”でAIが説明してる。見ずに少しジタバタした)。’/’は
defではwelcomeページ表示になっているようだ。これもルーティングで設定してる。

/*****************************************/
AI使ってどう書いたら動くのかの回答を貰っても、
Route::get(‘/shop_list’, [ShopController::class, ‘list’])->name(‘shop_list’);
結局、書籍を見るかAIに内容を聞かないとパラメタの意味が分からない。動作する仕組みが分からない。

Route::get(‘/shop_list’, [ShopController::class, ‘list’])->name(‘shop_list’); の意味を教えて、
と聞くとAIはそこだけを教えてくれる。これも有用だ。沢山ある中から必要な関数と引数をズバリ教え
てくれる。
一方、書籍だと、Route::get(アドレス,関数など); から説明している。60-nouen2以下のファイルやディ
レクトリの意味を説明している。これも必要だよなあ。やっぱ一回くらいは最初から書籍をじっくり
読むか。納得いくか飽きるまで。

Chapter 1 Laravelを準備する
1-1 PHPフレームワークとLaravel:
1-2 Laravelを使ってみる:
Chapter 2 ルーティングとコントローラ
2-1 ルーティング:

/*****************************************/
参考書籍1をLaravel化する続き
shop_product.php:
shop_list.php から以下の shop_product.php を実行していたが、shop_product.php はどのように変更するか?
(コードのメモは省略)
shop_product.phpをLaravelに適応させるためには、LaravelのMVC(Model-View-Controller)構造に従ってコードを再構築する必要があります。以下はその手順です。
1.コントローラーにメソッドを作成
まず、ShopControllerに商品詳細を表示するためのメソッドを追加します。
$ emacs app/Http/Controllers/ShopController.php
(コードのメモは省略)
2.ルートの定義
routes/web.phpで、商品詳細ページへのルートを設定します。
$ emacs routes/web.php
(コードのメモは省略)
3.ビューの作成
resources/viewsディレクトリにshop_product.blade.phpというBladeテンプレートファイルを作成し、商品情報を表示します。
$ emacs resources/views/shop_product.blade.php
(コードのメモは省略)
4.セッション管理
Laravelでは、セッション管理にsessionヘルパーを使用します。ユーザーのログイン状態をチェックし、適切なメッセージやリンクを表示します。(パターン1)
(コードのメモは省略)
Laravelでは、セッションの管理は通常Authファサードを使います。session_start()や$_SESSIONを使用する代わりに、Laravelの認証機能を活用して、ログイン状態を確認し、ユーザー名を表示します。Auth::check()は、ユーザーがログインしているかを確認します。Auth::user()でログイン中のユーザーの情報を取得できます。(パターン2)
(コードのメモは省略)
5.サニタイズの考慮
Bladeテンプレートでは、データをそのまま出力すると自動的にエスケープされますが、htmlspecialcharsを使用して明示的にサニタイズすることもできます。ただし、Laravelではe()ヘルパーや二重中括弧 {{ }} を使用することで自動的にエスケープされます。
(コードのメモは省略)
6.画像の表示
商品に画像がある場合は表示し、ない場合は「画像はありません」と表示します。画像ファイルはstorageディレクトリに保存し、シンボリックリンクを作成してアクセス可能にします。
$ sudo mkdir -p storage/product/gazou
$ sudo cp -i -a ../60-nouen/product/gazou/* storage/product/gazou/
$ sudo chown -R apache storage
$ php artisan storage:link
(コードのメモは省略)
7.その他の設定
・ルーティングの設定: shop_cartinやmember_loginなどのルートが正しく設定されているか確認します。
・CSSの適用: シンプルなスタイルを適用するために、public/css/style.cssを作成し、ビューで読み込みます。
(コードのメモは省略)
8.データベース接続設定
.envファイルでデータベース接続情報を設定します。
(設定のメモは省略)
9.エラーハンドリング
例外処理をLaravelの仕組みに合わせて行います。
(コードのメモは省略)
10.セキュリティとバリデーション
・バリデーション: $pro_codeが整数であることを確認します。
(コードのメモは省略)
・CSRF対策: フォームには@csrfディレクティブを追加します。
\<form method=”POST” action=”{{ route(‘shop_cartin’) }}”>
\ @csrf
\ <!– フォーム内容 –>
\</form>
(保留。後から見る)
まとめ
shop_product.phpをLaravelに移行することで、コードの可読性や保守性が向上し、Laravelの豊富な機能を活用できます。上記の手順に従って、適切にコントローラー、ルート、ビューを設定し、セキュリティやサニタイズを考慮した実装を行ってください。

blade.phpの中にコメント文を入れたい。
{{– これはBladeのコメントです –}}
<!– これはHTMLコメントです –>

storage/product/gazou/以下の画像ファイルが表示されない。
アプローチ1: 画像をpublicディレクトリに移動する
アプローチ2: storageディレクトリを公開する (シンボリックリンクを作成)
$ php artisan storage:link (よく見ると上にもあってやってなかった。そういう事か)
これにより、storage/app/publicディレクトリがpublic/storageとして公開され、storage/app/public/product/gazou/のファイルにアクセスできるようになります。
どちらのアプローチを使うべきか?
・もし画像を頻繁にアップロードしたり、storageディレクトリを使用する必要がある場合は、アプローチ2(シンボリックリンクの作成)がおすすめです。
・シンプルな構造で、全ての公開ファイルをpublicディレクトリにまとめたい場合は、アプローチ1で画像ファイルをpublicに移動する方がわかりやすいかもしれません。
$ PATH=$PATH:/usr/local/laravel-composer/:~/.config/composer/vendor/bin/ php artisan storage:link
The [/myproj/60-nouen2/public/storage] link has been connected to [/myproj/60-nouen2/storage/app/public].
The links have been created.
$ ls -l storage/app/
合計 4
drwxr-xr-x 3 apache root 4096 9月 11 xx:yy public
$ sudo mv -i storage/product storage/app/public/
(これで画像が表示できた)
$ ls -l public/
合計 12
drwxr-xr-x 2 ore root 4096 9月 10 xx:yy css
\-rw-r–r– 1 ore root 0 4月 12 2022 favicon.ico
\-rw-r–r– 1 ore root 1710 4月 12 2022 index.php
\-rw-r–r– 1 ore root 24 4月 12 2022 robots.txt
lrwxrwxrwx 1 ore root 36 9月 11 xx:yy storage -> /myproj/60-nouen2/storage/app/public
(よく見ると、単にリンクを張っているだけだった)

shop_product.php から実行している shop_cartin.php をLarabelへ変換せよ。
(コードのメモは省略)
1. ルーティングの設定、2. コントローラの作成、3. Bladeテンプレートの作成
4. セッション管理の改善(オプション)
Laravelのセッションはsession()を使って簡単に管理できます。例えば、session()->regenerate()でセッションIDの再生成ができ、session()->has()でセッションの有無を確認します。これを使用することで、PHPのsession_start()やsession_regenerate_id(true)を直接呼び出す必要がなくなります。

shop_list.php から実行している shop_cartlook.php をLarabelへ変換せよ。
1.セッション管理: session() 関数でLaravelのセッション管理が行われています。cart と kazu はセッションから取得しています。
2.データベース操作: PDO を直接使用していた部分は、LaravelのEloquent ORMやクエリビルダを使って、データベースとのやり取りを行います。クエリビルダを使って、mst_product テーブルから商品情報を取得しています。
3.テンプレート拡張: @extends と @section を使ってBladeテンプレートを拡張し、共通レイアウト (layouts.app) を使用しています。

shop_cartlook.php から呼び出している kazu_change.php を Laravelへ変換せよ。
1.セッション管理: Laravel のセッション管理機能を使用して、session(‘cart’) でカートの内容を取得し、更新しています。
2.バリデーション: Request クラスで受け取った数量 (kazu) に対してバリデーションを行い、1以上10以下の整数に制限しています。
3.削除処理: 商品が削除された場合には、array_splice() を使って cart と kazu の配列からその商品を削除しています。
4.リダイレクト: 処理が完了したら、cartlook のルートにリダイレクトし、メッセージを表示します。

shop_cartlook.blade.php から呼び出している shop_form.php を Laravelへ変換せよ。
1.Bladeテンプレートの作成: shop_form.php を Blade テンプレートに変換し、Laravel のフォーム送信メカニズムや CSRF 保護を追加しました。
2.バリデーション: 名前やメールアドレス、郵便番号、電話番号に対して Laravel の Request クラスを使ったバリデーションを実装しました。
3.確認ページ: ユーザーが入力したデータを確認するページを作成しました。

shop_form_check.php から実行している shop_form_done.php をLarabelに変換せよ。
1.メール送信: Laravel の Mail ファサードを使用して、注文確認メールと店舗への通知メールを送信します。
2.データベース操作: トランザクションを使って、注文データ(dat_sales)と注文商品のデータ(dat_sales_product)を安全に保存します。
3.セッション管理: セッションに保存されているカート情報を使用して、注文内容をデータベースに保存し、メール送信後にセッションをクリアします。

ShopController.php にてメール送信できていない。どのような原因が考えられるか?sendmailコマンドにて送信できる事は確認できている。
1. Mailファサードの設定が不完全
・LaravelのMailファサードでメールを送信する場合、config/mail.phpに正しい設定がされているか確認してください。特に、sendmailのパスやMAIL_MAILERの設定が正しいかどうか確認する必要があります。
解決策: MAIL_MAILERがsendmailになっているか確認します。以下のように.envファイルで設定を確認・修正します。
MAIL_MAILER=sendmail
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=abc@def.net
MAIL_FROM_NAME=”ろくまる農園”
2. fromアドレスの不一致
・Mail::raw()の2つ目の送信で、from()メソッドを使用して$emailを直接セットしています。この値が送信元の設定と一致していないと、メールサーバ側で拒否される可能性があります。メール送信者(Fromアドレス)が送信するドメインと一致していないと、スパム対策としてブロックされることがあります。
解決策: from()にabc@def.netを設定し、送信者アドレスが一貫するようにします。
(コードのメモは省略)
3. エラーメッセージの確認
・メール送信が失敗している場合、Laravelのログファイル(storage/logs/laravel.log)にエラーメッセージが記録されているかもしれません。このログを確認して、何が問題になっているか確認してみてください。
4. サーバー側のメール設定の問題
・サーバーのメール設定がLaravelのメール機能と適切に連携していない可能性もあります。sendmailコマンド自体が機能していても、Laravelが内部で使用しているメール送信ライブラリ(SwiftMailerなど)が正しく動作していないことがあります。
解決策: サーバーのsendmailパスが正しいか、config/mail.phpのsendmail設定が正しいか確認します。
‘sendmail’ => ‘/usr/sbin/sendmail -bs’,
5. メールの文字コードやエンコーディング
・日本語のメール送信の場合、mb_languageやmb_internal_encodingの設定が必要な場合があります。LaravelのMailではそのままテキストを送るとエンコーディングの問題が発生する可能性があります。
解決策: Mailファサードの前に、メール送信の際に以下のように文字コード設定を行うことを検討してください。
mb_language(‘Japanese’);
mb_internal_encoding(‘UTF-8’);

https エラーコード 419、でググると、いきなりLaravelがヒットする件:
[Laravel] 最も簡単で最も難しい419エラーの解決策
https://zenn.dev/wadakatu/articles/f3948e577a3b65

edit_check.blade.php で $staff->pass が受け取れていないのは、edit.blade.php からフォームデータを正しく渡せていないためです。
まず、edit_check.blade.php では $staff オブジェクトは存在せず、フォームから渡されたデータを受け取る必要があります。Laravelでは、フォームデータは request オブジェクトから受け取るのが一般的です。フォームから渡されたデータを直接 Blade テンプレートで確認したい場合、以下のように変更します。
説明
・フォームで送信されたデータは、request() を使って受け取ります。
・パスワードや名前などのフィールドは request(‘name’) や request(‘pass’) で取得できます。
・パスワードの一致チェックも request(‘pass’) と request(‘pass2’) を比較する形に変更しました。
これにより、edit_check.blade.php で正しくフォームデータを受け取って処理できます。

Laravel の Hash::make() 関数は、通常 60 文字のハッシュを生成します。このため、password カラムのサイズが小さい場合に、エラーが発生します。
$ ALTER TABLE mst_staff MODIFY COLUMN password VARCHAR(255);
これにより、60文字以上のハッシュ値を格納できるようになります。255 など余裕を持たせたサイズに設定するのが一般的です。
$ SHOW COLUMNS FROM mst_staff;
もし Laravel マイグレーションを使用している場合、マイグレーションファイルで password カラムのサイズを変更できます。以下の例を参考にしてください。
\Schema::table(‘mst_staff’, function (Blueprint $table) {
\ $table->string(‘password’, 255)->change();
\});
参考書籍4にてマイグレーションを読んだ。データベースの内容をLaravelのPGから生成する。(2024.11)

Larabelの機能で、以下の2つの違いを述べよ。
<a href=”{{ route(‘shop.cartlook’) }}”>カートを見る</a><br />
<a href=”{{ url(‘shop/cartlook’) }}”>カートを見る</a><br />
・**route()**は、名前付きルートを使ってURLを生成するため、柔軟性が高く、ルートが変更された際のメンテナンスが容易です。
・**url()**は、指定したパスを基にURLを生成するため、簡単ですが、ルートが変更された際の管理が難しくなります。
route()を使用することで、コードの保守性が向上し、特にアプリケーションが成長したりルート構造が変更される可能性がある場合に役立ちます。

laravel https 302 error code、でググった:
https://qiita.com/Yuzaburo/items/ca5a757c6ed223e0931f
(画像が転送されてなくて、受ける側でバリデーションでエラった)
無料判ChatGPTで、pro_add.php -> products/add.blade.php 変換したが、
<form method=”post” action=”pro_add_check.php” enctype=”multipart/form-data”>
から
<form method=”post” action=”{{ route(‘products.add_check’) }}”>
に変換された。無料判ChatGPTは時々間違う。
\
その他、405、POST待ちにGET
https://qiita.com/kiyc/items/692a53e1023ea72888d4
https://qiita.com/aminevsky/items/04cdf17686e28c9847c4
https://qiita.com/miriwo/items/2452b3466737cd117248
https://qiita.com/kuroudoart/items/44eca2150f102ba7fdb4

残りのコードも同様に、参考書籍1を復習しながら変換して、ほぼ実装した。(2024.10)

/*************************************************************************************/
より実際にECサイトに使えそうなLaravelのツールを探した
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/PHP/Laravel/OSS%20EC%a5%b7%a5%b9%a5%c6%a5%e0%a1%a2%cd%bd%cc%f3%a5%b7%a5%b9%a5%c6%a5%e0
が、主な高シェアなソフトはローコードやクラウド。OSSもでかくて複雑そうなので、
Laravelでの最小構成なものを使ってみる事にした。
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/Laravel%20Ecommerce

/*************************************************************************************/
参考書籍1のLaravel化したshop_*.phpをLunarのヘッドとして入れ込む。(2024.10)
フロントエンドをそのまま(HTML/CSSのみで頑張る)で行くか、生JSかReact化するかは後から検討する。

https://seesaawiki.jp/lifewithslackzaurus_15_0/d/Laravel%20Ecommerce%20%28Lunar%29%20%bb%c8%a4%a4%ca%fd
上で、ShopController.php を
use Lunar\Base\Traits\LunarUser;
use Lunar\Base\LunarUser as LunarUserInterface;
を考慮してLunarで動作するように変換したが、DB合わせや動作確認はここでやる。
Lunarには以下のテーブルがある。
activity_log
failed_jobs
lunar_addresses
(メモ省略)
先のShopController.php にて使用している以下のテーブルを上のLunarのテーブルに割り振りたい。
以下のテーブルの gazou は、画像ファイル名のこと。
商品一覧テーブル mst_product (code,name,price,gazou)
注文情報テーブル dat_sales (code, date, code_member, name, email, postal1, postal2, address, tel)
注文商品テーブル dat_sales_product (code, code_sales, code_product, price, quantity)
上記のLunarのテーブルをもとに、ShopController.phpにて使用している3つのテーブルをLunarのシステムに適合させる方法を考えると、それぞれの役割をLunarのテーブル構造にマッピングできます。(ChatGPT)
### 1. **商品一覧テーブル (mst_product)**
\- **テーブル内容**: 商品コード (code), 商品名 (name), 価格 (price), 画像ファイル名 (gazou)
\- **対応するLunarテーブル**:
\ – `lunar_products`: 商品の基本情報(商品名やSKUなど)を管理します。`name`や`code`はここにマッピングされます。
\ – `lunar_product_variants`: `price`やその他のバリエーションごとの情報(例: SKUやサイズ、在庫)を保持します。価格はこのテーブルに格納されるため、`price`はここに保存されます。
\ – `media`: 商品画像ファイルは`media`テーブルに格納されます。このテーブルの`file_name`フィールドに`gazou`が対応します。

priceはlunar_pricesテーブルに入っているようだが、product_idが無いように見えるが、どの商品の値段かをどうやって特定する?
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/Laravel%20Ecommerce%20%28Lunar%29%20%bb%c8%a4%a4%ca%fd

lunar_pricesテーブルのpriceable_idには複数のpriceがある。最新のpriceを取得するにはSQLコマンドをどう書く?
`lunar_prices`テーブルで特定の`priceable_id`に対して最新の価格を取得するためには、SQLの`GROUP BY`と`MAX`関数を使って最新の`created_at`または`updated_at`を持つ行を取得する方法が一般的です。以下はそのSQLクエリの例です。
### 例: 特定の`priceable_id`の最新価格を取得するクエリ
\SELECT lp.*
\FROM lunar_prices lp
\INNER JOIN (
\ SELECT priceable_id, MAX(updated_at) AS latest_update
\ FROM lunar_prices
\ GROUP BY priceable_id
\) AS latest_prices
\ON lp.priceable_id = latest_prices.priceable_id
\AND lp.updated_at = latest_prices.latest_update
\WHERE lp.priceable_id = 1; — ここに対象のpriceable_idを指定
### 説明
\- **`MAX(updated_at)`**: `updated_at`が最新の日付を持つ行を取得します。
\- **`GROUP BY priceable_id`**: 同じ`priceable_id`ごとに最新の日付を取得します。
\- **`INNER JOIN`**: その最新日付に該当する行のみを取得します。
\- **`WHERE priceable_id = 1`**: 特定の`priceable_id`(ここでは1)に絞り込みます。
このクエリにより、`priceable_id`ごとに最新の価格が取得されます。

上記のSQLコマンドをLaravelではどう書くか?
LaravelのEloquentを使って、`lunar_prices`テーブルから最新の価格を取得するためのクエリは、以下のように書けます。
\use Illuminate\Support\Facades\DB;
\use App\Models\Lunar\Price;
\$latestPrice = Price::where(‘priceable_id’, 1) // 対象のpriceable_idを指定
\ ->orderBy(‘updated_at’, ‘desc’) // updated_atで最新順に並べる
\ ->first(); // 最初の1つを取得
### 説明
\- **`where(‘priceable_id’, 1)`**: 特定の`priceable_id`(ここでは1)をフィルタします。
\- **`orderBy(‘updated_at’, ‘desc’)`**: `updated_at`カラムを降順に並べ、最新のものを先頭に持ってきます。
\- **`first()`**: 最初の1つ、つまり最新の価格を取得します。
これにより、指定された`priceable_id`に対して最新の価格を取得することができます。
#### 別の方法(クエリビルダーを使う場合)
\$latestPrice = DB::table(‘lunar_prices’)
\ ->where(‘priceable_id’, 1) // priceable_idをフィルタ
\ ->orderBy(‘updated_at’, ‘desc’) // updated_atで降順ソート
\ ->first(); // 最新のデータを取得
この方法でも同じ結果が得られます。

商品名は、lunar_productsのattribute_dataに、{“name”:{“field_type”:”Lunar\\FieldTypes\\TranslatedText”,”value”:{“ja”:”\u30c8\u30de\u30c8″}},”description”:{“field_type”:”Lunar\\FieldTypes\\TranslatedText”,”value”:{“ja”:”<p>\u5c71\u58f2\u308a<\/p>”}}}という形で入っているが、クエリビルダーを使う場合で、どう取り出すか?
`lunar_products` テーブルの `attribute_data` カラムには JSON 形式で商品名や説明が保存されているので、Laravelのクエリビルダーを使ってデータを抽出し、`JSON_EXTRACT` を利用して特定のキーから値を取り出すことができます。
例えば、商品名 (`”name”`) を日本語(`”ja”`)で取り出すには、以下のようなクエリになります。
### クエリビルダーを使用した場合
\use Illuminate\Support\Facades\DB;
\$productName = DB::table(‘lunar_products’)
\ ->select(DB::raw(“JSON_UNQUOTE(JSON_EXTRACT(attribute_data, ‘$.name.value.ja’)) as product_name”))
\ ->where(‘id’, 1) // 商品のIDでフィルタリング
\ ->first();
\echo $productName->product_name;
### 説明
\- **`DB::raw()`**: クエリ内で生のSQL文を使用するために使います。
\- **`JSON_EXTRACT()`**: JSONデータから特定のキーの値を抽出します。`$.name.value.ja` は、`attribute_data` 内の `name` キーの `value` の中の `ja` を指定しています。
\- **`JSON_UNQUOTE()`**: JSON値がクォートされている場合に、クォートを除去して実際の文字列を返します。
\- **`where(‘id’, 1)`**: 商品IDに基づいてフィルタリングしています。
### 例: 商品名と説明を同時に取得する場合
\$productInfo = DB::table(‘lunar_products’)
\ ->select(DB::raw(”
\ JSON_UNQUOTE(JSON_EXTRACT(attribute_data, ‘$.name.value.ja’)) as product_name,
\ JSON_UNQUOTE(JSON_EXTRACT(attribute_data, ‘$.description.value.ja’)) as product_description
\ “))
\ ->where(‘id’, 1) // 商品のIDでフィルタリング
\ ->first();
\echo $productInfo->product_name;
\echo $productInfo->product_description;
この方法で、商品名や説明など、JSON形式で保存されているデータを簡単に抽出することができます。

配列に対して @foreach ($product[] as $product) という記述は、正しく機能しません。$product[] のような記述は新しい要素を配列に追加するためのもので、foreach で繰り返し処理するための構文としては不適切です。
配列に対してループ処理を行いたい場合、@foreach は次のように使います:
\@foreach ($products as $product)
\<p>
\ <a href=”{{ url(‘shop/product’, [‘procode’ => $product[‘code’]]) }}”>
\ {{ htmlspecialchars($product[‘name’], ENT_QUOTES, ‘UTF-8’) }} —
\ {{ htmlspecialchars($product[‘price’], ENT_QUOTES, ‘UTF-8’) }}円
\ </a>
\</p>
\@endforeach
修正のポイント
・@foreach 構文は、コレクションまたは配列に対して使います。したがって、$products は配列であり、その中身を foreach でループするのが正しい使い方です。
・$product[] は新しい要素を配列に追加する記述であり、ループ処理を行うためのものではありません。

ルートパラメータ、クエリパラメータ、フォームデータ、JSONデータ:
`$request` オブジェクトは、**GET**リクエストでも**POST**リクエストでも利用できます。Laravelの`Request`オブジェクトは、HTTPリクエスト全体を管理しており、GETパラメータ(クエリパラメータ)やPOSTデータ(フォームデータ)、ルートパラメータなど、すべてのリクエストデータにアクセスすることが可能です。
### GETリクエストでの `$request` の使用
`GET`リクエストの場合、URLクエリパラメータやルートパラメータを取得することができます。
#### 1. **クエリパラメータ** の取得
クエリパラメータは、URLの「`?`」以降に指定される値です。例えば、`/shop/product?category=1` というURLに対して、クエリパラメータ `category` を `$request` オブジェクトで取得できます。
\public function showProduct(Request $request)
\{
\ // クエリパラメータの取得
\ $category = $request->query(‘category’); // ‘category’ パラメータが取得できる
\ // もしくは、all()で全クエリパラメータを取得
\ $allParams = $request->all(); // すべてのリクエストデータを取得
\}
#### 2. **ルートパラメータ** の取得
ルートに指定されたパラメータは、コントローラのメソッド引数として取得するか、`$request` オブジェクトからも取得できます。
\Route::get(‘/shop/product/{procode}’, [ShopController::class, ‘showProduct’])->name(‘shop.product’);
\public function showProduct(Request $request, $procode)
\{
\ // ルートパラメータの取得(引数)
\ // $procodeにはURLのパラメータが入ります: /shop/product/123 -> $procode = 123
\ // ルートパラメータを$requestからも取得可能
\ $procodeFromRequest = $request->route(‘procode’);
\}
### POSTリクエストでの `$request` の使用
`POST`リクエストでは、フォームデータやJSONデータなど、リクエスト本文に含まれるデータを取得できます。
\public function submitProduct(Request $request)
\{
\ // POSTデータの取得
\ $productName = $request->input(‘name’); // ‘name’ フィールドの値を取得
\}
### まとめ
\- `$request` オブジェクトは **GET** リクエストでも **POST** リクエストでも使用できます。
\- **GET**リクエストの場合、クエリパラメータやルートパラメータを取得可能。
\- **POST**リクエストでは、フォームデータやJSONデータを取得可能。
どちらの場合でも、`$request` オブジェクトを使って必要なリクエストデータにアクセスできます。
・url() は基本的に第2引数をURLパスパラメータとして扱うため、url(‘shop/product’, [‘procode’ => $product->code]) のように使うと、/shop/product/1 のような結果になります。
・route() はルートパラメータやクエリパラメータの両方に対応しており、名前付きルート(Route::name() で指定したルート)を使う場合、クエリパラメータとして正しく追加できます。route(‘shop.product’, [‘procode’ => $product->code]) を使うと、/shop/product?procode=1 のようにクエリパラメータが生成されます。

### 2. **注文情報テーブル (dat_sales)**
\- **テーブル内容**: 注文コード (code), 注文日 (date), 会員コード (code_member), 名前 (name), メール (email), 郵便番号 (postal1, postal2), 住所 (address), 電話番号 (tel)
\- **対応するLunarテーブル**:
\ – `lunar_orders`: 注文に関する基本的な情報(注文日、顧客情報)を保持します。`date`や`code`(注文コード)などがマッピングされます。
\ – `lunar_customers`: 顧客の基本情報を保存します。`code_member`、`name`、`email`などはこのテーブルに保存されます。
\ – `lunar_order_addresses`: 住所や連絡先(郵便番号、住所、電話番号)はこのテーブルに保存されます。
### 3. **注文商品テーブル (dat_sales_product)**
\- **テーブル内容**: 注文商品コード (code), 注文コード (code_sales), 商品コード (code_product), 価格 (price), 数量 (quantity)
\- **対応するLunarテーブル**:
\ – `lunar_order_lines`: 注文内の商品を保存します。ここに商品コード (`code_product`)、価格 (`price`)、数量 (`quantity`)が保存されます。
\ – `lunar_products`: 商品コード (`code_product`)は`lunar_products`テーブルのIDに対応します。
このように、Lunarのテーブル構造に合わせて、従来のテーブルをマッピングすることで、Lunarの機能を活用しながら既存の機能を適用できます。

ecommerce-app/app/Http/Controllers/ShopController.php のみLunarで表示できるようになった。
が、やっぱり実践的なヘッド(UI/UX)をちゃんと作らないと、お話にならない。

/*************************************************************************************/
以下で EC-CUBEをInstしてイロイロ調べているが、Symfonyベースらしい。以下にメモする事にした。
Inst、設定、起動方法 (2024.10)
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/EC%2dCUBE
使い方、と言うよりLaravel化 (2024.11-2024.12)
https://seesaawiki.jp/lifewithslackzaurus_15_0/d/EC%2dCUBE%20%bb%c8%a4%a4%ca%fd

以下に、Symfonyの `ProductStock` エンティティをLaravelのモデルとして変換した際のポイントを説明します。(ChatGPT)
### **1. ファイル構造**
\- Symfonyのエンティティは `Eccube\Entity\ProductStock` という名前空間に格納されています。
\- Laravelでは、このモデルは `app/Models/ProductStock.php` に配置するのが一般的です。
### **2. クラスとプロパティ**
\- Symfonyではプロパティに対してDoctrineのアノテーション(`@ORM\Column` など)を使用してデータベース構造を定義していました。
\- Laravelでは、これらをマイグレーションで管理し、モデル内で `$fillable` プロパティやリレーションを設定します。
### **3. データベースリレーション**
\- Symfonyではアノテーション(`@ORM\OneToOne` や `@ORM\ManyToOne`)を使用してリレーションを定義していました。
\- Laravelでは、Eloquent ORMのメソッド(`hasOne`, `belongsTo` など)を使用します。
\ – `ProductClass` とのリレーションは `belongsTo`。
\ – `Creator` とのリレーションも同様に `belongsTo` で定義します。
### **4. タイムスタンプ**
\- Symfonyでは `create_date` と `update_date` が個別に定義されていました。
\- Laravelでは `timestamps` を有効にすると、自動で `created_at` と `updated_at` が管理されます。
\ – `timestamps = false` を設定する場合、手動でカラムを管理する必要があります。
### **5. その他の変更点**
\- **定数の定義**
\ – Symfonyの定数(`IN_STOCK` と `OUT_OF_STOCK`)はそのまま `const` を使ってLaravelモデルに定義しました。
\- **メソッド名**
\ – Symfonyの `get` や `set` メソッドは、Laravelのアクセサ・ミューテータに置き換えることが可能です。
\ – シンプルな実装のため、まずはそのままメソッドを移植しています。
### **6. マイグレーションの作成**
\- Laravelではデータベーススキーマをマイグレーションで定義します。`dtb_product_stock` テーブルを再現するためのマイグレーションを別途作成する必要があります。
例:
\“`php
\Schema::create(‘dtb_product_stock’, function (Blueprint $table) {
\ $table->id();
\ $table->unsignedBigInteger(‘product_class_id’)->nullable();
\ $table->decimal(‘stock’, 10, 0)->nullable();
\ $table->unsignedBigInteger(‘creator_id’)->nullable();
\ $table->timestamps();
\});
(DBはEC-CUBEのを直接コピーしてるからマイグレーションはいいか?、念のため以下は実行)
$ PATH=$PATH:/usr/local/laravel-composer/:~/.config/composer/vendor/bin/ php artisan migrate
### **7. 補足**
\- 依存関係にある `ProductClass` や `Member` も同様にLaravelモデルとして実装する必要があります。
\- SymfonyからLaravelへの移行作業は、エンティティ以外にリポジトリやサービスの実装も含む場合が多いです。それらも適宜変換する必要があります。
変換後のLaravelモデルが正しく動作するように、必要に応じてマイグレーションやリレーションの設定を確認してください。
\
### **8. Viewの違い** (自分で追加、あるいはそのうち別途用意する)
\- **本件(エンティティ)ではなく、viewについて**
\ – Symfonyでは、*.twig、Laravelでは、*.blade.php。Symfonyでは、{% if、Laravelでは、@if。

/*************************************************************************************/
体系的に学ぶ 安全なWebアプリケーションの作り方(参考書籍6)
以下で 安全なWebアプリの作り方を調べているが、(2025.06)
https://shirakawa.weblike.jp/blog-page/2024/01/27…
33-001a.htmlのJSのコードに対して、PHPのコードが33-002a.phpの場合(PHP文は省略)、
`?>`で閉じていないが 、問題なく機能するのか? (->ChatGPT)

はい、PHPファイルの末尾に`?>`を書かなくても問題なく動作します。実際、多くのPHP開発者はあえて`?>`を書かないスタイルを採用しています。
### ✅ なぜ`?>`を省略しても問題ないのか?
PHPの公式仕様では、`?>`は PHPコードを終了して HTMLなどに戻すためのものであり、ファイルの最後がすべてPHPコードの場合は省略しても構文的に正しいです。
<?php
(PHP文は省略)
// ここでファイル終了 → OK
`?>`の後に空白や改行があると、意図せず出力されることがあり、特に `header()` や `setcookie()` のようなヘッダ出力関数がエラーを起こす原因になります。
* これを防ぐために、「ファイルの末尾に`?>`を書かない」スタイルが推奨されるようになっています。
### 📌 結論
* **問題なく機能します。**
* **ベストプラクティスとして`?>`は省略しておく方が安全です。**
必要であれば、PHP公式の該当説明リンクも紹介します。

/*****************************************/
4b-002e.phpの$descriptorspecとは何か? (->DeepSeek) (2025.10)
・外部プロセスを実行する際の標準入出力(stdin, stdout, stderr)の扱い方を指定する配列
・proc_open() 関数で使用されます
\
// これを実行しているのは親プロセス
$descriptorspec = array(
0 => array(“pipe”, “r”), // 子プロセスのstdin
1 => array(“pipe”, “w”), // 子プロセスのstdout
2 => array(“pipe”, “w”) // 子プロセスのstderr
);
// 親プロセスが子プロセス(some_command)を起動
$process = proc_open(‘some_command’, $descriptorspec, $pipes);
if (is_resource($process)) {
// 親プロセスが子プロセスのstdinに書き込み
fwrite($pipes[0], “入力データ”);
fclose($pipes[0]);
// 親プロセスが子プロセスのstdoutから読み取り
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($process);
}
通信の流れ
親プロセスが proc_open() で子プロセスを起動
親プロセス → $pipes[0]に書き込み → 子プロセスの標準入力
子プロセス → 標準出力 → $pipes[1] → 親プロセスが読み取り

/*****************************************/
4c-002a.phpの@(エラー制御演算子)以外にもC言語にはない演算子は他にあるか? (2025.10)
https://shirakawa.weblike.jp/blog-page/2025/10/12…

/*****************************************/
4g-021b.phpの $_COOKIE,$_SESSION,$_SERVER の違い (->DeepSeek) (2025.12)
https://www.php.net/manual/ja/reserved.variables.server.php
\

# PHPのスーパーグローバル変数比較表
| 項目           | `$_COOKIE`                  | `$_SESSION`                   | `$_SERVER`                  |
|----------------|-----------------------------|-------------------------------|-----------------------------|
| 保存場所       | クライアント側(ブラウザ)    | サーバー側                    |サーバー側(リクエスト時生成)|
| データの性質   | Cookieデータ(ユーザーごと) |セッションデータ(ユーザーごと) | サーバー/リクエスト情報     |
| データの安全性 |低い(クライアント側で改ざん可能)| 比較的高い(サーバー内)     | 中(一部クライアントから提供)|
| データ型       | 文字列のみ                  |配列、オブジェクトなど複雑なデータ| 文字列(一部は配列)      |
| データ容量     | 制限あり(約4KB/ドメイン)    | サーバーの設定による(大きい)  | リクエスト情報による        |
| 寿命           | 設定した有効期限まで        | セッション終了まで(デフォルト)| リクエスト中のみ            |
| 明示的な開始   | 自動で使用可能              | `session_start()`が必要       | 自動で使用可能              |
| 主な用途       | ユーザー設定、トラッキング  |ログイン状態、ショッピングカート| 環境情報、リクエスト情報   |

\

### 2. ライフサイクルの違い
|              | 生成タイミング      | 消滅タイミング         | 永続性           |
|--------------|---------------------|------------------------|------------------|
| `$_COOKIE`   | `setcookie()`時     | 有効期限切れ           | 複数セッション間 |
| `$_SESSION`  | `session_start()`時 | セッション終了・破棄時 | 複数リクエスト間 |
| `$_SERVER`   | リクエスト毎        | リクエスト終了時       | 単一リクエスト内 |

\

### 3. セキュリティ比較
| リスク   | `$_COOKIE`            | `$_SESSION`            | `$_SERVER`             |
|----------|-----------------------|------------------------|------------------------|
| 改ざん   | 可能(クライアント側)  | ほぼ不可能(サーバー側) | 一部可能(ヘッダー偽装) |
| 盗聴     | 全てのデータが通信    | セッションIDのみ通信   | 通信中の情報           |
| 推奨用途 | 非機密な設定          | 認証情報、重要なデータ | 参照のみ               |

\
### 5. 各変数の主なキー例
#### `$_COOKIE` の例
$_COOKIE[‘PHPSESSID’] // セッションID(デフォルト名)
$_COOKIE[‘preferred_lang’]、$_COOKIE[‘theme_color’]、$_COOKIE[‘tracking_id’]
\
#### `$_SESSION` の例
$_SESSION[‘user_id’]、$_SESSION[‘username’]、$_SESSION[‘cart’]、$_SESSION[‘last_activity’]
\

#### `$_SERVER` の主なキー
| キー              | 説明                 | 例                     |
|-------------------|----------------------|------------------------|
| `REQUEST_METHOD`  | HTTPメソッド         | GET, POST              |
| `REQUEST_URI`     | リクエストURI        | `/index.php?page=home` |
| `REMOTE_ADDR`     | クライアントIP       | `192.168.1.100`        |
| `HTTP_USER_AGENT` | ユーザーエージェント | `Mozilla/5.0...`       |
| `HTTP_REFERER`    | 参照元URL            | `https://example.com/` |
| `SERVER_NAME`     | サーバー名           | `www.example.com`      |
| `SCRIPT_NAME`     | 実行スクリプト       | `/index.php`           |

|
PHPはHTTPヘッダー名を $_SERVER のキーに変換する際、以下のルールを適用します:
X-CSRF-Token → HTTP_X_CSRF_TOKEN
X-Requested-With → HTTP_X_REQUESTED_WITH
Content-Type → HTTP_CONTENT_TYPE
User-Agent → HTTP_USER_AGENT
\

### 7.重要な注意点
|             | 注意すべき点                                                    |
|-------------|-----------------------------------------------------------------|
| `$_COOKIE`  | 重要なデータは保存しない。HTTP Only, Secure, SameSite属性を設定 |
| `$_SESSION` | セッション固定化攻撃対策が必要。セッションIDは推測困難なものに  |
| `$_SERVER`  | 信頼できない入力として扱う。偽装可能なヘッダーに注意            |

/*****************************************/
Origin ヘッダーが送信されるのは、以下の CORS(Cross-Origin Resource Sharing)リクエスト の場合です: (->DeepSeek) (2025.12)
## 送信される条件
1. クロスオリジンリクエストの場合
– 現在のページのオリジン(スキーム+ホスト+ポート)と、リクエスト先のオリジンが異なる場合
– 例:`https://example.com` から `https://api.example.com` へのリクエスト
2. POSTリクエストの場合(あなたの例のように)
– クロスオリジンPOSTリクエストではほぼ常に送信される
– 特に`Content-Type`が以下の場合:
– `application/x-www-form-urlencoded`
– `multipart/form-data`
– `text/plain`(あなたの例ではこれ)
– `application/json`など
3. 一部のGETリクエストでも送信される
– クロスオリジンで認証情報(Cookieなど)を含む場合
– ただし、シンプルなクロスオリジンGETリクエストでは送信されないことも

POST https://example.jp/4g/4g-021.php HTTP/1.1
Origin: https://example.jp:
– なぜOriginが送信されているか?
– `Referer: https://example.jp/4g/4g-022.html`と同一オリジンなので、通常は送信不要
– しかし、`Content-Type: text/plain`や`application/json`などの「プリフライトリクエストを引き起こす可能性のあるContent-Type」を使用しているため、ブラウザが安全のために送信している
GET https://example.jp/4g/4g-020.php HTTP/1.1:
(Originヘッダーなし)
– こちらは同一オリジン内でのシンプルなGETリクエストなので、`Origin`ヘッダーは送信されていない

## 技術的詳細
– `Origin`ヘッダーはユーザーエージェント(ブラウザ)が自動的に追加する
– 開発者が手動で設定することはできない(制限されている)
– CORSのプリフライトリクエスト(OPTIONS)でも送信される
– サーバー側でCORSポリシーを検証するために使用される
つまり、あなたの例ではPOSTリクエストで`Content-Type: text/plain`を使用しているため、ブラウザがCORS関連のチェックを行う一環として`Origin`ヘッダーを自動的に追加しているのです。

/*************************************************************************************/

 

主な参考書籍/参考URL、マニュアル:
気づけばプロ並みPHP 改訂版 2017.03
https://www.ric.co.jp/book/programming/detail/192
基礎からのMySQL 第3版 2017.09
https://www.sbcr.jp/product/4797393118/
(持っているのは1つ前の物)
Software Design 2019年12月号 第2特集 PHPプログラミング・アラカルト なぜ愛され,なぜ進化するのか?
https://gihyo.jp/magazine/SD/archive/2019/201912
PHP言語リファレンス
https://www.php.net/manual/ja/langref.php
Laravel(ララベル)とは?基礎知識やできることを解説
https://techmania.jp/blog/php0004/
Laravel学習帳 – はじめてのLaravel入門サイト –
https://laraweb.net/
PHPフレームワーク Laravel入門 第2版 2019.12
https://www.shuwasystem.co.jp/book/9784798060996.html
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) //Go
function handler(req, res) { //Node.jsもGoと似たような感じにハンドラ関数化
app.post(‘/body’, (req, res) => { //express.js
Route::get(‘/’, [HogeController::class, ‘index’])->name(‘index’); //PHP
public function index(Request $request, Response $response){… //PHP
(どれを使ってもサーバサイドが実現できる)
Software Design 2021年5月号 PHP 8移行のタイミングとコツ コーディング,JITコンパイラ,フレームワークの3点で考える
https://gihyo.jp/magazine/SD/archive/2021/202105
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 2018.6
https://www.sbcr.jp/product/4797393163/

その他の参考URL:
ECサイト Laravel、でググった:
https://qiita.com/neneta0921/items/f99fc0d2c6e9600604e7
https://qiita.com/motuo/items/08b7d6ef92498034b58d
https://www.udemy.com/course/laravel-multi-ec/?couponCode=ST11MT91624B
(BladeComponentを活用したView画面作成方法、LaravelBreezeを活用した認証機能、Laravelでのマルチログイン環境構築、Tailwindcssを使ったモダンな画面作成方法、画像アップロード, リレーションなど、ダミーデータ設定、stripeを使った決済方法、MicromodalJsやSwiperJsなどのJSライブラリの設定)
\
EC-CUBE入れた方が色々と都合がよいってなるかもしれないので、EC-CUBEも参考にする。(後回し)
ec-cube デザインテンプレート 無料、でググった:
https://shuukyakudesign.com/content64
https://designup.jp/eccube4-theme-develop.html
https://qiita.com/xinome/items/35ae5237e5dd94c9fa2b
\
.htaccess php、でググった:
.htaccessでPHPの設定 – PHP で WEB作成
https://php-web.net/web/php-htaccess.html
(FC2ホームページで無料でWordPressが使えるというので、PHP使えるか試すのに参考にした)
html form method dialog、でググった:
たまたまformのmethodの入力をしていたらVSCodeの補完機能でdialogと出たが、https://html-coding.co.jp/annex/dictionary/html/form/ に無い、html5か?
https://developer.mozilla.org/ja/docs/Web/HTML/Element/dialog global属性だった。https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes やっぱ補完機能あると助かる。
php バリデーション とは、でググった:
https://techacademy.jp/magazine/49322
そこでPHP等のプログラミング言語を使ってデータを処理することになりますが、送信データが正しい形式のデータであるかどうかや想定した文字数の範囲か、適切なデータ型なのかをチェックするのがバリデーション機能です。2019/12/05
mysql utf8mb4_unicode_ci vs utf8_unicode_ci、でググった:
https://gomiba.co/archives/2017/08/938/
MySQL の UTF-8 は 3 バイトの幅しかなく、絵文字などを表現するためには 4 バイトが必要。きっと歴史的な背景から utf8 と utf8mb4 が分裂している。
https://qiita.com/tfunato/items/e48ad0a37b8244a788f6
MySQLの文字コードはこれからはutf8mb4一択のようです。
\
PHPフレームワークのまとめ【2023年版】 (2023.09)
https://freelance-start.com/articles/70#title9
CakePHPは、Ruby on Railsの影響を強く受けており,Webアプリケーションを高速に開発出来ます。
CakePHPとLaravelはどっちがおすすめ?違いやメリットデメリットを比較
https://www.sejuku.net/blog/126976
徹底比較!バックエンドフレームワーク5選(Web開発)
https://www.crunchtimer.jp/blog/16586#%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF_%E4%BA%BA%E6%B0%97%E3%83%A9%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0
(Laravelは小規模向けらしい。Express、Laravel、Flask)
\
PEARとは?:(2024.09)
PEAR (PHP Extension and Application Repository) とは、PHPのためのフレームワークおよび再利用可能なコンポーネントのリポジトリです。PEARは、PHPでの開発を効率化するために、パッケージ(モジュール)を提供し、開発者が共通の機能を簡単に利用できるようにするための仕組みです。
pearコマンドを使ってパッケージをインストール、更新、削除ができます。Composerが普及する以前、PHPプロジェクトで依存パッケージを管理するために一般的に使われていました。
現在ではPHPのパッケージ管理としてはComposerが主流になっており、PEARの利用は減少しています。しかし、PEARは一部のレガシーシステムや古いPHPプロジェクトで依然として使用されています。
\
php ファイルサーバ 作り方、でググった:(2023.11)
https://blow-in.net/blog/entry-1246.html
\
PHPをコマンド実行:(2025.10)
https://shirakawa.weblike.jp/blog-page/2022/01/30…

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です