- 投稿日:2019-05-22T23:27:32+09:00
【個人用】Laravel5.5 初開発メモ①
用途
- 開発中に調べたことをメモしてた(雑です)
- 限定公開に埋もれ出したので、公開する
- Laravel 5.5
- 困った時に見てる
設計
- 外部キーにユニーク制約が必要でないか調べる
FormHelper
RadioButton
CheckBox
だいたいこんな感じで進むと思われる
1) make migration 2) make model 3) make factory 4) make seeder 5) make controller 6) make blade 7) make routing 8) make RequestForm 9) make logic 10) testing api & validationDone!
実装・修正箇所の探し方
Controllerから探す
①Controller見る
②Routingを見る
③Blade見るViewから探す
①Routingから見る
②Controller探す
or
①Grepかける使ったライブラリ
- barryvdh/laravel-debugbar => デバッガー
- FriendsOfPHP/PHP-CS-Fixer => コード解析&修正
Composer
dump-autoload
- とりあえず、クラス等のロードが早くなるイメージ
Migrate
$ php artisan make:migration create_users_tableint、bigint、smallint、および tinyint (Transact-SQL)
- TinyIntにunsignedは要らない
- intは-2からなのでいる
Eloquent(Model)
- Migrationファイルと一緒に生成することもできる。
論理削除
$ php artisan make:model UserSeeder
- SeederでFactory使うときは、呼び出す
$ php artisan make:seeder UsersTableSeederFactory
$user = factory(User::class)->create(); # モデルの作成&保存 $user = factory(User::class)->make(); # モデルの作成$ php artisan make:factory PostFactoryFaker
- 出たものは出さないようにする
'user_id' => $faker->unique()->numberBetween(1, 50),Controller
Routing
Route::resource
Roure::resource('/email-template', 'EmailTemplateController');
- ルートの確認
$ php artisan route:list名前付きルート
バリデーション
- おそらく、sizeとmaxの違いは、文字数かKBの違い
フォームリクエストバリデーション
$ php artisan make:request StoreBlogPost
- return=falseでrulesがからの場合、the action is unconciousになる
検索のバリデーション
- 検索のバリデーションも考慮する。
- name属性がちゃんと指定されているか、確認する
name="title" #いける title="title" #grepかけて、直すとミスる時がある。PHPUnit
Generate
// Featureディレクトリにテストを生成する(Controller) $ php artisan make:test StaffControllerTest // Unitディレクトリにテストを生成する(Model) $ php artisan make:test StaffTest --unitExecute
$ ./vendor/bin/phpunit // 全体のテスト $ ./vendor/bin/phpunit tests/Feature // Featureのテスト $ ./vendor/bin/phpunit tests/Unit // UnitのテストPoint of view
Feature Test(Controller)
- Testing APIUnit Test(Model etc)
- Testing ValidationTips
- Laravel 5.3 データベースのテスト
- 属性のオーバーライド、ステート、DBのリフレッシュあたりは押さえておきたい
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\DatabaseMigrations;
- Docker内だと、セッション開始がテスト時に実行されないケースがあるので、明示的に開始する
use DatabaseMigrations; use WithFaker; protected function setUp() { parent::setUp(); Session::start(); }FormHelper
Form::open{{ Form::open(['route' => array('email-template.update', $email_template->id), 'method' => 'post']) }} {{ method_field('PUT') }} @include('email_template.partials.form')Mailer
- 設定の変更
$ cp .env.example .env
- 再読み込み
$ php artisan config:cache
- generate
$ php artisan make:mail UserPasswordResetMail
- Error
Class 'App\Http\Controllers\Mail' not found
- HTMLの命名規則はケバブケース
=> password-reset.blade.php
namespaceについて
form request validation
フォームのバリデーション設定
パスワードリセット機能を作る
laravel str_randomは安全ですか? - 文字列、laravel、URL、ランダム
CSRF の安全なトークンの作成方法
[Laravel]メール認証を使った会員登録- メールで初期パスワードを平文で送るの大丈夫か??
ルーティング
Viewに値を渡す
[laravel] controllerからviewへの変数の受け渡しとその展開方法
RequestFormによるバリデーション
ORM
- where(※一件だけ取得する)
$user = User::where('email', $request->email)->first();HTTPレスポンス
フラッシュメッセージ
trans
日付処理
Laravelで日付関連の処理を行うCarbonを使ってみる
複数の変数を引数で渡す
php – Laravel – 複数の変数を渡して表示する
- 取り出し方$user->name = $data['user_info']['name'];405: ルーティング定義漏れ
419: CSRF対策漏れハッシュ化と暗号化
Laravel 5.6 ハッシュ
Laravel 5.5 暗号化コメント
@section('script') <script> (function ($) { /* --------------------------------------------------- // character count -----------------------------------------------------*/ (function () { $('textarea').on('keyup', function() { const len = $(this).val().length; if (len > 1000) { $(this).val($(this).val().substring(0, 999)); } else { $(this).next('span').text(len + '/1000文字'); } })
- 投稿日:2019-05-22T19:09:53+09:00
ArrayAccessでコード補完(PhpStormネタ)
ArrayAccessを使うとオブジェクトを配列のように使えます。その際、いくつかメソッドを追加するのですが、返り値を指定することができます。
こんなコード。/** * @param mixed $offset * @return Hi */ public function offsetGet($offset) { .... }するとコード補完ができた。
この「
e()」が補完したいメソッド。なお、
$thisではだめだった。
PhpStormのバージョンは2019.1を利用。コード
一応、クラスとコード。
class Hi implements ArrayAccess { private $hi = ''; public function e() { return $this->hi; } /** * @param mixed $offset * @return Hi */ public function offsetGet($offset) { $this->hi .= $offset; return $this; } public function offsetSet($offset, $value) {} public function offsetUnset($offset) {} public function offsetExists($offset) { return false; } } $hi = new Hi(); echo $hi['h']['i']->e();
- 投稿日:2019-05-22T18:00:13+09:00
php-pecl-mysql-xdevapiをインストールするとApacheのリロードに失敗する問題
はじめに
PHPのモジュールで、php-pecl-mysql-xdevapiをインストールしてから
Apacheが決まった時間帯に勝手に落ちる現象が発生していたので
その原因と対策について投稿してみます。環境
CentOS Linux release 7.6.1810 (Core)
Server version: Apache/2.4.6 (CentOS)
PHP 7.3.5 (cli)決まった時間に落ちるのでcronを確認
/var/log/cron をみてみる。
run-parts(/etc/cron.daily)[21871]: starting logrotate run-parts(/etc/cron.daily)[21891]: finished logrotatecron.dailyでlogrotateが動いている。
/var/log/httpd/配下のログを確認すると、Apacheが落ちるタイミングで
ログがローテートされている。ログローテート設定の確認
/var/logrotate.d/httpd の中身を確認してみると
/var/log/httpd/*log { missingok notifempty sharedscripts compress delaycompress postrotate create 0644 /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true endscript }ログローテートの際に、systemctl reload httpd が実行されている。
リロードの際にApacheが落ちてる模様Apacheのログを確認
落ちた時間付近の /var/log/httpd/error_log に気になるログが...
PHP Fatal error: Class mysql_xdevapi\\XSession cannot extend from interface CURLMOPT_MAXCONNECTS in Unknown on line 0 [core:notice] [pid 17512] AH00060: seg fault or similar nasty error detected in the parent processphp-pecl-mysql-xdevapiが原因っぽいログがでてる。
どうやらこのモジュールが原因でリロードした際にApacheが起動してこない模様Apacheをリロードしてみる
systemctl reload httpdやはりApacheが起動してこない...
ログをみると先ほど出ていたログと同様のログがでてる。php-pecl-mysql-xdevapiを削除してみる
yum remove php-pecl-mysql-xdevapi削除!
再度Apacheをリロードしてみる
systemctl restart httpd一回リスタートかけてリロード実施!
systemctl reload httpdApacheが落ちてない!
php-pecl-mysql-xdevapiをインストールした状態でApacheをリロードすると
Apacheが立ち上がらなくなる模様対策
1.そもそもphp-pecl-mysql-xdevapiを使用しない
2.restartなら問題なく起動するので
/etc/logrotate.d/httpd のreload部分をrestartに変更することで
問題なく起動する。
ただし、ログローテートの度にApacheのリスタートが実施される。3.ローテートの設定を下記のように、postrotateとendscriptの間を
copytruncateに変更するとリロードなくログローテートが行える。/var/log/httpd/*log { missingok notifempty sharedscripts compress delaycompress postrotate copytruncate endscript }copytruncateはリロードなくログローテートできるが、ローテート最中にきた
アクセスについては記録できないとのことおわりに
エンジニアになり1年たったので、たまにはこうやって記事書いたりしていこうと
思います。(たぶん)
- 投稿日:2019-05-22T17:54:41+09:00
phpのselenium-webdriverでCSSセレクタを使う方法
正直、CENT OS7でPHPから動くするようにするまでがぼちぼち大変でございました。
まあ、動けば楽勝と思ったのですが・・・、セレクタの指定で若干迷ってしまったのでメモ。cssSelectorを利用して子を検索指定ができる。
$driver->wait()->until( WebDriverExpectedCondition::elementToBeClickable(WebDriverBy::cssSelector(".break_time_timer .-start")) ); $driver->findElement(WebDriverBy::cssSelector(".break_time_timer .-start"))->click();チート見りゃすぐわかったんだけど、リファレンスがわかりにくかったので悩んでしまった。
https://gist.github.com/aczietlow/7c4834f79a7afd920d8f
- 投稿日:2019-05-22T17:44:06+09:00
Lalavelでのログイン機能実装にあたって罠にはまった
背景
Laravel5.8でコマンド「php artisan make:Auth」でログイン機能やら登録画面やら一撃実装できることを知って、
感動してたときのことです。やっぱり自分流にカスタマイズしたい
そう思うでしょう?
罠
登録画面をカスタマイズ、DBにテーブルも準備してユーザ登録されることも確認!いざ!ログイン!
だがしかし、IDとパスワードを入れてログインボタンを押すと、永遠にログイン画面にリダイレクトされる。。。
今回の問題点
僕は数行前でIDとパスワードを入れてログインボタンを押すといった。
そう、IDとパスワード。
そう、IDこれだ。
改善
コマンドで一撃実装をすると、ログイン画面で入力するフォームは
・password
となっている。このe-mailのフィールドをblade上でidに書き換えるだけではだめだったのである。
ここで公式のドキュメントを見てみる。
[ユーザー名のカスタマイズ]の項目を見ると、どうやらLoginController内にてusernameメソッドを定義する必要があったようだ。
こんな感じで定義してやると、ログインできる。
もちろん、bladeのフィールド名はちゃんと書き換えてくれ。
公式のドキュメント見たら済むお話をわざわざ記事にしてしまった自分が情けない。。。。
- 投稿日:2019-05-22T15:31:49+09:00
Laravelでヘルパー乱用をしてグローバル汚染するのを避ける提案
Laravelでviewのロジックを切り出したいときにhelperは便利
以下のように定義してしまえば、どこからでも呼び出せる
viewロジックをまとめられた!!となるが、
どこからでも呼び出せてしまうという問題も同時におきている。if (!function_exists('normalizeAge')) { /** * 年齢から 10代前半 の表記に丸めた文字列を返す * @param int $age 年齢 * @return string 10代前半など年代を丸めた文字列 */ function normalizeAge($age) { if (empty($age)) { return '年齢 未回答'; } return getTensPlace($age) . '代' . (isEarlyAge($age) ? '前半' : '後半'); } }そこでviewテンプレートのBladeの構文解析器を拡張する(directive追加)
Controller側でこれを定義しておくことで、そのControllerを用いた時だけ使える
viewテンプレートで利用可能な構文が追加される。Blade::directive('normalizeAge', function ($age) { if (empty($age)) { return "<?php echo 年齢、未回答; ?>"; } return "<?php echo getTensPlace($age) . '代' . (isEarlyAge($age) ? '前半' : '後半') ?>"; });使い方
bladeテンプレートファイルで @if や @foreach のように記述するだけ
@normalizeAge(14)このようにすることでグローバル汚染を防ぎつつ、viewで使えるロジックを定義できるのではないかと思った。
いや、普通に違う方法あるでしょというベストアンサーお待ちしてます。
- 投稿日:2019-05-22T13:58:40+09:00
php-master-changes 2019-05-21
今日は opcache のバグ修正、テストの修正、stream コンテキストオプション content_type のサポート追加を 7.2 系へのバックポート、一部拡張の共有ライブラリのビルド修正があった!
2019-05-21
dstogov: Fixed bug #78014 (Preloaded classes may depend on non-preloaded classes due to unresolved consts)
- https://github.com/php/php-src/commit/f53b9939fe4f66e1a539a42d607fefbe45be6239
- [7.4~]
- ext/opcache で、未解決定数により preload されないクラスへ依存したクラスを誤って preload してしまう問題の修正
dstogov: Prevent race condition in opcache_reset()
- https://github.com/php/php-src/commit/a8a019d68a605dd2b699174dd7f55d6e8bbaeee6
- [7.2~]
- ext/opcache で、opcache_reset() の race を修正
hollyhuiLi: use {TMP} placeholder in phpt tests
- https://github.com/php/php-src/commit/202e6936d6fa319fdda16c5c61d70ce19c2ecef6
- [7.2~]
- テストで
{TMP}を使うよう修正vjardinMisc: Support content_type stream context option in soap
- https://github.com/php/php-src/commit/5f8c22d41536768298354218fe238691ae750f75
- [7.2~]
- ext/soap で、先日 7.4 系以降へ入った stream コンテキストオプション content_type のサポート追加を 7.2 系へバックポート
cmb69: Prevent test case failure
- https://github.com/php/php-src/commit/e6a191de1b73c902b631cb8f0f70ed58b81005d4
- [7.2~]
- ext/opcache で、ログ出力によるテストこけの修正
remicollet: fix typo breaking shared build
- https://github.com/php/php-src/commit/24206783c3cf2e41e0895ab04e8f59b8092f476a
- [7.4~]
- ext/sqlite3 で、共有ライブラリビルド時エラーになる typo の修正
cmb69: Fix ASLR related invalid opline handler issues
- https://github.com/php/php-src/commit/8ba10b8fbc020dc225d3b19d8f088f1351a3e304
- [7.4~]
- ext/opcache で、Windows で ASLR により共有メモリ上の opline handler が正しいポインタにならず正常動作しない場合がある問題の修正
- PR:4170 の奴、execute_ex のアドレス見てロード先を判定してファイルキャッシュにフォールバックしたりするみたい
remicollet: enchant: fix shared build
- https://github.com/php/php-src/commit/1f8b9b8de6f04b28ba5b1019863615c58489f437
- ext/enchant で、共有ライブラリのビルドを修正
remicollet: sodium: fix shared build
- https://github.com/php/php-src/commit/9ef03a94ba68be0f8bae36f46c4763ba3c88a02a
- [7.4~]
- ext/sodium で、共有ライブラリのビルドを修正
nikic: Improve SCCP debug code
- https://github.com/php/php-src/commit/367788cbc37d54f6f77ac3785c2de612d9fdc36d
- [7.3~]
- ext/opcache で、SCCP のデバッグコードを改善
nikic: Extract ct_eval_binary_op()
- https://github.com/php/php-src/commit/bdce5849b7866132097b8730f695fa2ead133019
- [7.3~]
- ext/opcache で、ct_eval_binary_op() の関数切り出し
- オペランドが partial array でなければ zend_optimizer_eval_binary_op() を呼ぶ挙動
nikic: Handle partial arrays in zend_is_true() checks
- https://github.com/php/php-src/commit/cd188d0398923fa4d49d45db3be3530598ac78d2
- [7.3~]
- ext/opcache で、SCCP 最適化の際に zend_is_true() を呼んでいた箇所で partial array のチェックをするよう関数切り出しして修正
nikic: Fix partial array handling in FE_RESET edge feasibility
- https://github.com/php/php-src/commit/fc4836b193666958844e50bc35b93cc2da08b91c
- [7.3~]
- ext/opcache で、SCCP 最適化の際の partial array のチェックを追加
- 投稿日:2019-05-22T08:40:14+09:00
XAMPPでPHP開発環境構築(XAMPPインストール〜複数サイトの運用を考慮した設定まで)
概要
- 案件でPHP開発環境を構築する必要があった
- 本番環境と同じ(HTML等はもちろんこと、JS、PHP)ソースが動作する環境を作るための手順書
- また、ざっくりとしたXAMPP周りの知識を収集したメモあり。
- 基本的には、XAMPPインストールでソースを配置し、表示が確認できれば完了。今回は、今後のことも考慮し、複数サイトの開発にも耐えられる環境の構築まで行い完了。
事前準備
- 事前準備は、不要。
- OSは、Windowsで進行。
事前知識
XAMPPとは
参考:https://ja.wikipedia.org/wiki/XAMPP
- 最も人気のあるPHP開発環境(オープンソースパッケージ)
- 開発用・学習用として優れている。
- XAMPPは、下記主要ソフトウェアを一括してインストールして、すぐに開発や運用が開始できる。
- Apache(Webサーバソフトウェア)
- MariaDB(リレーショナルデータベースマネジメントシステム)
- Perl(プログラミング言語)
- phpMyAdmin(データベース接続クライアント)
- SQLite(軽量なリレーショナルデータベースマネジメントシステム)
- つまり、Webサーバ + RDB(データベース) + phpMyAdmin(データベースにブラウザ接続)を一括インストールして、すぐに開発できる環境を構築してくれる。
XAMPPの名前の由来
- X・・・Windows、Linux、macOS、Solarisのクロスプラットフォーム
- A・・・ApecheのA
- M・・・MariaDB(旧バージョンはMySQL)のM
- P・・・PHPのP
- P・・・PerlのP
作業内容
XAMPPのインストール
- 公式サイト( https://www.apachefriends.org/jp/index.html )よりインストール
- 特に、デフォルトのままNextで進みインストールまで終わらせる。
XAMPPインストール時にインストールされるソフトウェア群
XAMPPインストール直後、主要ソフトウェアのバージョン確認
C:\xampp直下のreadme_en.txtを読むと、そこに全てのバージョンが書いてあった。
readme_en.txt一部抜粋(参考程度に)XAMPP:7.3.5 Apache:2.4.39 MariaDB:10.1.40 PHP:7.3.5 phpMyAdmin:4.8.5 Strawberry Perl(MS Windows用のperl環境):5.16.3.1
- 念の為、
readme_en.txtが最新なのかどうか不安なのでコマンドを叩いて確認。- 直接コマンドプロンプトから、バージョン確認コマンドを叩いても認識されないので
XAMPPのShellからコマンドを叩く必要があります。
XAMPPのShellは、XAMPP Control PanelのShellボタンから開けます。
XAMPPのShellからコマンドで確認。一部抜粋(参考程度に)XAMPP:コマンドはなさそう?? Apache:2.4.39 MariaDB:10.1.40 PHP:7.3.5 phpMyAdmin:コマンドはなさそう?? Strawberry Perl(MS Windows用のperl環境):5.16.3
- 結果、
readme_en.txtのバージョンと相違がなく、readme_en.txtのバージョンを正として進めても良さそう。Apacheを起動し、http://localhost/ にアクセス
- ローカルサーバを起動する。
- XAMPP Control Panel > Apache > Start
- http://localhost/ にアクセス
- デフォルトは、http://localhost/dashboard/ にリダイレクトされる。
複数サイトの運用を考慮した設定
- 基本は、
C:\xampp\htdocsにフォルダ(例:プロジェクトA)を配置すれば、http://localhost/プロジェクトA にアクセスすることで、サイトが表示される。ただし、このままだと
- ドキュメントルートが、デフォルトだと
C:/xampp/htdocsのため、ソースに/img/aaa.jpgや/info/form/index.htmlなどと記述されていると、画像切れやリンクが正しく飛ばない。- 複数サイト毎にプロジェクトのディレクトリを作成し、プロジェクト毎にドキュメントルートを設定したいときに困る
ので、
XAMPPで複数のサイトのテストサーバーを作ってみました(バーチャルホスト)を参考に設定しました。
参考サイトでは、3つのプロジェクト(サイト)運用時の例だったので、私は1つのプロジェクトだけ同じように設定をしました。
事後確認&作業
Apacheを再起動し、http://localhost/プロジェクト名 にアクセス
- ローカルサーバを再起動する。
- XAMPP Control Panel > Apache > Stop → Start
- http://localhost/プロジェクト名 にアクセス
これで、画像・リンク切れ等がなければ完了です。
ルート相対パスで記述されていた箇所も正しいドキュメントルートを基準に読み込むため、画像切れやリンク切れの問題が解決しました。
まとめ
- ほぼ、XAMPPをインストールしてしまえば、簡単にPHP開発環境が作れたので、やはり有名なだけあるなと思いました。
- 複数サイトを考慮した構築は、初めてでしたが設定ファイルを書き換えれしまえばすぐに反映&いろんな設定ができるので良いですね。特に、バーチャルホスト機能は良い!
- JSPを動かすTomcat(Webコンテナ)が入っていたのは驚き(笑)
- 多分、本番のソースによっては、JSがエラーや正しい挙動をしてくれず、完了と言えない人(私です・・・)はいると思いますが、ひとまず汎用的な設定はここまでです。
- 投稿日:2019-05-22T00:16:16+09:00
【Laravel】コレクションのgroupByメソッド 練習問題3問(初心者向け)
はじめに
Laravelのコレクションの便利なメソッド
groupBy。あれこれ触ったので、覚えたことを忘れないよう、練習問題にしてみました。
問題
Order,OrderDetail,Book,Publisherモデルがあり、OrderDetailからリレーションのあるBook,Publisherまでを以下のように取得しました。$order_details = OrderDetail::with('book.publisher')->get(); print_r(json_encode($order_details, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))$order_detailsをJSON化したもの[ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } }, { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ]問1
publisher_idでgroupByしてください。問2
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22){ "11": [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], "22": [ { "id": 10002, "order_id": 1, "book_id": 222, //略これを
0から振り直してください。(JSON化した場合、以下のように出力されるようにしてください)[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, //略問3
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。補足
必要に応じてLaravel公式ドキュメントの
groupByほかを参照してください。
https://readouble.com/laravel/5.8/ja/collections.html#method-groupbyここから先、解答になります。
...
...
...
解答
問1の解答
publisher_idでgroupByしてください。
publisher_idは、bookをキーとする値の中に、さらにキーとして存在していました。$order_detailsをJSON化したものの抜粋"book": { "id": 111, "publisher_id": 11,こういった場合は、
.で繋いで指定すればOKです。問1の解答例$answer1 = $order_details->groupBy('book.publisher_id');問1の別解$answer1 = $order_details->groupBy('book.publisher.id');問2の解答
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22)
これを0から振り直してください。キーの振り直しにはコレクションのメソッドである
valuesが使えます。valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。
Laravel5.8 公式ドキュメント - values
https://readouble.com/laravel/5.8/ja/collections.html#method-values問2の解答例$answer2 = $order_details->groupBy('book.publisher_id') ->values();問2の解答例の結果をJSON化したもの[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ]問3の解答
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。こういった場合は、同じくコレクションのメソッドである
transformの利用が考えられます。transformメソッドはコレクションを繰り返し処理し、コレクションの各アイテムに指定したコールバックを適用します。コレクション中のアイテムはコールバックから返される値に置き換わります。
Laravel5.8 公式ドキュメント - transform
https://readouble.com/laravel/5.8/ja/collections.html#method-transform
is_electronic_bookでgroupByした結果、2つの要素に分かれていますので、各々の要素に対してさらにpublisher_idでgroupByします。問3の解答例$answer3 = $order_details->groupBy('book.is_electronic_book') ->transform(function ($order_detail) { return $order_detail->groupBy('book.publisher_id') ->values(); });問3の解答例の結果をJSON化したもの[ [ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ], [ [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } } ] ] ]最後に
以上です。何問解けたでしょうか?
コレクションメソッドを使っていて、また何か気付きがあれば練習問題にしてみたいと思います
参考
- 投稿日:2019-05-22T00:16:16+09:00
Laravelコレクションメソッド groupBy練習問題3問(初心者向け)
はじめに
Laravelのコレクションの便利なメソッド
groupBy。あれこれ触ったので、覚えたことを忘れないよう、練習問題にしてみました。
問題
Order,OrderDetail,Book,Publisherモデルがあり、OrderDetailからリレーションのあるBook,Publisherまでを以下のように取得しました。$order_details = OrderDetail::with('book.publisher')->get(); print_r(json_encode($order_details, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))$order_detailsをJSON化したもの[ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } }, { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ]問1
publisher_idでgroupByしてください。問2
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22){ "11": [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], "22": [ { "id": 10002, "order_id": 1, "book_id": 222, //略これを
0から振り直してください。(JSON化した場合、以下のように出力されるようにしてください)[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, //略問3
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。補足
必要に応じてLaravel公式ドキュメントの
groupByほかを参照してください。
https://readouble.com/laravel/5.8/ja/collections.html#method-groupbyここから先、解答になります。
...
...
...
解答
問1の解答
publisher_idでgroupByしてください。
publisher_idは、bookをキーとする値の中に、さらにキーとして存在していました。$order_detailsをJSON化したものの抜粋"book": { "id": 111, "publisher_id": 11,こういった場合は、
.で繋いで指定すればOKです。問1の解答例$answer1 = $order_details->groupBy('book.publisher_id');問1の別解$answer1 = $order_details->groupBy('book.publisher.id');問2の解答
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22)
これを0から振り直してください。キーの振り直しにはコレクションのメソッドである
valuesが使えます。valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。
Laravel5.8 公式ドキュメント - values
https://readouble.com/laravel/5.8/ja/collections.html#method-values問2の解答例$answer2 = $order_details->groupBy('book.publisher_id') ->values();問2の解答例の結果をJSON化したもの[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ]問3の解答
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。こういった場合は、同じくコレクションのメソッドである
transformの利用が考えられます。transformメソッドはコレクションを繰り返し処理し、コレクションの各アイテムに指定したコールバックを適用します。コレクション中のアイテムはコールバックから返される値に置き換わります。
Laravel5.8 公式ドキュメント - transform
https://readouble.com/laravel/5.8/ja/collections.html#method-transform
is_electronic_bookでgroupByした結果、2つの要素に分かれていますので、各々の要素に対してさらにpublisher_idでgroupByします。問3の解答例$answer3 = $order_details->groupBy('book.is_electronic_book') ->transform(function ($order_detail) { return $order_detail->groupBy('book.publisher_id') ->values(); });問3の解答例の結果をJSON化したもの[ [ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ], [ [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } } ] ] ]最後に
以上です。何問解けたでしょうか?
コレクションメソッドを使っていて、また何か気付きがあれば練習問題にしてみたいと思います
参考
- 投稿日:2019-05-22T00:16:16+09:00
Laravelコレクションメソッド groupByを重ねて複数使う (練習問題形式)
はじめに
Laravelのコレクションの便利なメソッド
groupBy。あれこれ触ったので、覚えたことを忘れないよう、練習問題にしてみました。
タイトルの、groupByを重ねて複数使う、最後の問3です。
問題
Order,OrderDetail,Book,Publisherモデルがあり、OrderDetailからリレーションのあるBook,Publisherまでを以下のように取得しました。$order_details = OrderDetail::with('book.publisher')->get(); print_r(json_encode($order_details, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))$order_detailsをJSON化したもの[ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } }, { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ]問1
publisher_idでgroupByしてください。問2
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22){ "11": [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], "22": [ { "id": 10002, "order_id": 1, "book_id": 222, //略これを
0から振り直してください。(JSON化した場合、以下のように出力されるようにしてください)[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, //略問3
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。補足
必要に応じてLaravel公式ドキュメントの
groupByほかを参照してください。
https://readouble.com/laravel/5.8/ja/collections.html#method-groupbyここから先、解答になります。
...
...
...
解答
問1の解答
publisher_idでgroupByしてください。
publisher_idは、bookをキーとする値の中に、さらにキーとして存在していました。$order_detailsをJSON化したものの抜粋"book": { "id": 111, "publisher_id": 11,こういった場合は、
.で繋いで指定すればOKです。問1の解答例$answer1 = $order_details->groupBy('book.publisher_id');問1の別解$answer1 = $order_details->groupBy('book.publisher.id');問2の解答
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22)
これを0から振り直してください。キーの振り直しにはコレクションのメソッドである
valuesが使えます。valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。
Laravel5.8 公式ドキュメント - values
https://readouble.com/laravel/5.8/ja/collections.html#method-values問2の解答例$answer2 = $order_details->groupBy('book.publisher_id') ->values();問2の解答例の結果をJSON化したもの[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ]問3の解答
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。こういった場合は、同じくコレクションのメソッドである
transformの利用が考えられます。transformメソッドはコレクションを繰り返し処理し、コレクションの各アイテムに指定したコールバックを適用します。コレクション中のアイテムはコールバックから返される値に置き換わります。
Laravel5.8 公式ドキュメント - transform
https://readouble.com/laravel/5.8/ja/collections.html#method-transform
is_electronic_bookでgroupByした結果、2つの要素に分かれていますので、各々の要素に対してさらにpublisher_idでgroupByします。問3の解答例$answer3 = $order_details->groupBy('book.is_electronic_book') ->transform(function ($order_detail) { return $order_detail->groupBy('book.publisher_id') ->values(); });問3の解答例の結果をJSON化したもの[ [ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ], [ [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } } ] ] ]最後に
以上です。何問解けたでしょうか?
コレクションメソッドを使っていて、また何か気付きがあれば練習問題にしてみたいと思います
参考
- 投稿日:2019-05-22T00:16:16+09:00
Laravelコレクションメソッド groupByを重ねて複数使うには? (練習問題形式)
はじめに
Laravelのコレクションの便利なメソッド
groupBy。あれこれ触ったので、覚えたことを忘れないよう、練習問題にしてみました。
タイトルの、groupByを重ねて複数使う、最後の問3です。
すぐにやり方を知りたいという方はこちらへどうぞ。問題
Order,OrderDetail,Book,Publisherモデルがあり、OrderDetailからリレーションのあるBook,Publisherまでを以下のように取得しました。$order_details = OrderDetail::with('book.publisher')->get(); print_r(json_encode($order_details, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))$order_detailsをJSON化したもの[ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } }, { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ]問1
publisher_idでgroupByしてください。問2
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22){ "11": [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], "22": [ { "id": 10002, "order_id": 1, "book_id": 222, //略これを
0から振り直してください。(JSON化した場合、以下のように出力されるようにしてください)[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, //略問3
まず、
is_electronic_bookでgroupByし、その上でそれぞれの要素に対して、publisher_idでgroupByしてください。補足
必要に応じてLaravel公式ドキュメントの
groupByほかを参照してください。
https://readouble.com/laravel/5.8/ja/collections.html#method-groupbyここから先、解答になります。
...
...
...
解答
問1の解答
publisher_idでgroupByしてください。
publisher_idは、bookをキーとする値の中に、さらにキーとして存在していました。$order_detailsをJSON化したものの抜粋"book": { "id": 111, "publisher_id": 11,こういった場合は、
.で繋いで指定すればOKです。問1の解答例$answer1 = $order_details->groupBy('book.publisher_id');問1の別解$answer1 = $order_details->groupBy('book.publisher.id');問2の解答
問1の結果では、グループ化された配列のキーは
publisher_idの値になります。(11や22)
これを0から振り直してください。キーの振り直しにはコレクションのメソッドである
valuesが使えます。valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。
Laravel5.8 公式ドキュメント - values
https://readouble.com/laravel/5.8/ja/collections.html#method-values問2の解答例$answer2 = $order_details->groupBy('book.publisher_id') ->values();問2の解答例の結果をJSON化したもの[ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } }, { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ]問3の解答
groupByを重ねて複数使うには、同じくコレクションのメソッドであるtransformも利用することが考えられます。問3の解答例$answer3 = $order_details->groupBy('book.is_electronic_book') ->transform(function ($order_detail) { return $order_detail->groupBy('book.publisher_id') ->values(); // valuesは用途に応じてお好みで。詳細は問2参照。 });transformメソッドはコレクションを繰り返し処理し、コレクションの各アイテムに指定したコールバックを適用します。コレクション中のアイテムはコールバックから返される値に置き換わります。
Laravel5.8 公式ドキュメント - transform
https://readouble.com/laravel/5.8/ja/collections.html#method-transform解答例では
is_electronic_bookでgroupByした結果、2つの要素に分かれていますので、このtransformを使って各々の要素に対してさらにpublisher_idでgroupByしています。問3の解答例の結果をJSON化したもの[ [ [ { "id": 10001, "order_id": 1, "book_id": 111, "selling_price": 3000, "book": { "id": 111, "publisher_id": 11, "name": "自習Laravel", "list_price": 3500, "is_electronic_book": false, "publisher": { "id": 11, "name": "AA出版" } } } ], [ { "id": 10003, "order_id": 1, "book_id": 333, "selling_price": 3000, "book": { "id": 333, "publisher_id": 22, "name": "パーフェクトLaravel", "list_price": 3000, "is_electronic_book": false, "publisher": { "id": 22, "name": "BB出版" } } } ] ], [ [ { "id": 10002, "order_id": 1, "book_id": 222, "selling_price": 2500, "book": { "id": 222, "publisher_id": 22, "name": "基礎から学ぶPHP", "list_price": 3000, "is_electronic_book": true, "publisher": { "id": 22, "name": "BB出版" } } } ] ] ]最後に
以上です。何問解けたでしょうか?
コレクションメソッドを使っていて、また何か気付きがあれば練習問題にしてみたいと思います
参考
- 投稿日:2019-05-22T00:09:09+09:00
[PHP その1]LAMP環境とは?
物事を知るには大枠から知ろう
プログラムについて新しく勉強するときは、初めにその言語がどんな目的で使用されるのか知ると非常に効率が上がると思う。おそらく言語を数多く学んでいる人は過去に学習したことのある似た用途の言語と無意識に照らし合わせながら学習すると思う。まあだいたい言語の説明がされている体系的な文章には書いてあることだろうと思うが。
だからまずはPHPがどんな目的で、どんな環境で使われているのかから知っていく。PHPはどんな目的で使用されるのか
PHP その0でも記述したため繰り返しとなるが、PHPとはサーバーサイドで動作するスクリプト言語である。このサーバーサイド言語であるという点とスクリプト言語であるという点から、以下のように使われる言語であることが想像できる。
- サーバーに対してユーザから[要求]が飛んでくる
- PHPが[要求]をサーバー上で処理する
- 何かしらの処理した結果をユーザに対して返却する
調べてみるとどうも正しそう。
スクリプト言語って言われたらこんなのか。
cmd.exe abc.batおそらく似たような感じで以下のように実行するのだろう
php.exe createReturnHTML.php要求に対してスクリプトを実行して結果となるhtmlを生成してリターンするのだ。
なるほど



