- 投稿日:2021-01-18T22:14:16+09:00
PHPとjqueryでJSON形式ではないAjax通信をする
先輩エンジニアさんから教えていただいたjson形式ではないAjax通信を行います。
html/jqueryは以下の通り。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> $(function() { $('#ajax_post').click(function () { var hogeValue = $('#hoge').val(); var someValue = $('#some').val(); $.ajax({ url: 'ajaxTest.php', type: 'post', data: "hoge="+hogeValue+"&some="+someValue }).done(function(data){ /* 通信成功時 */ $('#ajax_show').text(data); }).fail(function(data){ /* 通信失敗時 */ alert('通信失敗!'); }); }); }); </script> </head> <body> <input type="text" id="hoge"><br> <input type="text" id="some"><br> <input type="button" id="ajax_post" value="送信"> <p id="ajax_show"></p> </body> </html>json形式にするのって結構めんどくさいですよね。
いちいちjson形式にするほど大量のデータをやり取りしないときにいいと思います。
データベースとやり取りするときは結局Json形式で値は返ってきますが。
続いてphp。<?php $afterHoge = $_POST["hoge"]; $afterSome = $_POST["some"]; $afterWord = ""; $afterHoge .= '形式ではない'; $afterSome .= '通信成功!'; $afterWord = $afterHoge . $afterSome; echo $afterWord;!これで簡単にフォームの値のやり取りを行います。
送信ボタンを押すと…
ちゃんとphpを通って返ってきました。
- 投稿日:2021-01-18T21:15:46+09:00
谷藤賢一『いきなりはじめるPHPワクワク・ドキドキの入門教室』でPHPを勉強してみた(1)
仕事のため、PHPの勉強を始めた。
タイトル通り、私が勉強に使っているのは谷藤賢一『いきなりはじめるPHPワクワク・ドキドキの入門教室』だが買ってはいけない本を買った気がする……
この本では、学習を進めるためにXAMPP(ザンプ)というサーバーをダウンロードするよう書かれているが、この記事を書いている2021年1月時点でテキスト通りにいかないことがいくつかある。
ポートのチェックの設定変更ができない
XAMPPをダウンロードしたとき、パソコンにSkypeが入っている場合、ポートを奪い合ってXAMPPが起動しない。そのために本書では「Skypeの設定で、ポートのチェックを外してください」と書いてあるのだが、現在、Skypeの設定画面からポートのチェックを外すことはできない。インターネットを検索すればなんとかポートの変更はできるが、初学者向けの本でこれはどうかと思う。
テキスト通りにやってもエラーが出る
テキストに書いてあることをただやってるだけなのに、
「Server error!
サーバ内部で障害が発生し、 リクエストに応えることができませんでした。 サーバが過負荷であるか、 CGI スクリプトにエラーがあります。
サーバーの障害と思われる場合は、ウェブ管理者までご連絡ください。
Error 500
localhost
Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/5.6.24」というエラーが出る。
ヤフー知恵袋でも、私と同じところで躓いた人がいた。
「新しいテキストを買ったほうがいいんじゃないか……」と思ったが、【PHP】超優良入門書『いきなりはじめるPHP』をMAMPで完走するために知っておくべき5つのこと【Mac】
というサイトによると、MAMPをダウンロードすれば学習を進められるらしいのでMAMPをダウンロードした。今日はChapter3 ワクワク!プログラミング編の3-1から3-8まで進めた。
■追記
MANPをダウンロードし起動したあと、スタートを押してもstop serversにならず、接続できない場合は、Preferenes → PHPのタグを押し、「Standard Version」の初期設定がを7.3.7から、7.2.14 に変更すればいい。HTML 4.01だからdoctype宣言が長い。
段落を
でなく
と書いてるテキストはじめてみた。
- 投稿日:2021-01-18T20:47:54+09:00
Laravel6 + Vue.js + Laravel SanctumのSPA認証でのアクセス制限の簡単な実装。
自分用なのでざっくりと。
時間がある時にもっと詳しい記事を書きたい。例えばdashboardページへ未認証ユーザーがアクセスしようとするとログインページへリダイレクトさせたい場合。
routes/api.phpRoute::middleware('auth:sanctum')->get('/authenticated', function () { return 'authenticated'; });resources/js/app.jsimport VueRouter from 'vue-router'; import DashBoard from "./components/DashBoard"; import LoginComponent from "./components/LoginComponent"; //〜略〜 const router = new VueRouter({ mode: 'history', routes: [ { path: '/login', name: 'login', component: LoginComponent, }, { path: '/dashboard', name: 'dashboard', component: DashBoard, beforeEnter: (to, from, next) => { axios.get('/api/authenticated') .then((res) => { if (res.data == 'authenticated') { next(); } }).catch(() => { next({ name: 'login' }); }); }, }, ] }); //〜略〜このようにすれば良い。
おまけ
最初は、
routes/api.phpRoute::middleware('auth:sanctum')->get('/authenticated', function () { return true; });resources/js/app.jsimport VueRouter from 'vue-router'; import DashBoard from "./components/DashBoard"; import LoginComponent from "./components/LoginComponent"; //〜略〜 const router = new VueRouter({ mode: 'history', routes: [ { path: '/login', name: 'login', component: LoginComponent, }, { path: '/dashboard', name: 'dashboard', component: DashBoard, beforeEnter: (to, from, next) => { axios.get('/api/authenticated') .then(() => { next(); }).catch(() => { next({ name: 'login' }); }); }, }, ] }); //〜略〜ってやってみて、実際にログインしてdashboardページにアクセスしようとしたら、
The Response content must be a string or object implementing __toString(), \"boolean\" given.っていう「booleanじゃだめよ!」っていうエラーが出てうまくいかなかったんだよねえ。。
でもとある外国人のYouTube動画ではこのやり方でうまくいってたんだよねえ。。
どうしてなんだろう。
まだまだ勉強不足みたいです。。
- 投稿日:2021-01-18T18:33:17+09:00
【Laravel】 Sass(Scss)の使い方実例。Laravel Mixを使ってコンパイルする。
Laravel Mixというツールを使うとSassをCSSにコンパイルすることができる。
出力先のディレクトリ設定も超簡単。
目次
- Laravel Mixの機能
- Node.jsとnpmのインストール
- Laravel Mixのインストール
- コンパイル先の指定
- ファイルの作成
- コンパイルの実行
- ブラウザに表示
- 変更反映の自動化
- 本番用のコンパイル
- URLの自動変換機能(オフにする方法も)
- 複数ファイルをワイルドカードで指定する
Laravel Mixの機能
SassをCSSにコンパイルするだけでなく、Less, Stylus, PostCSSにも対応している。複数のcssファイルを1つのcssファイルに統合することもできる。
また、CSS以外にもJSの圧縮、.vue(ビューJS)、.jsx(リアクトJS)などのコンパイルにも対応している。
今回は、Sass -> CSS機能のみにフォーカス。
コンパイル手順
1. Node.jsとnpmのインストール
node -v #v12.18.3 npm -v #6.14.8バージョンが表示されればインストール済み。
ない場合は、node.js公式ページからダウンロード。
2. Laravel Mixのインストール
Laravelのプロジェクトを作成した時点でルートディレクトリ直下に
package.json
が存在する。ここにはnodeの依存パッケージが記述されており、以下コマンドで記載のパッケージをインストールする。
$npm install
package-lock.json
が作成されたらインストール完了。このファイルはインストール済みのnpmパッケージが記載されている。(自動生成されるファイルなので編集しない!)
$npm install [パッケージ名]
で指定したパッケージをインストールする。
パッケージ名を指定しない場合は、package.jsonに従ってインストールを行う。
3. コンパイル先の指定
デフォルトでルートディレクトリに
webpack.mix.js
がある。この中にコンパイルする形式や出力先の情報を記述する。・
mix.メソッド名('コンパイルするファイルパス', '出力先');
webpack.mix.js(デフォルト)const mix = require('laravel-mix'); mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', [ // ]);↓ 以下に変更
webpack.mix.jsmix.js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css');resources > sass の app.scssファイルをコンパイルして、public > css 配下に出力する。
▼(補足)別の指定方法
メソッドチェーンでつなげず、別々に記述しても機能する。phpmix.js('resources/js/app.js', 'public/js'); mix.sass('resources/sass/app.scss', 'public/css');
4. ファイルの作成
実際にコンパイルするファイルを作成する。
app.scssファイルの作成
resources > sass > app.scss
app.scssh1 { color: skyblue; }テストなのでシンプルに、、
ビュー
resorces > views > for-scss.blade.php
for-scss.blade.php<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="{{ asset('css/app.css') }}"> </head> <body> <div> <h1>SCSSのテスト</h1> </div> </body> </html>▼cssファイルの読み込み
コンパイルされたcssファイルを読み込む記述を記載する。<link rel="stylesheet" href="{{ asset('css/app.css') }}">URLの呼び出しはassetヘルパー関数を使用。
(参考)assetヘルパー関数とは?
ルーティング
routes > web.php
web.phpRoute::get('scss', function () { return view('for-scss'); });
5. コンパイルの実行
以下コマンドでコンパイルが開始する。
npm run dev
▼実行例$ npm run dev 99% done plugins BuildOutputPlugin Laravel Mix v6.0.10 ✔ Compiled Successfully in 1143ms ┌───────────────────────────────────────────────────────┬──────────┐ │ File │ Size │ ├───────────────────────────────────────────────────────┼──────────┤ │ /js/app.js │ 596 KiB │ │ css/app.css │ 25 bytes │ └───────────────────────────────────────────────────────┴──────────┘webpack.mix.jsの指示通り、jsファイルとcssファイルが作成される。
コンパイル結果の確認
生成されたapp.cssを確認する。今回はapp.scssと同じ内容が記述されていればOK。
app.cssh1 { color: skyblue; }
6. ブラウザに表示
サーバーを起動する。
php artisan serve
URLを入力。http://127.0.0.1:8000/scss
狙い通りコンパイル後のCSSが反映されている。
7. 変更反映の自動化
$ npm run watch
を実行すると、指定したコンパイル元のファイルに変更があった場合に、自動でコンパイルを実行する。$ npm run watch > @ watch /Users/s01386/projects/laravel/test-pj > mix watch
ctrl + c
でサーバーを停止すれば自動監視(mix watch)も停止する。
8. 本番用のコンパイル
$npm run production
を実行すると、本番用の圧縮したファイルを出力してくれる。圧縮版は、改行やスペース、コメントアウトなどを削除したもの。
$ npm run production > @ production /Users/s01386/projects/laravel/test-pj > mix --production 99% done plugins BuildOutputPlugin Laravel Mix v6.0.10 ✔ Compiled Successfully in 5416ms ┌───────────────────────────────────────────────────────┬──────────┐ │ File │ Size │ ├───────────────────────────────────────────────────────┼──────────┤ │ /js/app.js │ 84.8 KiB │ │ css/app.css │ 14 bytes │ └───────────────────────────────────────────────────────┴──────────┘▼出力されたファイル
app.cssh1{color:red}改行やスペースが削除されている。
9. URLの自動変換機能(オフにする方法も)
Laravel Mixの便利機能の一つで、urlで画像リソースを指定した場合に、対象のファイルを
public/images
フォルダにコピーし、コンパイル後のURLをコピー後のファイルのパスに変更する機能がある。▼例
css.example { background: url('../../public/img/cat3.png'); }↓ コンパイル
$ npm run dev 99% done plugins BuildOutputPlugin Laravel Mix v6.0.10 ✔ Compiled Successfully in 888ms ┌──────────────────────────────────────────────────────┬───────────┐ │ File │ Size │ ├──────────────────────────────────────────────────────┼───────────┤ │ /js/app.js │ 596 KiB │ │ css/app.css │ 105 bytes │ │ images/cat3.png?204c4068c53d4775b6e9cb23998276cb │ 158 KiB │ └──────────────────────────────────────────────────────┴───────────┘▼コンパイル後のCSSファイル
css.example { background: url(/images/cat3.png?204c4068c53d4775b6e9cb23998276cb); }画像がパラメータで指定されている。(画像名にパラメータはついていない)
自動コピー&URL変換機能をオフにする
この機能をオフにして、指定したURLをそのままコンパイルしたい場合は、
webpack.mix.js
内にオプションメソッドで以下を追記する。webpack.mix.js.options({ processCssUrls: false });
▼実際のコード例webpack.mix.jsmix.sass('resources/sass/app.scss', 'public/css').options({ processCssUrls: false });
10. 複数ファイルをワイルドカードで指定する
scssファイルがいくつもある場合、コンパイル元のファイルと出力先を個別に設定するのは手間。
npmのパッケージの一つである
glob
を使うことでファイルをワイルドカードで指定できる。const mix = require('laravel-mix'); const glob = require('glob'); glob.sync('resources/sass/*.scss').map(function(file) { mix.sass(file, 'public/css'); });・冒頭に
const glob = require('glob');
を記述。
▼jsのコンパイルもグローバル指定した場合の例webpack.mix.jsconst mix = require('laravel-mix'); const glob = require('glob'); glob.sync('resources/sass/*.scss').map(function (file) { mix.sass(file, 'public/css').options({ processCssUrls: false, }); }); glob.sync('resources/js/*.js').map(function (file) { mix.js(file, 'public/js'); });
参考リンク
- 投稿日:2021-01-18T18:15:22+09:00
LaravelでAuthモデルを呼び出す時って、なんでuse App/Authじゃないの?
Q. LaravelのAuthってなんでApp/Authじゃないの?
Laravel
でモデルを呼び出すときuse App/User;
とかuse App/〇〇
なのに、なんでAuth
だけuse Auth;
で使えるの?
A. Authに関する色々な機能はLaravelが作ってるからじゃない?
use Auth;
で使える直接の理由は、(プロジェクト名)/routes/web.app
で、こう(↓)書かれているから。
認証機能を有効化した段階、ターミナルで
$ php artisan ui vue --auth
を実行した際に記入される。『なんでそれができるか』という問いに対する個人的な認識、仮定としては、
Laravel
で他のモデルはエンジニアが作るけど、Auth
はLaravel
側が作成するからuse Auth;
で使えるようになっている…としか言いようがなくない?
- 投稿日:2021-01-18T18:14:15+09:00
PHPのopenssl_encrypt関数で暗号化したものをopensslコマンドで複合化
PHPのopenssl_encryptとopenssl
phpのopenssl_encrypt()で暗号化した文字列をopensslコマンドで複合化しないといけない案件があったのでメモ
エンコード条件
ivを指定してエンコードするのが定石だが、今回はivの指定がなかった。
$enc_key = "abcedfg"; $enc_method = "aes-256-cbc"; $text = "some encode text"; openssl_encrypt($text, $enc_method, $enc_key);opensslで復号
openssl_encrypt()はIVの指定をしていない場合、key文字列と同じものが指定されるもよう
ポイント
- key文字列を16進数にしたものを-Kオプションに指定する
- ivは-Kオプションに指定した文字の先頭数文字が対応するみたい(文字数はmethod依存?)/** * 文字列を16進数に変換 * @param $x * @return string */ function strtohex($x) { $s=''; foreach (str_split($x) as $c) $s.=sprintf("%02X",ord($c)); return($s); } $key = strtohex($enc_key); $iv = substr($key, 0, 32); //$keyの先頭32文字で複合化できた $cmd = sprintf('echo -n "%s" | openssl enc -d -%s -base64 -A -K %s -iv %s', $custom_data, $key, $iv, $iv); exec($cmd, $out); echo $out;
- 投稿日:2021-01-18T16:34:58+09:00
【Laravel】画面に画像を表示する方法。assetsの使い方とurlヘルパ関数との違いについて。
Laravelでブラウザに画像を表示する方法。
1. publicディレクトリに画像をおく
ブラウザが直接読み取るデータなのでpublicディレクトリに設置する。
2. assetヘルパーで呼び出す
imgタグのsrc属性で、assetsヘルパー関数を使って指定の画像を呼び出す。
<img src="{{ asset('img/cat3.png') }}" alt="">以上で完了。
assetヘルパー関数とは?
publicディレクトリ配下の素材へのURLを生成する。
・
assets('ファイルパス')
ディレクトリの中にある場合は、
ディレクトリ名.
でつなぐ。ビューで呼び出す
ビュー(拡張子 .blade.php)の中で呼び出す場合は、
{{ }}
をつける。.blade.php{{ asset('img/cat3.png') }} <br> {{ asset('robots.txt') }}▼ブラウザの表示
自分のサイトのpublicフォルダのパスが表示される。
あとは、aタグやimgタグのsrcで指定すれば、各アセットにアクセスできる。
公式ページには以下のように説明されている。(違いはよくわからない)
urlヘルパとassetヘルパの違い
URLを表示するヘルパには、
url()
という関数もある。・
asset()
asset関数は、現在のリクエストのスキーマ(HTTPかHTTPS)を使い、アセットへのURLを生成。・
url()
url関数は指定したパスへの完全なURLを生成。結論からいうと、
url
もasset
もほぼ同じ。ただし、url
は引数でパスを渡せるので動的にURLを生成しやすい。
urlヘルパとassetヘルパは同じ使い方ができる
.blade.phpasset: {{ asset('img/cat3.png') }} <br> <img src="{{ asset('img/cat3.png') }}" alt=""> <hr> url: {{ url('img/cat3.png') }} <br> <img src="{{ url('img/cat3.png') }}" alt="">
全く同じURLが表示される。
url
に特化した使い方・
url('prefixのパス', ['後ろに続くパス'])
例1{{ url('img', ['cat3.png']) }}↓
例2{{ url('column', ['technology', 2020, 1, 10, 'monday']) }}↓
動的にURLを指定する際に何かと便利。
参考
- 投稿日:2021-01-18T15:48:43+09:00
【Laravel】publicとresourcesディレクトリのassets(img, css, js)の違いについて
Laravelのimageファイルやjs, cssファイルの置き場所を探したときに、publicとresourcesディレクトリに混在していることがある。
このpublicとresourcesディレクトリの違いについて。
publicとresourcesディレクトリの違い
公開範囲が異なる。
・publicディレクトリ
名前(public)の通り、中身が公開されており、ブラウザが直でアクセスできるデータ。・resourcesディレクトリ
公開はされておらず、コンパイル前のデータが置かれている。viewsディレクトリのビュー(.blade.php)もコンパイル前はPHPを含んでいるが、コンパイル後の公開するファイルはHTMLのみとなる。
publicとresourcesディレクトリの使い分け
publicファイルにはブラウザが直でアクセスしてもいいデータを置く。
resoucesの使い方は主に2つ。
(1)サブの画像などを置いておく
公開されないので何を置くかは自分次第。(2)コンパイルが必要なファイルをおく
.blade.phpやscssなどコンパイル前の元ファイルを置いておく。
- 投稿日:2021-01-18T15:23:29+09:00
【小ネタ】JavaScriptでPHPのlist()っぽいことをやってみる。
はじめに
ドット連結の文字列を分割してそれぞれを変数にできないかなーって考えたときに、もしかしたらJSでもPHPのlist()みたいなことできるんじゃね?って思ったんですよ。
PHPのlist()とは
右辺が配列になるとき、左辺側に列挙した変数に値を入れれるというやつです。
https://www.php.net/manual/ja/function.list.phplist($jeffy, $tockey, $fagimaru) = ['犬', '猿', '雉']; echo $jeffy; // 犬 echo $tockey; // 猿 echo $fagimaru; // 雉実はPHP7.1以降は以下の書き方でもいけるんですよね。全然気づかなかった……
[$jeffy, $tockey, $fagimaru] = ['犬', '猿', '雉']; echo $jeffy; // 犬 echo $tockey; // 猿 echo $fagimaru; // 雉JSではどうするの?
実はPHPの省略構文と同じです。
const [jeffy, tockey, fagimaru] = ['犬', '猿', '雉']; console.log(jeffy); // 犬 console.log(tockey); // 猿 console.log(fagimaru); // 雉「分割代入」っていうんですね。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
- 投稿日:2021-01-18T14:26:29+09:00
Laravelで画像をアップロードし、パスをDBに保存する方法
はじめに
Laravelで画像をアップロードし、DBに保存する方法について解説していきます。
まず、今回は画像はプロジェクト内のディレクトリに保存をし、画像のパスをデータベース(以下DB)に保存していきます。
データベースに画像を保存することもできますが、その場合はサイズが大きくなってしまい処理に時間がかかってしまいます。
そのため、画像のパスのみをDBに保存するのが主流のようです。また、今回はLaravelのプロジェクトは作成し、DBへ接続済であることを前提に進めていくのでご了承ください。
-各バージョン
-laravel 6.x
-PHP 7.4.9
-mySQL 5.7.30モデルとテーブルを作成する
今回は読書の記録をするアプリを推定して作っていきます。データはシンプルに画像、本の題名、著者名にしたいと思います。
早速、モデルとテーブルをコマンドで作成します。
php artisan make:model Book -m上記のコマンドを実行すると、Bookモデルとbooksテーブルが作成されます。
続いて、booksテーブルにDBに保存する項目を入力していきます。
books_table_phppublic function up() { Schema::create('books', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('title', 100); $table->string('author', 100); $table->string('image'); $table->timestamps(); }); }そのままマイグレーションします。
php artisan migrate問題なくマイグレーションできれば、DBにbooksというテーブルが作成されているはずです。
ビューを作成する
続いて、入力フォームを作っていきます。
upload.blade.php<form method="post" action="{{ route('upload_image') }}" enctype="multipart/form-data"> @csrf <input type="file" name="image"> <label for="title">題名</label> <input id="title" type="text" name="title"> <label for="author">作者</label> <input id="author" type="text" name="author"> <input type="submit" value="登録"> </form>まず、画像ファイルをアップデートするには必ず
form
にenctype="multipart/form-data
が必要になります。
また、@csrf
はCSRFトークンというもので、外部からの悪意のある攻撃から守るための記述であり、Laravelのフォームには記述が必須となっています。
input
内を見ていきます。
画像をアップロードする場合はtype属性をfile
に指定します。そしてname属性には先ほどbooks_table_phpで指定したカラム名を指定します。コントローラーを作成する
まずはコマンドでコントローラーを作成します。
php artisan make:controller BookControllerBookControllerが作成されたら、利用するモデル名と、使用するヘルパ関数名を冒頭に記述します。もちろん、あとからその都度記述することも可能です。
BookController.phpuse App\Book; use Illuminate\Support\Str;そして、画像を保存するための処理を書いていきます。
phppublic function store(Stock $request) { $book = new Book(); $book->title = $request->input('title'); $book->author = $request->input('author'); // 保存されているデータを$formに格納する $form = $request->all(); // もし$formにimageデータがあったら if (isset($form['image'])) { // $fileにイメージデータを格納する $file = $request->file('image'); // getClientOrientalExtension()でファイルの拡張子を取得する $extension = $file->getClientOriginalExtension(); $file_token = Str::random(32); $filename = $file_token . '.' . $extension; // 表示を行うときに画像名が必要になるため、ファイル名を再設定 $form['image'] = $filename; $file->move('uploads/books', $filename); } $book->save(); return redirect('home'); }コードにコメントを書いていないところを解説していきます。
まず、
getClientOriginalExtension()
でファイルの拡張子を取得した後に、Str::random()
でランダムな文字列を取得します。Str::random()
は( )内に指定された文字数分、ランダムな文字列を作成することができる関数です。今回は32文字を指定しました。
こうして$filename
には画像のパスが「ランダムな32文字 . 拡張子」の状態で保存されていることになります。続いてこちらを、
move()
で任意のファイルに保存するように設定します。move('指定したファイル', 保存するファイル名)
の順番で記述をすると、Publicフォルダ内に指定したファイルが自動生成され、アップロードした画像が保存されるようになります。最後に
save()
メソッドでデータを保存し、今回はredirect()
でhomeに戻るように指定しています。ルーティングを設定する
upload.blade.php内で
form
のaction
をroute('upload_image')
と指定したので、今回はupload_image
をname()
で指定し、アクセスをしたら、BookControllerのStoreアクションにつながるように記述します。web.phpRoute::post('/upload', 'BookController@store')->name('upload_image');これで完成です!
さいごに
今回はLaravelで画像をアップロードし、DBに保存する方法について解説しました。
次回以降、保存したデータを表示する方法や編集方法に関しても解説していけたらと思います!参考
- 投稿日:2021-01-18T13:47:59+09:00
【Laravel】変数の前の(int)や(string)の意味。変数の型を簡単に変換する方法。
Laravelで変数の前に
(int)
や(string)
などが使われていることがあるこの意味について。
(型)$変数名
の意味
(型)$変数名
で変数の型を変換することができる。
これを型キャストと呼ぶつまり、
(int)
は後に続く変数の方を整数にする処理となる。型キャストの例$x = "12000" $y = (int) $x echo gettype($y) //integer $z = ( array ) $x; var_export($z); //array (0 => '2000')カッコ内や型キャストと変数の間にスペースがあっても機能する。
型キャストでbooleanに変換する場合、値が存在すればtrueに変換される。$x = "12000" $z = (boolean)$x; var_export($z); //true使用可能な型キャスト一覧
型キャスト 処理 (int) 整数へのキャスト。(integer)と同じ。 (bool) 論理値へのキャスト。(boolean)と同じ。 (float) float へのキャスト。(double), (real)と同じ (string) 文字列へのキャスト (array) 配列へのキャスト (object) オブジェクトへのキャスト (unset) NULL へのキャスト https://www.php.net/manual/ja/language.types.type-juggling.php
- 投稿日:2021-01-18T12:55:21+09:00
【PHP】IoTデバイスからPOST送信されたときに送信元IPアドレスを取得する【ESP32】
はじめに
IoTデバイスをIPアドレスを使って識別しようとしている方,デバイスのIPアドレスをサーバ側で取得したい方向けになります.
環境
- IoTデバイス(ESP32)
- ファームウェア(MicroPython1.3)
- サーバ(Ubuntu18.04)
- Webサーバ(Apache2)
- PHP(PHP7.4)
※Apache2を起動して/var/www/html/にPHPプログラム(今回はreceive.php)を置いておくことが前提です.
ソースコード(ESP32)
今回はESP32で適当なJSONデータのPOST送信をし,サーバで送信元のIPアドレスを取得してレスポンスとしてそのIPアドレスを返すようなプログラムにしました.
post.pyimport urequests import ujson #送信先のURLの指定 #"XXX.XXX.XXX.XXX"にURLを入れる url = 'http://XXX.XXX.XXX.XXX/receive.php' #データをDICT型で宣言 obj = {"value" : 123, "text" : "abc"} #jsonデータで送信するという事を明示的に宣言 header = {'Content-Type' : 'application/json'} #オブジェクトをJSONに変換し,HTTPリクエストをPOSTとして送信 res = urequests.post( url, data = ujson.dumps(obj).encode("utf-8"), headers = header ) #サーバ側からのレスポンスを受け取って表示(jsonのデコードも一緒にしている) print (res.json()) #終了 res.close()ソースコード(サーバ)
送信元のIPアドレスは
$_SERVER[REMOTE_ADDR]
に入っているのでそれを変数に入れるなりする.receive.php<?php //送られてきたPOSTデータを受け取って,JSONデータをデコードして$inに入れる. $json_string = file_get_contents('php://input'); $in = json_decode(stripslashes($json_string),true); //送られてきたデータを取り出す $value = $in["value"]; // = 123 $text = $in["text"]; // = abc //$_SERVER変数を使って送信元のIPアドレスを取得する //レスポンスを取得したIPアドレスとし,それをJSONとして再度エンコード //そして送信元(ESP32)へ返す. $ipAddress = $_SERVER['REMOTE_ADDR']; //AWS ELBを使用している場合はELBのIPアドレスを取得してしまうので //以下のようにして元のIPアドレスを取得する if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) { $ipAddress = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])); } //IPアドレスをエンコードして返す echo json_encode($ipAddress); ?>実行結果
micropythonのWEB REPLで実行したところ,IPアドレスが返ってきました.
>>> execfile("post.py") >>> YYY.YYY.YYY.YYY // <- ESP32のIPアドレス参考
この記事は以下の記事を参考に書いています
[1]
ESP32からMicropythonでHTTPリクエスト(POST)でデータを送信し,PHP(サーバ)で受け取る
- 投稿日:2021-01-18T12:50:49+09:00
【Laravel】アンダースコア2つの意味。__()の記述は何をしているのか?
Laravelの
__( )
の処理内容について。▼こういうの
例1@if(__('career.'. $career_slug .'.is_recruiting') === "false") //処理 @endif例2@include('partials.jumbotron', ['title' => __('page.recruit.career.'. $career_slug .'.title')])__()の意味
__ヘルパ関数
と呼ぶ。Lang::get
の省略形。現在設定中の言語ファイルから、指定したデータを呼び出すときに使用する。
現在設定中の言語
config > app.php の中の
locale
を参照。ja(日本語)の場合'locale' => 'ja',言語ファイルの場所
resources > lang配下。
enはデフォルトでプロジェクトを作成した状態。
jaが後から追加したもの。
__()
の使い方例えば、言語設定が
'locale' => 'ja'
のときに使うと、jaディレクトリの指定したファイルのデータを取得する。・
__('ファイル名')
ファイルの中のデータをごっそり取得・
__('ファイル名.プロパティ名')
指定したプロパティのデータを取得
実例
例@php $career_slug = 'editor' @endphp @if(__('career.'. $career_slug .'.is_recruiting') === "false") //処理 @endif上記処理を確認すると、
__('career.'. $career_slug .'.is_recruiting')`carrer.phpの、editorプロパティ(
$career_slug
)の、is_recruitingプロパティの値を取得している。carrer.php<?php return [ 'editor' => [ 'is_recruiting' => 'false', 'position' => "編集", 'job_description' => "ライティング業務です" ], ];つまり、取得したデータは
false
となる。
@if(__('career.'. $career_slug .'.is_recruiting') === "false")
@if
の条件式がtrueになるので処理が実行される。
参考
- 投稿日:2021-01-18T11:21:15+09:00
【Laravel】コンポーネントとスロットの使い方を実例で理解する(@component & @slot)
Laravelで使われるコンポーネント(
@component
)とスロット(@slot
)の使い方について。Laravel公式のコンポーネントとスロットを参照したがコードに
slot
が複数あったりで機能がわかりにくいので、要素を分解し確認してみた。
目次
ファイルの準備
用意するファイルは2つ。
(1)ビュー
viewsフォルダ直下にcomp-slot.blade.php
を作成。ディレクトリapp > resources > views > comp-slot.blade.php
(2)コンポーネント
componentsフォルダの中にtest.blade.php
を作成。ディレクトリapp > resources > views > components > test.blade.phpルーティングの設定
app > routes > web.php にルーティングを追記する。
web.phpRoute::get('test', function () { return view('comp-slot'); });パスがtestのURIにアクセスがあったら、ビューファイルcomp-slot.blade.phpを開く。
コンポーネントの使い方
コンポーネントの中身を表示する方法は大きく3つ。
1. コンポーネントの中身をそのまま表示
2. 変数slotでデータを渡す
3. 指定したslot名でデータを渡す2と3でslotが登場するのがわかりにくい、、それぞれ用途が異なる。
1. コンポーネントの中身をそのまま表示
コンポーネントをそのまま呼び出して表示する。(データの受け渡しをしない)
▼コンポーネント
test.blade.php<div> <p>test.blade.phpです。</p> </div>▼メインビュー
comp-slot.blade.php@component('components.test') @endcomponent・
@component('コンポーネントファイル名')
- ファイル名はviewsからの絶対パスを記載。
- ディレクトリの中にある場合はディレクトリ名をドットで繋ぐ。
画面表示
comp-slot.blade.phpを開くと、コンポーネントの内容が表示された。
2. 変数slotでデータを渡す。
次に、元のビューファイルの
@component
の中に記載したデータを渡す方法について。▼メインビュー
comp-slot.blade.php@component('components.test') <p>コンポーネントの中身</p> @endcomponent
@component
の中にある要素をコンポーネントに{{$slot}}
を記載することで好きな場所で呼び出すことができる。▼コンポーネント
test.blade.php<div> <p>test.blade.phpです。</p> {{$slot}} </div>
▼複数呼び出すtest.blade.php<div> {{$slot}} <p>test.blade.phpです。</p> {{$slot}} </div>
▼{{$slot}}
を呼び出さない
{{$slot}}
を記述しない場合は、@component
内の記載は無視される。▼コンポーネント
test.blade.php<div> <p>test.blade.phpです。</p> </div>
注意点
@component
の中身が@slot
などで分断して記述してある場合でも、@slot
を除いた、ひとまとまりの要素として出力される。▼メインビュー
comp-slot.blade.php@component('components.test') コンポーネントの中身(上) @slot('xxx') slotディレクティブのxxx @endslot コンポーネントの中身(下) @endcomponent▼コンポーネント
test.blade.php<div> {{$slot}} <p>test.blade.phpです。</p> </div>
3. 指定したslot名でデータを渡す
@component
内に複数のデータのまとまりを作成し、コンポーネントに渡すには、slot('スロット名')
を使う。呼びだしは
{{$スロット名}}
とする。▼メインビュー
comp-slot.blade.php@component('components.test') @slot('xxx') slotディレクティブの中身 @endslot @endcomponent▼コンポーネント
test.blade.php<div> {{$xxx}} <p>test.blade.phpです。</p> </div>
@slot
を複数設置ひとまとまりのデータを複数作成することができる。
▼メインビュー
comp-slot.blade.php@component('components.test') <p>コンポーネントの中身</p> @slot('xxx') slotディレクティブの中身 @endslot @endcomponent▼コンポーネント
test.blade.php@component('components.test') @slot('xxx') slotディレクティブのxxx @endslot @slot('yyy') slotディレクティブのyyy @endslot @endcomponent
まとめ
コンポーネントの中身を表示する方法を一つづつ確認すればだいぶわかりやすい。
1. コンポーネントの中身をそのまま表示
2. 変数slotでデータを渡す
3. 指定したslot名でデータを渡す最後に、3つを複合すると以下のようなコードになる。
▼メインビュー
comp-slot.blade.php@component('components.test') <p>コンポーネントの中身(上)</p> @slot('xxx') slotディレクティブのxxx @endslot @slot('yyy') slotディレクティブのyyy @endslot <hr> <p>コンポーネントの中身(下)</p> @endcomponent▼コンポーネント
test.blade.php<div> {{$yyy}} {{$slot}} <p>test.blade.phpです。</p> {{$xxx}} {{$slot}} </div>
- 投稿日:2021-01-18T09:52:40+09:00
【Laravel】プロジェクトの作成からブラウザ経由のDB操作までを実際にやってみる(アプリ作成の手順詳細)
Laravel学習のため、プロジェクト作成しブラウザからのDB操作(新規追加、編集、削除)を自分でやってみる。
目次
- composerのインストール
- laravelのインストール
- laravelサーバーの起動
- DBにsqliteを設定
- モデルとマイグレーションの作成
- マイグレーションでDBのテーブルにカラムを追加
- コントローラの作成
- ルーティングの設定
- seederを使ってテストデータをDBに設定
- 一覧画面の作成(ブラウザにDBの全データを表示)
- 詳細ページの作成
- 編集機能の作成
- 削除機能の作成
1. composerのインストール
2. laravelのインストール
$ composer create-project laravel/laravel [プロジェクト名] --prefer-dist指定したプロジェクト名でフォルダが作成される。
・
--prefer-dist
オプション
高速ダウンロード用。このオプションをつけると圧縮されていないファイルを優先してダウンロードする。また、すべてのVSC(バージョン管理ソフト)を取得しないので軽量となる。
3. laravelサーバーの起動
php artisan serve
$ php artisan serve Starting Laravel development server: http://127.0.0.1:8000表示されたURLにアクセス
http://127.0.0.1:8000
上記画面が表示されればOK。
サーバーの停止はctrl + c
。
DBにsqliteを設定
使用が簡単かつmacにデフォルトでインストールされているsqliteをDBに使用する。
laravelインストール時のデフォルトのDBはMySQLのため、環境ファイルの設定を一部変更する。
.envファイルの変更
ルートディレクトリ直下にある.envファイルを開き、以下コードを変更する。
.env(変更前)DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD=↓ 以下に変更
.env(変更後)DB_CONNECTION=sqliteDB用のファイルを作成する
database/database.sqliteを作成する。
プロジェクトのルートディレクトリで以下を実行。
$ touch database/database.sqliteモデルとマイグレーションの作成
DBのテーブルに対応するモデルと、テーブルにカラムを追加したり型指定するマイグレーションファイルを作成する。
$ php artisan make:model [モデル名] -m
- artisanコマンドの
make:model
でモデルを作成する。-m
オプションでマイグレーションファイルも同時生成。(--migrate
の省略形)- モデル名は冒頭大文字の単数形。単語をつなげる場合はキャメルケースにする(例:MakerCode)
▼モデルの命名規則
DBのテーブル名は複数形とし、Model名はその単数形とする。・DBのテーブル名: 複数形のスネークケース
・対応するModel名: 冒頭大文字のキャメルケース<例1>
・DBのテーブル名: articles
・対応するModel名: Article<例2>
・DBのテーブル名: maker_codes
・対応するModel名: MakerCode
▼(例)Productモデルを作成$ php artisan make:model Product -m Model created successfully. Created Migration: 2021_01_15_022833_create_products_table2つのファイルが生成される。
・マイグレーション
database > migrations > タイムスタンプcreateテーブル名_table.php
(補足)モデルとマイグレーションファイルを別々に作る場合
マイグレーションファイルは作成用のartisanコードがあるので、それを使って生成できる。
$ php artisan make:model Product $ php artisan make:migration create_products_table
マイグレーションでDBのテーブルにカラムを追加する
マイグレーションファイルの編集
作成したいカラムを追記する。デフォルトでidとtimestampsのカラムがある。
up関数の中に追記する。
・
$table->型('カラム名')
2021_01_15_022833_create_products_table.phppublic function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('product_name')->unique(); //追加 $table->integer('price'); //追加 $table->boolean('is_stocked')->nullable(); //追加 $table->timestamps(); }); }必要に応じて、
unique()
やnullable()
などの修飾子をつけることができる。
カラムタイプと修飾子
他にもたくさんのカラムタイプが用意されている。
続きは以下リンク参照。
マイグレーションの実行
作成したマイグレーションファイルの内容をテーブルに反映する。
php artisan migrate
▼migrationの実行例$ php artisan migrate Migration table created successfully. Migrating: 2021_01_15_022833_create_products_table Migrated: 2021_01_15_022833_create_products_table (0.90ms)テーブルの作成に成功。
エラー発生時
Illuminate\Database\QueryException
Database (/laravel/test-pj/database/database.sqlite) does not exist. (SQL: PRAGMA foreign_keys = ON;)対策:$ touch database/database.sqlite を実行
コントローラの作成
DBにデータを追加・読み込み・編集・削除(CRUD操作)するためにコントローラを作成する。
作成時にオプションで
-r
をつけると、CRUD操作のためのアクションが記載されたコントローラを作成することができる。$ php artisan make:controller [コントローラ名] -r
-r
は--resource
の省略形- コントローラ名は冒頭大文字で、後ろに
Controller
をつける(例:ProductController)- app > Http > Controllerの中にファイルが生成される
--resourceオプションで作成したコントローラを特別にリソースコントローラと呼ぶ。
▼ProcuctControllerの作成例
create, show, editなどCRUD操作に必要なアクションの外枠を既に記述してくれている。
あとは実際の処理を各アクションの中に記述するだけの状態。$ php artisan make:controller ProductController -r Controller created successfully.▼ファイルの中身
ProductController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class ProductController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } }
ルーティングの設定
先ほど作成したコントローラの各アクションをルートに登録する。
ルーティングは、app > routes > web.php に記述する。
リソースコントローラのルート登録は、Routeファサードのresourceメソッドで簡単にできる。
web.phpRoute::resource('$URI', 'コントローラ名');
- $URIは複数形のパスを指定する。
▼実例web.phpRoute::resource('products', 'ProductController');▼ルートの登録状況を確認
・
$ php artisan route:list
$ php artisan route:list +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | | GET|HEAD | api/user | | Closure | api | | | GET|HEAD | products | products.index | App\Http\Controllers\ProductController@index | web | | | POST | products | products.store | App\Http\Controllers\ProductController@store | web | | | GET|HEAD | products/create | products.create | App\Http\Controllers\ProductController@create | web | | | GET|HEAD | products/{product} | products.show | App\Http\Controllers\ProductController@show | web | | | PUT|PATCH | products/{product} | products.update | App\Http\Controllers\ProductController@update | web | | | DELETE | products/{product} | products.destroy | App\Http\Controllers\ProductController@destroy | web | | | GET|HEAD | products/{product}/edit | products.edit | App\Http\Controllers\ProductController@edit | web | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+リソースコントローラの各アクションがルート登録されている。
Laravel8.xでエラーが出た場合は、RouteServiceProvider.phpのコメントアウトを解除する
(補足)sqliteにテーブルが作成されているか確認する
sqliteにアクセスするためには、
sqlite3
コマンドで、database.sqliteを開く。ルートディレクトリで以下を実行。
・$ sqlite3 database/database.sqlite
$ sqlite3 database/database.sqlite SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. #テーブル一覧を表示 sqlite> .table failed_jobs password_resets users migrations products #productsテーブルの構造(schema)を表示 sqlite> .schema products CREATE TABLE IF NOT EXISTS "products" ( "id" integer not null primary key autoincrement, "product_name" varchar not null, "price" integer not null, "is_stocked" tinyint(1) not null, "created_at" datetime null, "updated_at" datetime null );productsテーブルがあり、指定したカラムを持っていることがわかる。
▼sqlite3の主なコマンド
コマンド 内容 .tables テーブル一覧を表示 .schema [テーブル名] 指定したテーブルのスキーマ定義を表示 .exit sqliteを終了 .help ヘルプを表示
seederを使ってテストデータをDBに設定する
seeder(シーダ)とは、DBを手軽にテストするために、テストデータをDBに設定する機能。
$ php artisan make:seeder シーダ名
- シーダ名は、[テーブル名]TableSeeder とするのが一般的
- 保存先: app > database > seeders
なかなか便利な機能で、deleteやedit機能などでデータをあれこれ変更した後に、seederをDBに送ればまた初期のデータを復活させることができる。
▼実例$ php artisan make:seeder ProductTableSeeder Seeder created successfully.ProductTableSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; class ProductTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // } }run関数を持ったクラスが生成される。
seederの編集
seederファイルのrun関数の中に処理を記述する。
今回はクエリビルダで記述する。冒頭でDBファサードのuse宣言をが必要。ProductTableSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; //追加 class ProductTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { //以下追加 DB::table('products')->insert([ [ 'product_name' => 'iPhone6s', 'price' => 62000, 'is_stocked' => false ], [ 'product_name' => 'iPhone8', 'price' => 84000, 'is_stocked' => true ], [ 'product_name' => 'iPhone12', 'price' => 120000, 'is_stocked' => true ] ]); } }今回はクエリビルダで記述しているが、Eroquentでも問題ない。
seederをDBに反映する
seederをDBに反映する際は、基本的に
DatabaseSeeder.php
を使う。
そのため、作成したクラスをDatabaseSeeder.php
の中で呼び出す。DatabaseSeeder.phppublic function run() { $this->call(ProductTableSeeder::class); }DatabaseSeeder.phpをメインとして使うとseederファイルを複数に分割している場合も容易にDBに反映できる。
#Composerのオートローダを再生成する $ composer dump-autoload #DatabaseSeeder.phpを実行する $ php artisan db:seed
▼実際の処理例$ composer dump-autoload Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: fruitcake/laravel-cors Discovered Package: laravel/sail Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. Generated optimized autoload files containing 4618 classes $ php artisan db:seed Seeding: Database\Seeders\ProductTableSeeder Seeded: Database\Seeders\ProductTableSeeder (9.16ms) Database seeding completed successfully.以上でseederで作成したデータをDBに反映完了。
▼(補足)別のseederファイルを直接DBに反映する
DatabaseSeeder.phpではなく、別途作成したseederファイルのみ読み込ませたい場合は、--class
オプションでseederを指定する。php artisan db:seed --class=ProductTableSeeder
DBのデータを確認する
・DBのデータを抽出してみる
artisanコマンドのtinkerを使って、Laravelの対話モードに入り、Eloquentのallメソッドで指定したモデルのすべてのデータを取得する。
$ php artisan tinker >>>[モデルの完全な名前空間]::all();対話モードは
exit
で抜ける。tinkerの元の意味は小さな改善をすること。phpの対話モードでコマンドを一つづつ実施することが由来している?
▼実例ターミナル$ php artisan tinker Psy Shell v0.10.5 (PHP 7.3.11 — cli) by Justin Hileman >>> >>> App\Models\Product::all(); => Illuminate\Database\Eloquent\Collection {#4309 all: [ App\Models\Product {#4308 id: "1", product_name: "iPhone6s", price: "62000", is_stocked: "0", created_at: null, updated_at: null, }, App\Models\Product {#4307 id: "2", product_name: "iPhone8", price: "84000", is_stocked: "1", created_at: null, updated_at: null, }, App\Models\Product {#4298 id: "3", product_name: "iPhone12", price: "120000", is_stocked: "1", created_at: null, updated_at: null, }, ], } >>> >>> exit Exit: Goodbye指定したデータが取得できている。
・sqliteで確認する
ルートディレクトリで以下を実行。
・$ sqlite3 database/database.sqlite
テーブルの中のデータをすべて表示(SQL)
・select * form [テーブル名]
$ sqlite3 database/database.sqlite sqlite> select * from products; 1|iPhone6s|62000|0|| 2|iPhone8|84000|1|| 3|iPhone12|120000|1|| sqlite> .exit
一覧画面の作成(ブラウザにDBの全データを表示)
取得した全データを表示する一覧画面を作成する。
コントローラのindexアクションを編集する
以前に作成したコントローラのindexアクションの戻り値にDBのすべてのデータを指定する。
Eloquentを使うため冒頭に使用するモデルのクラスをuse宣言する。
ProductController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; //追記 class ProductController extends Controller { public function index() { $productsInfo = Product::all(); //追記 return $productsInfo; //追記 } //以下略(参考)Eroquetとは?
サーバーを起動する
$ php artisan serve
を実行する。$ php artisan serve Starting Laravel development server: http://127.0.0.1:8000
ブラウザで表示する
URIにindexに対応するルートを入力する。(ここでは /products)
ルートは、
$php artisan route:list
コマンドで確認できる。
取得したデータの表示に成功。取得データをそのまま返しているのでデータはJSON形式で表示される。
ビューの作成
取得データを見やすく表示するためにビューを作成する。
ビューは resources > views 配下に、拡張子.blade.php
で保存する。今回は、productsディレクトリを作成し、外側となるbase.blade.phpとメイン部分となるindex.phpを用意する。
レイアウトの作成
layoutsディレクトリの中に
base.blade.php
を作成する。base.blade.php<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@yield('title')</title> </head> <body> <h1>@yield('title')</h1> @yield('content') </body> </html>メインビューの作成
index.blade.phpを作成する。
index.blade.php@extends('.products.layouts.base') @section('title', '製品一覧') @section('newLink') <a href="/products/create">新規作成</a> <hr> @stop @section('content') @foreach ($products as $product) <div> <h2>{{$product->product_name}}</h2> <p>・製品価格:{{number_format($product->price)}}円</p> <p>・在庫: @if ($product->is_stocked) あり @else なし @endif </p> <a href="/products/{{$product->id}}/edit">編集する</a> | <a href="/products/{{$product->id}}">商品詳細</a> <hr> </div> @endforeach @stop後々作成する、新規作成、編集、商品詳細ページへのリンクも設置してある。
(参考)section, yield, extendsについて
コントローラでビューを指定
ProductControllerのindexアクションで、作成したビュー(index.blade.php)を開くように処理を変更する。
ProductController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; //追記 class ProductController extends Controller { public function index() { $productsInfo = Product::all(); return view('products.index', ['products' => $productsInfo]); //変更 } //以下略
view
をviewヘルパーと呼び、指定したビューを開く。その際、第2引数でデータを渡せる。- resource > products > index.blade.phpは、products.indexとして指定。
- 第2引数の書き方: ['変数名' => 渡すデータ]
▼ブラウザの表示
保存して、サーバー起動php artisan serve
し、URIを入力する。http://127.0.0.1:8000/products
DBから取得したデータが成形して表示されている。
詳細ページの作成
商品詳細ページを作成する。
コントローラの編集
ProductControllerのshowアクションを編集する。
ProductController.phppublic function show($id) { //受け取ったidの製品情報を格納 $product = Product::find($id); return view('products.show', ['product' => $product]); }URLのproductsの後ろのデータが
$id
として渡される。
findメソッドを使って、指定したidのデータを変数$productに格納する。
ビューの編集(show.blade.php)
resources > products 配下にshow.blade.phpを作成する。
show.blade.php@extends('.products.layouts.base') @section('title', '製品詳細') @section('content') <div> <h2>{{$product->product_name}}</h2> <p>・製品価格:{{number_format($product->price)}}円</p> <p>・在庫: @if ($product->is_stocked) あり @else なし @endif </p> <a href="/products/{{$product->id}}/edit">編集する</a> | <a href="/products">製品一覧に戻る</a> | @component('components.delete-txt', ['product'=>$product]) @endcomponent <hr> </div> @stopあとは、http://127.0.0.1:8000/products/1 のように、末尾でidを指定すると製品詳細ページが開く。
編集と削除リンク先は後ほど作成。
▼(補足)削除機能のボタン
削除機能はcomponentとして読み込んでいる。詳細の機能は最後の削除機能で作成する。@component('components.delete-txt', ['product'=>$product]) @endcomponent
新規追加機能の作成
ルーティングの確認
DBに保存するには、createアクションを実行し、storeアクションを行う。
ルートを確認すると、/products/createでcreateアクションを実行、/productsにPOSTでアクセスするとstoreアクション実行となる。
$ php artisan route:list +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | | POST | products | products.store | App\Http\Controllers\ProductController@store | web | | | GET|HEAD | products/create | products.create | App\Http\Controllers\ProductController@create | web | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+
createビューの作成
新規作成ページとして、create.blade.phpを作成する。
create.blade.php@extends('.products.layouts.base') @section('title', '製品の新規追加') @section('content') <form action="/products" method="post"> @csrf <div> <label for="product_name">製品名:</label> <input type="text" name="product_name" required autoforcous> </div> <div> <label for="price">製品価格: </label> <input type="text" name="price" required> </div> <div> <label for="stock">在庫有無:</label> <select name="stock"> <option value="1">あり</option> <option value="0">なし</option> </select> </div> <div> <div> <input type="submit" value="送信"> </div> </form> @stop・
@csrf
クロスサイトリクエストフォージェリ対策として必須。(参考)Laravel公式 CSRF保護
@csrf
の記述がないと、submit後に419のエラーページに飛ばされる。(419はLaravel独自のエラーページ)
コントローラの編集
新規追加のためには、createアクションとstoreアクションの2つに処理を追加する。
createアクション
createアクションでは、上記で作成したビューを表示させるのみ。
ProductController.phppublic function create() { return view('products.create'); }storeアクション
storeアクションでは、submitで送られてきたデータを受け取り、DBに保存する処理を記述する。
ProductController.phppublic function store(Request $request) { $product = new Product; $product->product_name = $request->product_name; $product->price = $request->price; $product->is_stocked = $request->stock; $product->save(); return redirect('products/'.$product->id); }・
$product = new Product;
Productモデルからインスタンスを作成し、変数に代入。
この変数に各データを保存していく。・
$request->[name属性]
submitで送られてきたデータは$request
に保存されている。
name属性を指定してデータを取得する。・
$product->save();
すべてのデータを格納したら、saveメソッドでDBに保存する。・
return redirect('products/'.$product->id);
新たに作成した製品詳細ページにリダイレクトする。
ブラウザで開く
ブラウザでcreateページを開く。
http://127.0.0.1:8000/products/create
↓ 送信
新規保存し、新しい製品詳細ページの表示に成功。
編集機能の作成
ルーティングの確認
既存商品の情報を編集するには、editアクションとupdateアクションを使う。
$ php artisan route:list +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | | PUT|PATCH | products/{product} | products.update | App\Http\Controllers\ProductController@update | web | | | GET|HEAD | products/{product}/edit | products.edit | App\Http\Controllers\ProductController@edit | web | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+
products/{product}/edit
にアクセスして、商品の編集を行い、products/{product}
にPUT|PATCHでアクセスすればDBの情報を更新できる。
編集ページの作成
編集用のビュー、edit.blade.phpを作成する。
基本的にはcreate.blade.phpと同じ。PUTでアクセスするために擬似メソッドを設置する。▼create.blade.phpとの違い
- formタグのactionでパスが変わる。
- 擬似フォームメソッドの
@method('PUT')
を設置。- inputタグにvalue属性で既存の設定データを表示。
- 在庫の有無に合わせてselectタグの初期値を設定。
- submitボタンのvalueを更新に変更。
edit.blade.php@extends('.products.layouts.base') @section('title', '製品の編集') @section('content') <form action="/products/{{$product->id}}" method="post"> @csrf @method('PUT') <div> <label for="product_name">製品名:</label> <input type="text" name="product_name" value="{{$product->product_name}}" required autoforcous> </div> <div> <label for="price">製品価格: </label> <input type="text" name="price" value="{{$product->price}}" required> </div> <div> <label for="stock">在庫有無:</label> <select name="stock"> @php $selected = "selected"; if ($product->is_stocked) $selected = "" @endphp <option value="1">あり</option> <option value="0" {{$selected}}>なし</option> </select> </div> <div> <input type="submit" value="更新"> </div> </form> @stop
・擬似フォームメソッド
HTMLフォームはPUT
,PATCH
,DELETE
リクエストを作成できないため(対応していない)、_method
を偽装する必要がある。・
<input type="hidden" name="_method" value="リクエストメソッド名">
type="hidden"をつけると画面上に表示していないデータを送信することができる。
_method
というキー名で、指定したリクエストメソッドを値として送信している。▼putを使う方法
送信ボタンの上に以下タグを設置する。edit.blade.php<input type="hidden" name="_method" value="put"> <input type="submit" value="更新">これを、laravelの擬似フォームメソッドを使うととても簡単にかける。
@method('PUT')・(参考)Laravel公式 擬似フォームメソッド
(補足)PUTとPATCHの違い
PUTはすべてのデータをまるごと変更する場合に使い、PATCHは一部のデータを変更する場合に使うらしい。
ここでは、PUTとPATCHどちらを使っても同じ結果になる。
コントローラの編集
editアクションとupdateアクションを編集する。
editアクション
Productモデルの指定したidのデータを取得してビューに渡す。
ProductController.phppublic function edit($id) { $product = Product::find($id); return view('products.edit', ['product'=>$product]); }updateアクション
記述はstoreアクションとほぼ同じ。
最初にProductモデルの新規インスタンスではなく、指定したidのデータを取得する。受け取ったデータ
$request
を代入し、save
でDBに保存する。ProductController.phppublic function update(Request $request, $id) { $product = Product::find($id); $product->product_name = $request->product_name; $product->price = $request->price; $product->is_stocked = $request->stock; $product->save(); return redirect('products/'.$product->id); }
削除機能の作成
ルーティングの確認
$ php artisan route:list +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+ | | DELETE | products/{product} | products.destroy | App\Http\Controllers\ProductController@destroy | web | +--------+-----------+-------------------------+------------------+------------------------------------------------+------------+
products/{product}
にDELETEでアクセスすればデータを削除できる。削除コンポーネントを作成する
削除ボタンは編集と詳細ページに設置する。laravelの機能であるコンポーネント化し簡単に呼び出しを行う。
コンポーネントはボタンとテキストの2種類を用意する。
ファイルの作成
resources > views > componentsの配下に、ファイルを2つ作成する。
▼削除ボタンコンポーネント
delete-btn.blade.php<form action="/products/{{$product->id}}" method="post" id="delete-btn"> @csrf @method('DELETE') <input type="submit" name="" value="削除"> </form>・acrtion属性の値に
"/products/{{$product->id}}"
を設定。formはDELETEメソッドをサポートしていないため、ここではpostを指定。
・
@csrf
クロスサイトリクエストフォージェリ防止機能を追加(必須!)・
@method('DELETE')
擬似フォームメソッドでDELETEを指定。これでdeleteメソッドで通信できるようになる。▼削除テキストコンポーネント
delete-txt.blade.php<form action='/products/{{$product->id}}' method='POST' id='dlt-txt'> @csrf @method('DELETE') <a onclick='document.getElementById("dlt-txt").submit()'>削除する</a> </form>inputタグをテキストに変更するため、JavaScriptの
submit
メソッドを使用。formタグに
id="dlt-btn"
を指定し、sbumitの対象をdocument.getElementById(dlt-btn)
とする。以上でコンポーネントが完成。
componentの仕組み
前述のコードで既にcomponentの呼び出し処理は記述してあるが、componentの仕組みについて。
Laravelでは
blade.php
ファイルをコンポーネントとして呼び出すことができる。
extends
,yield
,section
の簡易的な機能のようなもの。コンポーネントの呼び出しはとても簡単で、呼び出したいところに以下のコードを記述する。
@component('ビューのパス', ['変数名'=>渡したいデータ]) @endcomponentビューのパスは相対ではなく、viewsフォルダからの絶対パスとなる。
このため、products > edit.blade.php から components >
delete-text.blade.phpを呼び出したい場合は、components.delete-txt
とする。第2引数はデータを渡したいときに使う。読み込むのみでデータを渡す必要がない場合は不要。
ブラウザの表示(削除機能の確認)
↓ 商品詳細(iPhone8)
↓ 削除
削除成功。
バリデーション、CSSの調整はないが、LaravelのCRUD操作の基本はおさえられた。
- 投稿日:2021-01-18T09:38:11+09:00
Vagrant(仮想化)でLaravel環境の構築について自分なりにまとめてみた(Windows10)
はじめに
Laravelでの環境構築の際にLaravelの公式ドキュメント様よりVagrant環境(仮想環境)で構築するよう記述されていたので私自身のアウトプットのために記事にしてみました。
目次
環境構築
Vagrantとは、ローカル環境内に仮想環境を比較的簡単に構築することだと認識しています。
詳細はIT用語辞典にて確認をお願いします。
では、環境構築についてはじめようかと思います。
まずは手順1~手順3まで入れてください。
手順1:VirtualBoxを入れる。
手順2:Vagrantを入れる。
手順3:Gitを入れる。下記コマンドは、homesteadに用いる仮想環境の下地を作成する
vagrantコマンドvagrant box add laravel/homesteadgitコマンドより、Homesteadディレクトリを作成してhomesteadを入れる。
Gitコマンドgit clone https://github.com/laravel/homestead.git Homesteadcd /Homesteadのディレクトリに入る
.bashcd /Homestead初期設定ファイルを作成(初めての場合は絶対にする)
.bash./init.sh #下記コマンドが表示されたらOK >Homestead initialized!homesteadに移動してyamlファイルを入れる。
.bashcd ~/.homestead/ vi Homestead.yaml※viは、linux上でテキストを編集するコマンドです。(類似でvimがある)
簡単なコマンド
文字の挿入:「i」
挿入から抜ける:「Esc」ボタン
保存:「:wq!」yamlファイルの編集
Homestead.yamlip: "192.168.10.10" #接続先となるIPアドレス memory: 2048 #割り当てるメモリ(MB)※2ギガこのこと cpus: 1 #同CPUのコア数 provider: virtualbox #VMのホスト authorize: ~/.ssh/id_rsa.pub #SSH公開鍵の場所 #上記の設定でhttp→httpsでも接続できるように設定しておいた方がよい #なぜなら、ajaxでの送信ができない為、今は無視してもよい keys: - ~/.ssh/id_rsa #秘密鍵の場所 folders: - map: C:\homestead\Laravel #ローカルのディレクトリ to: /home/vagrant/Code #VM上のディレクトリ sites: - map: homestead #ホスト名 to: /home/vagrant/Code/Laravel/public #web上に公開するディレクトリ(Apacheのhtdocsみたいなもん) databases: - homestead公開鍵と秘密鍵を生成する
.bashcd ~/.homestead/ mkdir ~/.ssh && cd $_ #鍵作成 ssh-keygen -b 4096 #パスフレーズを入れる・入れないは自由。鍵ファイル名はHomestead.yamlのそれと合わせるようにしてください。 Generating public/private rsa key pair. Enter file in which to save the key (xxxxx): ~/ Enter passphrase (empty for no passphrase): #2回パスワード聞かれるので適当にパスワードを入力してください ※忘れないように!! Enter same passphrase again:上記より生成されているか確認する
下記は確認コマンドより(id_rsa(秘密鍵),id_rsa.pub(公開鍵)).bashcd ~/.sshhostsファイルの書き換え(C:\Windows\System32\drivers\etc\hosts)
権限により編集できないのでテキストファイルで開きなおしてください。
hostsの書き換え方hosts#下記を追加する一番したに追加する 192.168.10.10 homestead※補足として仮に複数のアプリと連動させたい場合は、192.168.10.10 プロジェクト名 プロジェクト名1
のように引数みたいに記述すればよい。vagrantの実行
hosts#下記を追加する vagrant up※vagrant up (vagrantの起動),vagrant up --provision(起動時に起動),vagrant reload(再起動)
vagrant halt(仮想のシャッドダウン)今はこれぐらいのコマンドでよい。このようなエラーがでた場合は、gitbashの文字コードをUTF-8からshift-jisでできるようになる。
まあ「encode!」っていってのるので修正しましょー。
※Git Bashを右クリックしてoption→text→文字コード(shift-jis)と変更する。hosts#下記を追加する C:/HashiCorp/Vagrant/embedded/gems/2.2.10/gems/childprocess-4.0.0/lib/childprocess/windows/process_builder.rb:44:in `encode!': "\xE8" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to UTF-16LE (Encoding::UndefinedConversionError) from C:/HashiCorp/Vagrant/embedded/gems/2.2.10/gems/childprocess-4.0.0/lib/childprocess/windows/process_builder.rb:44:in `to_wide_string' from C:/HashiCorp/Vagrant/embedded/gems/2.2.10/gems/childprocess-4.0.0/lib/childprocess/windows/process_builder.rb:67:in `create_environment_pointer' from C:/HashiCorp/Vagrant/embedded/gems/2.2.10/gems/childprocess-4.0.0/lib/childprocess/windows/process_builder.rb:28:in `start' from C:/HashiCorp/Vagrant/embedded/gems/2.2.10/gems/childprocess-4.0.0/lib/childprocess/windows/process.rb:70:in `launch_process'これで下記URLでLaravelの画面が表示されたら完了です。
http://homestead/使ってみてわかったこと
取り敢えず、linuxコマンドに強くなるのかな~と思います。後は、簡単にアプリを配置したり削除できたりする事が可能なので便利だと思います。仮想化の勉強になるしURLも汚れないし(localhost8080はちょっと恥ずかしいかな?)以上になります。
ほとんどこの方を参考にしました
有難うございます。追記:できれば間違っている点やおかしな点があれば教えて頂けると幸いです。
参考文献