- 投稿日:2020-04-30T23:48:08+09:00
MAMP(FREE)のインストールから表示まで(MAC )
MAMPとは
MAMP(マンプ)とは、ローカル開発環境に必要なソフトウェア(Apache、MySQL、PHP)をパッケージ化したもので、macOS、Windows上で動作させることが出来る。
「Macintosh」「Apache」「MySQL」「PHP」の頭文字をとってMAMPと名付けられている。MAMPのインストール
MAMPの公式サイトよりダウンロード(https://www.mamp.info/en/)
FREE Downloadをクリック
MAMP & MAMPPRO5.7をクリック
クリックするとダウンロードが始まるので終わるまで待つ。
ダウンロードが終わったらファイルを解凍する。
続けるをクリックすると、使用許可を求められるので、特に問題なければ同意するをクリック
MAMP PROを一緒にインストールする場合はインストールをクリック。今回は、MAMP PROはインストールしないのでカスタマイズを選択し、MAMP PROのチェックを外しインストール。
何もなければ無事にインストールが終了したと思います。MAMPの起動
インストールされたMAMPを立ち上げるとこのような画面が出るので、起動するにはStart Serversをクリックします。
Apache MySQLが緑に点灯すれば起動成功です。ストップさせたい場合はStop Serversをクリックで終了します。ブラウザに表示
ブラウザを開いて「localhost」もしくは「127.0.0.1」と入力します。
このような形で表示されると無事にローカルサーバーに表示できている事が確認できるかと思います。
これから初期設定等ありますが、とりあえず今回はここまでにします。
今回初投稿で見にくいところなどあったかと思いますので、徐々に改善していきたいとおもいます。
最後まで読んでいただいてありがとうございました!!
- 投稿日:2020-04-30T23:04:08+09:00
「破壊的メソッド」はRuby用語なのか?
昨日、「データサイエンティストが知るべき破壊的メソッドのすべて」という記事を書いたのですが、友人から次のような意見を貰いました。
微妙に気になったけど、「破壊的メソッド」「非破壊的メソッド」ってプログラミング全般でなくRuby用語で、かつ、「レシーバを変更するメソッド」っていう意味じゃない?
もしあえて名前で呼ぶなら、inplace methodが正しそう。(日本語は見つからない)
https://discuss.pytorch.org/t/what-is-in-place-operation/16244
https://ja.wikipedia.org/wiki/In-placeアルゴリズム更に、例えばpandasでもinplaceという引数名が使われているので、データサイエンティスト向けならinplaceのほうが馴染みあるかもしれないとも言われました。
たしかに「破壊的」と調べて出てくる記事は、Rubyのものが多いように思います。少し気になったので、いろいろな言語のドキュメントで「破壊的(destructive)」「インプレース(in-place)」という単語で調べて比較してみました。
Pythonの場合: in-placeが優勢
ドキュメントを検索したところ、実際に「インプレース(in-place)」という単語がよく使われているようです。例えば「プログラミング FAQ」の中では次のようにあります。
文字列をインプレースに変更するにはどうしたらいいですか?¶
文字列はイミュータブルなので、それはできません。殆どの場合、組み立てたい個別の部品から単純に新しい文字列を構成するべきです。
一方で、「破壊的(destructive)」という単語も多少は使われています。例えばPython2.7のドキュメントには「破壊的に(destructively)」という単語があります。最新バージョンのドキュメントでは「消去して返します」とありますが、日本語の訳語が変わっただけでした。
集合のアルゴリズムで使われるのと同じように、
popitem()は辞書を破壊的にイテレートするのに便利です。辞書が空であれば、popitem()の呼び出しはKeyErrorを送出します。Python3.8でも「curses --- 文字セル表示を扱うための端末操作」の中に「非破壊的(non-destructive)」という単語が見つかりました。
ウィンドウを
destwinの上に重ね書き (overlay) します。ウィンドウは同じサイズである必要はなく、重なっている領域だけが複写されます。この複写は非破壊的です。少し離れた箇所に「破壊的(destructive)」もあります。
destwinの上にウィンドウの内容を上書き (overwrite) します。ウィンドウは同じサイズである必要はなく、重なっている領域だけが複写されます。この複写は破壊的です。Rubyの場合: destructive methodという用語が説明されている
Official Ruby FAQの中に「What is a destructive method?」という項目が用意されていました。日本語版の訳は見つかりませんでした。
The plain version creates a copy of the receiver, makes its change to it, and returns the copy. The “bang” version (with the !) modifies the receiver in place.
説明の中に「in place」という単語も使われています。
ドキュメントではあまりヒットしなかったので、るびまも見てみます。やはり「破壊的」という単語がよく使われています。例えば「Ruby コードの感想戦 【第 2 回】 WikiR」より。
force_encoding は ! がついていないので名前だけではわかりづらいですが、破壊的なメソッドです。 そのため、戻り値を text に代入する必要はありません。これで十分です。
「6 月 10 日 午前の部」でin-placeという単語が使われている箇所もありました。
文法上、yield が先に入って、ブロックつき引数を後で導入したとき yield が邪魔になった。あと String で、in-place で mutate するしないがごっちゃになってよくない。Perl からもってきた組み込み変数の 98% は後悔してます。
PHPの場合: 両方とも併用されている
「in-place」と「destructive」という単語が両方とも使われているようです。これらの箇所の日本語への翻訳はまだ行われていない様子?
Sorts the sequence in-place, using an optional comparator function.
注意:
This method is not destructive.
その他の言語
Rubyに影響を与えたSmalltalkも調べてみたかったのですが、はっきりしたこととは分かりませんでした。ただ、Smalltalk-72のドキュメントを見ると、non-destructiveという単語が少なくとも一箇所使われていました。
Note that you can make non-destructive text by using xor ink which complements the background so that reshowing the text crases it while restoring what was
underneath.また、基本的に変数がイミュータブルなHaskellも調べてみたのですが、destructiveが「過去の互換性を切った言語仕様のアップデート」という意味で使われているものしか見つけられなかったのと、ドキュメント自体を読むのが今の私にとっては骨が折れそうだったので諦めました。
また、Rubyでは「destructive method」という固有名詞に近い使われ方をしているのに対して、他の言語のdestructiveは一般的な形容詞として使われているように見えます。もしかすると、「破壊的メソッド」というのはRubyのコミュニティで使われ始めた言葉が、日本語でプログラミング用語として認識されて広まったものなのかもしれません。機会があればまた調べてみます。
- 投稿日:2020-04-30T22:46:23+09:00
Amazon PA-API が v5になって使えなくなったから、スクレイピングして強引にデーターを持ってくるVBAを作った話
初めに
amazonPA-APIと楽天ブックス書籍検索APIに書籍やCD、DVDの情報を取りに行き、記事の文末にアフィリエイトのリンクを貼るためのHTMLを生成するツールをPHPで作っていました。
ツールの仕様は、本の見出しやISBN-10で検索し、amazonのAPIから必要な情報を取得した後に、ISBNを持って楽天APIに行って、楽天からも書籍データーを取得します。それを規定のHTMLの指定の場所に挿入して、1つのHTMLの塊として書き出し、それをコピペして使うというものです。
商品画像や本のタイトル、著者情報や価格はAmazonから引用したもので、それらをクリックするとAmazonの商品ページにジャンプし、楽天ショッピング用のボタンもあり、それを押すと、楽天の該当商品の画面にジャンプします。
ツールが動かないとの連絡
2020年3月中旬に、このツールが動かなくなったと各部署から連絡があり、調べるとAmazon PA-APIがv5にバージョンアップしていて、
PA-API v5への移行を2020年3月9日までに実施しなかった場合、現在のPA-APIはご利用をいただけなくなりますとありました。▪️PA-API v5移行のご案内 (2020/3/9まで)
https://affiliate.amazon.co.jp/help/node/topic/GZBFW3F79Y7FADBLもともとアカウントを管理しているのは、営業部門で、我々IT部門はツールを作っただけでした。
連絡も管理者にはメールが届いていたようですが、見事に見逃していたようで、こちらには連絡が一切ありませんでした。ツールをPA-API 5.0に移行
amazonの移行ガイドには以下のように書かれています。
そのため、アカウントを移行してから新しい認証情報(AWSアクセスキーとAWSシークレットキー) を取得し、それをツールにセットしました。現在お持ちのAWS認証情報 (AWSアクセスキーとAWSシークレットキー) は PA-API 5.0では使えません。
現在AWSの認証情報をお持ちの場合は、アカウントを移行してから新しい認証情報を作ることができます。「リクエスト回数が多すぎる」というエラーで値が取れない
Error! RequestThrottled You are submitting requests too quickly. Please retry your requests at a slower rate.というエラーが出て値が取れない。
requests too quicklyとあるので時間をおいてアクセスしてもダメ!なんどやってもダメ!全然「too quickly」じゃ無いのに。そもそも1日に多くても数回しかアクセスしていない(テストでも2桁前半)のに、「requests too quickly」なら、誰が使えんねん!と思いつつググる。
以下のポリシーの変更(特に売り上げ実績のところ)のせいなのかと思いアカウントを管理している部署に問い合わせるも、売り上げはあるとの回答(額は教えてくれない)
https://affiliate.amazon.co.jp/help/node/topic/GW65C7J2CSK7CA6C2019年01月23日以降、過去30日以内のPA-API経由の売上実績(発送済み商品売上)がない場合、PA-APIへのアクセスができなくなる可能性がございます。
結局、理由がわからない。
ここで、ツールがループしてなんどもamazon PA-APIにアクセスしているのかと疑う。
スクラッチパッドでもデーターが取れない
v5.0用の認証情報 (AWSアクセスキーとAWSシークレットキー) でスクラッチパッドで書籍を検索してもデーターが取れない。
また、これでツールがループしてなんどもamazon PA-APIにアクセスしていないこが証明できた。
もうわけわからん。
amazonの担当者にメールで問い合わせ
送った内容
今週から、「Associate Tag:●●●●●●」アカウントでAPIを叩くと 「Error! RequestThrottled」とのエラーが出るようになりました。 「 You are submitting requests too quickly. Please retry your requests at a slower rate.」とありますが、多くてもアクセスは1時間に数回です。 また、ネットで調べると、規約改定により、30日間、売り上げが無いとAPIが使えなくなり、その時も上記エラーが出る。とありました。 上記のエラーはこれに該当するものでしょうか? また、ほかに原因となりそうな点がございましたらご教示いただけると幸いです。 よろしくお願い申し上げます。amazonカスタマーサービスから返ってきたのは
Amazon.co.jpアソシエイト・プログラムにお問い合わせいただき、ありがとうございます。 下記メッセージが表示される状態はAPIのサーバーに複数の同時アクセスがあり、先着順で接続処理が行われ、その中で接続出来なかった方に表示されるものとなります。 --------------------------------------------------------------------- You are submitting requests too quickly. Please retry your requests at a slower rate. --------------------------------------------------------------------- つまり、お客様以外にも多数のお客様がPA-APIのリクエストを試みている場合は上記メッセージは出やすくなるかと存じます。 1日のリクエスト可能数をご理解の上、上記メッセージが返却・表示された場合は、再度リクエストを送信いただきますようお願いいたします。 アソシエイト・プログラムをご利用いただき、ありがとうございます。この回答に対し、再度の返信
返信いただいた下記メッセージでは「お客様以外にも多数のお客様がPA-APIのリクエストを試みている場合は上記メッセージは出やすくなるかと存じます。」とありますが、これは我々だけでなく、その他の(世界中の)ユーザーも 含めてのことでしょうか。 今もAPIにアクセスを行いましたが、到達できませんでした。今週一度もAPIにアクセスできていません。 原因は、複数の同時アクセスが問題というだけでしょうか。 ご回答いただけると幸いです。よろしくお願い申し上げます。amazonカスタマーサービスからの返答
カスタマーサービスからのお知らせ Amazon.co.jpアソシエイト・プログラムにお問い合わせいただき、ありがとうございます。 下記メッセージが表示される状態はAPIのサーバーに複数の同時アクセスがあり、先着順で接続処理が行われ、その中で接続出来なかった方に表示されるものとなります。 --------------------------------------------------------------------- You are submitting requests too quickly. Please retry your requests at a slower rate. --------------------------------------------------------------------- つまり、お客様以外にも多数のお客様がPA-APIのリクエストを試みている場合は上記メッセージは出やすくなるかと存じます。 1日のリクエスト可能数をご理解の上、上記メッセージが返却・表示された場合は、再度リクエストを送信いただきますようお願いいたします。要するに、世界中から同時にAPIにアクセスする数が単純に多いから、ということ???
諦めて、ツールを作り直す
もはや、APIから情報を取ることを諦め、該当の商品ページのHTMLからスクレイピングして必要なデーターを取ってこれるツールを作成することに決めました。
ツールを何で作ろうかと考えたのだが、Excel VBAにしました。
ググると、amazon PA-APIの問題は時間が解決してくれるとの情報がちらほらあったのと、
phpを使っているサーバーが古いということもあり、
会社のAWSにインスタンス立てて、そこでもよかったのですが、お金もかかるし申請が面倒なので、どの環境でも動く「Excel VBA」で作りました。
基本設計
Dim isbn As String Dim ans As String Dim doc As New XmlScraping isbn = InputBox("ISBN-10を入力ください", "") ans = "https://www.amazon.co.jp/dp/" & isbn If ans <> "" Then doc.gotoPage ans End IfユーザーにinputboxからISBN-10を入力してもらい、その値を、
https://www.amazon.co.jp/dp/の文末に追加し、変数ansに格納。
gotoPageでそのページに移動し、データーを変数docに格納する。後は、ワークシートの「tool」をターゲットに値を貼り付けていく
Worksheets("tool").Select numberTitles = doc.css(".content ul li").count Cells(1, 1) = "タイトル" Cells(1, 2) = doc.css("#productTitle").index(0).text Cells(2, 1) = "画像URL" Cells(2, 2) = doc.css("#img-canvas").index(0).html Cells(3, 1) = "価格" Cells(3, 2) = doc.css(".a-color-price").index(0).text Cells(3, 2) = Replace(Cells(3, 2), "¥", "") Cells(3, 2) = Replace(Cells(3, 2), "\", "") For i = 1 To numberTitles - 1 If InStr(doc.css(".content ul li").index(i).text, "出版社") > 0 Then Cells(5, 2) = doc.css(".content ul li").index(i).text Cells(5, 2) = Replace(Cells(5, 2), "出版社: ", "") Cells(5, 1) = "出版社" ElseIf InStr(doc.css(".content ul li").index(i).text, "ISBN-10") > 0 Then Cells(6, 2) = doc.css(".content ul li").index(i).text Cells(6, 2).NumberFormatLocal = "@" Cells(6, 2) = Replace(Cells(6, 2), "ISBN-10: ", "") Cells(6, 1) = "amazonコード" End If Next i後は、正規表現で必要な値を取り出していく。例えば以下。
Dim x As String Dim regx As RegExp Dim m As Match Dim ms As MatchCollection Set regx = New RegExp regx.Pattern = "https:\/\/images-.{2}\.ssl-images-amazon\.com\/images\/.*\.jpg" regx.Global = True Set ms = regx.Execute(Cells(2, 2)) For Each m In ms Cells(2, 2) = m Next Set regx = Nothing Cells(2, 2) = Replace(Cells(2, 2), "https://images-fe.ssl-images-amazon.com/images/I/", "")同じようにISBNを使って楽天の該当商品まで行き、値を取って正規表現で綺麗にしてあげればOK。
ans2 = "https://books.rakuten.co.jp/search?sitem=" & Cells(6, 2) If ans2 <> "" Then doc2.gotoPage ans2 End If Cells(7, 2) = doc2.css(".rbcomp__item-list__item__image").index(0).html Dim x2 As String Dim regx2 As RegExp Dim m2 As Match Dim ms2 As MatchCollection Set regx2 = New RegExp regx2.Pattern = "https:\/\/books\.rakuten\.co\.jp\/rb\/.{8}\/" regx2.Global = True Set ms2 = regx2.Execute(Cells(7, 2)) For Each m2 In ms2 Cells(7, 2) = m2 Next Cells(7, 2) = Replace(Cells(7, 2), "https://books.rakuten.co.jp/", "") Set regx2 = NothingASINの場合は楽天の商品と紐付かない
商品コードがISBNの場合はそれをアマゾンにも楽天にも持っていいって使えるのだが、ASINの場合は紐付かない。
色々考えたんですが結局、ユーザーにASINとJANを入力してもらう事にしました。以上。
- 投稿日:2020-04-30T22:14:10+09:00
PHP 正規表現
前提
PHPにおける正規表現について記述していきます。
本題
行頭にマッチする
^ #例:^hello。行頭にhelloの文字列はこのパターンにマッチする。行末にマッチする
$ #例:hello$。行末にhelloの文字列はこのパターンにマッチする。改行以外の任意の1文字にマッチする
. #例:1、hello.world。hello worldやhello-worldなどの文字列はこのパターンにマッチする。英大文字A-Zの任意1文字にマッチする
[A-Z] #例:1、a[A-Z]c。aAc,aBc,…,aZcなどの文字列はこのパターンにマッチする。英小文字a-zの任意1文字にマッチする
[a-z] #例:1、a[a-z]c。aac,abc,…,azcなどの文字列はこのパターンにマッチする。数字0-9の任意1文字にマッチする
[0-9] #例:1、a[0-9]c。a0c,a1c,…,a9cなどの文字列はこのパターンにマッチする。角括弧内に含まれない1文字にマッチする
[^] #例:1、[^abc]。a、b、c以外の文字はこのパターンにマッチする。直前の表現を0回以上繰り返す
* #例:a、ab、abb、abbbなどはマッチする。直前の表現を1回以上繰り返す
+ #例:ab、abb、abbbなどの文字列はこのパターンにマッチする。
- 投稿日:2020-04-30T21:33:12+09:00
Laravelのルーティング基本
web.php
routes\web.php
ルーティングに関する情報の記載。記入内容
・アドレス指定
・コントローラを指定
・コントローラのメソッドを指定コントローラ
Http\Controllers\コントローラ名
php artisan make::controller コントローラ名で作成する。
作成されたコントローラは、Http\Controllers\コントローラ名 に作成される。useでrequrestやresponseやフォームリクエスト等のクラスをインポートし、メソッドの引数で読み込むことで利用可能にする。
return view('テンプレートフォルダ名', 渡す値);この第1引数に読み込むテンプレートフォルダ名を記入。helloフォルダのindexファイルの場合は、hello.indexと記入する。
第2引数の値は、配列。この値をテンプレートに渡す。Bladeテンプレート
resourdes\views\フォルダ名.blade.php
{{$変数名}}で、コントローラ等から渡された値を表示できる。
- 投稿日:2020-04-30T21:07:30+09:00
[WIP] ヘルパ DI クラス一覧
以下は全ヘルパと実際のクラスまたは代替の一覧です。
配列とオブジェクト
helper class method Arr::* Illuminate\Support\Arr * data_fill Illuminate\Support\Arr add ※1 data_get Illuminate\Support\Arr get ※1 data_set Illuminate\Support\Arr set ※1 head Illuminate\Support\Arr first ※1 last Illuminate\Support\Arr end ※1 ※1 代替。同じではない。
パス
helper class method app_path Illuminate\Foundation\Application path base_path Illuminate\Foundation\Application basePath config_path Illuminate\Foundation\Application configPath database_path Illuminate\Foundation\Application databasePath mix Illuminate\Foundation\Mix そのまま呼ぶ(__invoke) public_path Illuminate\Foundation\Application publicPath resource_path Illuminate\Foundation\Application resourcePath storage_path Illuminate\Foundation\Application storagePath 文字列
helper class method __ Illuminate\Translation\Translator get class_basename e preg_replace_array Str::* Illuminate\Support\Str * trans(引数なし) Illuminate\Translation\Translator trans(引数あり) Illuminate\Translation\Translator get trans_choice Illuminate\Translation\Translator choice URL
helper class method action Illuminate\Routing\UrlGenerator action asset Illuminate\Routing\UrlGenerator asset route Illuminate\Routing\UrlGenerator route secure_asset Illuminate\Routing\UrlGenerator asset(第2引数に true を指定) secure_url Illuminate\Routing\UrlGenerator to(第3引数に true を指定) url(引数なし) Illuminate\Routing\UrlGenerator url(引数あり) Illuminate\Routing\UrlGenerator to その他
helper class method abort Illuminate\Foundation\Application abort abort_if Illuminate\Foundation\Application abort と if 文など abort_unless Illuminate\Foundation\Application abort と if 文など app(引数なし) Illuminate\Foundation\Application app(引数あり) Illuminate\Foundation\Application make auth(引数なし) Illuminate\Auth\AuthManager auth(引数あり) Illuminate\Auth\AuthManager guard back Illuminate\Routing\Redirector back bcrypt Illuminate\Contracts\Hashing\Hasher driver('bcrypt')->make blank broadcast Illuminate\Contracts\Broadcasting\Factory event cache(引数なし) Illuminate\Cache\CacheManager cache(引数あり) Illuminate\Cache\CacheManager get または put class_uses_recursive collect Illuminate\Support\Collection make config(引数なし) Illuminate\Config\Repository config(引数あり) Illuminate\Config\Repository get または set cookie(引数なし) Illuminate\Contracts\Cookie\Factory cookie(引数あり) Illuminate\Contracts\Cookie\Factory make csrf_field csrf_token Illuminate\Session\SessionManager token dd decrypt Illuminate\Encryption\Encrypter decrypt dispatch dispatch_now Illuminate\Contracts\Bus\Dispatcher dispatchNow dump encrypt Illuminate\Encryption\Encrypter encrypt env Illuminate\Support\Env get event Illuminate\Events\Dispatcher dispatch factory Illuminate\Database\Eloquent\Factory of filled info Illuminate\Log\LogManager info logger(引数なし) Illuminate\Log\LogManager logger(引数あり) Illuminate\Log\LogManager debug method_field now Illuminate\Support\DateFactory now old Illuminate\Http\Request old optional policy Illuminate\Contracts\Auth\Access\Gate getPolicyFor redirect(引数なし) Illuminate\Routing\Redirector redirect(引数あり) Illuminate\Routing\Redirector to report Illuminate\Contracts\Debug\ExceptionHandler report request(引数なし) Illuminate\Http\Request request(引数あり) Illuminate\Http\Request only またはプロパティアクセス (__get) rescue resolve Illuminate\Foundation\Application make response(引数なし) Illuminate\Contracts\Routing\ResponseFactory response(引数あり) Illuminate\Contracts\Routing\ResponseFactory make retry session(引数なし) Illuminate\Session\SessionManager session(引数あり) Illuminate\Session\SessionManager get または put tap throw_if throw_unless today Illuminate\Support\DateFactory today trait_uses_recursive transform validator(引数なし) Illuminate\Contracts\Validation\Factory validator(引数あり) Illuminate\Contracts\Validation\Factory make value view(引数なし) Illuminate\Contracts\View\Factory view(引数あり) Illuminate\Contracts\View\Factory make with
- 投稿日:2020-04-30T21:00:59+09:00
laravelで、LoginController.phpがない
php artisan make:model auth
を実行し、成功したのに、ディレクトリ app/Http/Auth の中に、LoginController.phpのファイルがありません。
ctrl+Hを押下しましたが、表示されません。
なぜでしょうか。
- 投稿日:2020-04-30T20:41:38+09:00
Laravelでビュー描画前処理を行う
Laravelのビュー描画前処理
Laravelのビュー描画前処理について書いていきます
Laravelではビューが描画される時に呼び出される処理を作成しておくことができます前提条件
下記前回記事の続きです
Laravelのレイアウトエンジンを使う
本記事は上記が完了している前提で書かれています
上記記事で使用したプロジェクトを引き続き使用していきますControllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにviewComposeメソッドを追記
public function viewCompose()
{
$data = ['key' => 123456789.123456];
return view('sample.viewCompose', $data);
}
(2) /sample/routes/web.phpに下記を追記
Route::get('sample/view-compose', 'SampleController@viewCompose');viewの作成
/sample/resources/views/sample/viewCompose.blade.phpファイル作成
viewCompose.blade.php<html> <head> <title>sample</title> </head> <body> {{$key}} </body> </html>描画前処理の作成
(1) /sample/app/Http/ViewComposersフォルダ作成
(2) /sample/app/Http/ViewComposers/SampleComposer.phpファイル作成SampleComposer.php<?php namespace App\Http\ViewComposers; use Illuminate\View\View; class SampleComposer { public function compose(View $view) { $view->with('key', number_format($view->getData()['key'], 2, '.', ',')); } }描画前処理が呼び出されるように登録する
(1) /sample/app/Providers/ViewComposerServiceProvider.phpファイル作成
ViewComposerServiceProvider.php<?php namespace App\Providers; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; class ViewComposerServiceProvider extends ServiceProvider{ public function boot() { View::composer( 'sample.viewCompose', 'App\Http\ViewComposers\SampleComposer' ); } public function register() { } }(2) /sample/config/app.php内のproviders配列に下記を追記
ViewComposerServiceProvider.php‥‥ 'providers' => [ ‥‥ App\Providers\ViewComposerServiceProvider::class, ], ‥‥これでレンダリングの際に
ViewComposerServiceProvider#boot→View::composer→SampleComposer#compose
が実行されます動作確認
http://localhost/laravelSample/sample/view-compose実行結果
123,456,789.12
- 投稿日:2020-04-30T20:22:47+09:00
ブラックボックスの罠 Guzzlehttpで解決しなかった文字化けが、cURLにしたらサクッと解決した
はじめに
APIを使う側の場合、サンプルコードなどがあれば、まずはそれに忠実な操作、処理をして疎通を確認する。
ライブラリは便利だが、ブラックボックスになる面もあるのでトラブルの原因把握や問題解決から遠くなる危険がある。
ソースが公開されているのなら、それを辿るがよろし。何が起こったか?
某決済業者のAPIを使い銀行振込用のバーチャル口座のリクエストを送った時に、全角文字が含まれているとその部分だけ文字化けが発生した。
なお、クレジットカード払いなどの別手段では発生しなかった。参考:当方サーバ側環境
- PHP7.X系
- Laravel5.X系
- guzzlehttp6.5.2
- システム内のデフォルトの文字コードはUTF-8
PHPやLaravelそのものは関係なくて、guzzleの中の問題(断言)
問題調査で発生したこと
途方に暮れる
文字コードをSJISに変換する必要がある
→変換しても、文字化けた後の内容が変わっただけで根本的な解決にはならなかった。リクエストを送るときのContent-Typeが問題
→ Postmanなどの、API送信ツールを使ったが、文字化けしていた。そのほか、URLエンコードした値を送信など様々な事を試みたがダメだった。
なお、業者がサンプルで提供している(本案件では採用しない)決済モジュールを動かしてみたら無事文字化けしなかった。
cURLで実装してみたら、問題なく送信できた!
決済モジュールのコードを辿ってみたら、全角文字列はSJISに変換する。
curl_setoptで、様々な設定をしたのちリクエストを送信。結局、いかにもありそうなcURLのサンプルコードを書いて動かしたら成功した。
cURLでリクエストを送る//前提:こんな感じのリクエスト値が存在する(実運用時には、他のメソッドで加工するケースが多いと思います) $params = [ 'access_code' => 'unique_access_code', 'price' => '3980', 'customer_name' => mb_convert_encoding('バカ殿様','SJIS','UTF-8') ]; //POSTする値を $post_fields = http_build_query($params); // APIのリクエスト先URL。各自の環境に置き換えて考えてください $request_url = "https://example.com/path/to/api/receiver"; //まず、オブジェクトを作る $curl = curl_init(); //リクエスト形式、戻り値の存在、リクエスト先などを設定する。 //URLは適宜考えてください curl_setopt($curl,CURLOPT_URL,$request_url); curl_setopt($curl,CURLOPT_POST,true); curl_setopt($curl,CURLOPT_RETURNNUMBER,true); //リクエスト先の仕様にそろえて、URLエンコード済の値をセットする curl_setopt($curl,CURLOPT_POSTFIELDS,$post_fields); //ここから下、cURLのリクエスト送信とレスポンス $response = curl_exec( $curl ); $curlinfo = curl_getinfo( $curl ); curl_close( $curl );顧客名は、時事ネタです(合掌)
犯人は(たぶん)お前だ!
guzzlehttp/guzzle/src/Client.php
applyOptionsメソッド内にてhttp_build_queryを使っていたが
ここでクエリを編集する部分に問題があるようだ。guzzlehttp/guzzle/src/Client.php// if (isset($options['query'])) { $value = $options['query']; if (is_array($value)) { $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);//この行に問題あり } if (!is_string($value)) { throw new \InvalidArgumentException('query must be a string or array'); } $modify['query'] = $value; unset($options['query']); }PHPリファレンスのhttp_build_queryのページによれば 4つ目の引数enc_typeは
デフォルトでは
PHP_QUERY_RFC1738つまり、RFC1738 に従ってエンコードされる。でよかったにも関わらず 上記ソースの抜粋のようにPHP_QUERY_RFC3986でエンコードされていた…これが原因のようだ。参考
PHP:http_build_query
- 投稿日:2020-04-30T19:43:56+09:00
Laravelのレイアウトエンジンを使う
Laravelのレイアウト処理
Laravelのレイアウト処理について書いていきます
viewsフォルダ配下に作成したblade.phpファイルを組み合わせて1つのビューとして処理をするものです前提条件
下記前回記事の続きです
Laravelのテンプレートエンジンを使う
本記事は上記が完了している前提で書かれています
上記記事で使用したプロジェクトを引き続き使用していきますControllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにchildメソッドを追記
public function child()
{
$data = ['msgList' => ["msg1", "msg2"]];
return view('sample.child', $data);
}
(2) /sample/routes/web.phpに下記を追記
Route::get('sample/child', 'SampleController@child');viewの作成
(1) /sample/resources/views/layoutフォルダ作成
(2) /sample/resources/views/layout/parent.blade.phpファイル作成parent.blade.php<html> <head> <title>@yield('title')</title> </head> <body> <ul> @section('menu') <li>共通メニュー1</li> <li>共通メニュー2</li> @show </ul> <div> @yield('content') </div> </body> </html>(3) /sample/resources/views/componentフォルダ作成
(4) /sample/resources/views/component/msgList.blade.phpファイル作成msgList.blade.php<div>{{ $msgTitle }}</div> @foreach ($msgList as $msg) <div>{{ $msg }}</div> @endforeach {{ $addMsg }}(5) /sample/resources/views/sample/child.blade.phpファイル作成
child.blade.php{{-- resources/views/layout/parent.blade.phpを使うのでlayout.parentにする --}} @extends('layout.parent') {{-- parent.blade.phpの@yield('title')を置換する --}} @section('title', 'Sample@tpl') {{-- parent.blade.phpの@section('menu')から@showまでを置換する --}} @section('menu') {{-- parent.blade.phpの@section('menu')から@showまでを描画する --}} @parent {{-- child.blade.php独自のメニューを描画する --}} <li>独自メニュー1</li> <li>独自メニュー2</li> @endsection {{-- parent.blade.phpの@yield('content')を置換する --}} @section('content') <p>child.blade.phpのコンテンツ</p> {{-- resources/views/component/msgList.blade.phpを描画する --}} @component('component.msgList', ['msgTitle' => 'コンポーネントタイトル', 'msgList' => $msgList]) @slot('addMsg') <div>addMsg1</div> <div>addMsg2</div> @endslot @endcomponent {{-- resources/views/component/msgList.blade.phpを描画する --}} @include('component.msgList', ['msgTitle' => 'インクルードタイトル', 'msgList' => $msgList, 'addMsg' => '<div>addMsg1</div><div>addMsg2</div>']) @endsection動作確認
http://localhost/laravelSample/sample/tpl実行結果
● 共通メニュー1 ● 共通メニュー2 ● 独自メニュー1 ● 独自メニュー2 child.blade.phpのコンテンツ コンポーネントタイトル msg1 msg2 addMsg1 addMsg2 インクルードタイトル msg1 msg2 <div>addMsg1</div><div>addMsg2</div>
- 投稿日:2020-04-30T19:16:18+09:00
Laravelのテンプレートエンジンを使う
Laravelの描画処理
Laravelの描画処理を行うbladeテンプレートエンジンの使い方を書いていきます
@と様々な予約語を組み合わせることでいろいろな描画処理をすることができます前提条件
下記前回記事の続きです
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っていますControllerにメソッド追加
/sample/app/Http/Controllers/SampleController.phpにtplメソッドを追記
public function tpl()
{
$data = ['val' => 2,
'parentList' => ['key1' => 1],
'list' => ['key1' => 1, 'key2' => 2, 'key3' => 3],
'emptyList' => []
];
return view('sample.tpl', $data);
}
/sample/routes/web.phpに下記を追記
Route::get('sample/tpl', 'SampleController@tpl');viewの作成
- /sample/resources/views/sample/tpl.blade.phpファイル作成
tpl.blade.php<html> <head> <title>sample</title> </head> <body> {{-- コメント --}} {{-- {!! !!}はエスケープしないデータの表示 --}} <div>[{!! '@php' !!}]</div> @php $tplVal = 10; echo '<div>' . $tplVal . '</div>'; @endphp <br> <div>[echo]</div> <div>{{ $val }}</div> <br> <div>[if]</div> @if ($val === 1) <div>1</div> @elseif ($val === 2) <div>2</div> @else <div>else</div> @endif <br> <div>[switch]</div> @switch($val) @case(1) <div>1</div> @break @case(2) <div>2</div> @break @default <div>default</div> @endswitch <br> <div>[unless]</div> @unless (true) <div>true</div> @else <div>false</div> @endunless <br> <div>[isset]</div> @isset($list['key1']) <div>isset true</div> @else <div>isset false</div> @endisset <br> <div>[empty]</div> @empty($list['key1']) <div>empty true</div> @else <div>empty false</div> @endempty <br> <div>[for]</div> @for ($i = 0; $i < 10; $i++) @if ($i == 1) @continue @endif <div>{{ $i }}</div> @if ($i >= 3) @break @endif @endfor <br> <div>[foreach]</div> @foreach ($list as $listKey => $listVal) @if ($listVal == 1) @continue @endif <div>{{ $listKey }}:{{ $listVal }}</div> @if ($listVal >= 3) @break @endif @endforeach <br> <div>[forelse]</div> @forelse ($emptyList as $listKey => $listVal) <div>{{ $listKey }}:{{ $listVal }}</div> @empty <div>空っぽのリストです</div> @endforelse <br> <div>[while]</div> @php $whileIndex = 0; @endphp @while ($whileIndex <= 3) <div>{{ $whileIndex }}</div> @php $whileIndex++; @endphp @endwhile <br> <div>[$loop]</div> @foreach ($parentList as $parentListKey => $parentListVal) <div>parent:{{ $parentListKey }}:{{ $parentListVal }}</div> @foreach ($list as $listKey => $listVal) <div>child:{{ $listKey }}:{{ $listVal }}</div> <div>$loop->index: {{ $loop->index }}</div> <div>$loop->iteration:{{ $loop->iteration }}</div> <div>$loop->remaining:{{ $loop->remaining }}</div> <div>$loop->count: {{ $loop->count }}</div> <div>$loop->first: {{ $loop->first }}</div> <div>$loop->last: {{ $loop->last }}</div> <div>$loop->even: {{ $loop->even }}</div> <div>$loop->odd: {{ $loop->odd }}</div> <div>$loop->depth: {{ $loop->depth }}</div> <div>$loop->parent->index: {{ $loop->parent->index }}</div> <div>$loop->parent->iteration:{{ $loop->parent->iteration }}</div> <div>$loop->parent->remaining:{{ $loop->parent->remaining }}</div> <div>$loop->parent->count: {{ $loop->parent->count }}</div> <div>$loop->parent->first: {{ $loop->parent->first }}</div> <div>$loop->parent->last: {{ $loop->parent->last }}</div> <div>$loop->parent->even: {{ $loop->parent->even }}</div> <div>$loop->parent->odd: {{ $loop->parent->odd }}</div> <div>$loop->parent->depth: {{ $loop->parent->depth }}</div> @if ($listVal >= 2) @break @endif @endforeach @endforeach <br> </body> </html>動作確認
http://localhost/laravelSample/sample/tpl実行結果
[@php] 10 [echo] 2 [if] 2 [switch] 2 [unless] false [isset] isset true [empty] empty false [for] 0 2 3 [foreach] key2:2 key3:3 [forelse] 空っぽのリストです [while] 0 1 2 3 [$loop] parent:key1:1 child:key1:1 $loop->index: 0 $loop->iteration:1 $loop->remaining:2 $loop->count: 3 $loop->first: 1 $loop->last: $loop->even: $loop->odd: 1 $loop->depth: 2 $loop->parent->index: 0 $loop->parent->iteration:1 $loop->parent->remaining:0 $loop->parent->count: 1 $loop->parent->first: 1 $loop->parent->last: 1 $loop->parent->even: $loop->parent->odd: 1 $loop->parent->depth: 1 child:key2:2 $loop->index: 1 $loop->iteration:2 $loop->remaining:1 $loop->count: 3 $loop->first: $loop->last: $loop->even: 1 $loop->odd: $loop->depth: 2 $loop->parent->index: 0 $loop->parent->iteration:1 $loop->parent->remaining:0 $loop->parent->count: 1 $loop->parent->first: 1 $loop->parent->last: 1 $loop->parent->even: $loop->parent->odd: 1 $loop->parent->depth: 1
- 投稿日:2020-04-30T18:33:24+09:00
Laravel Dump Server インストールエラー Argument 1 passed to Symfony\Component\VarDumper\Server\Connection::__construct() must be of the type string
https://github.com/beyondcode/laravel-dump-server Laravel Dump Serverのライブラリをインストールしようとしたところ謎のエラーが発生してしまいました。
環境
- PHP 7.4.5
- Laravel 7.5.1
- Laravel Dump Server 2.7.0
問題
$ composer require --dev beyondcode/laravel-dump-server Using version ^1.4 for beyondcode/laravel-dump-server ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Nothing to install or update Package zendframework/zend-code is abandoned, you should avoid using it. Use laminas/laminas-code instead. Package zendframework/zend-eventmanager is abandoned, you should avoid using it. Use laminas/laminas-eventmanager instead. Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi In Connection.php line 32: Argument 1 passed to Symfony\Component\VarDumper\Server\Connection::__const ruct() must be of the type string, null given, called in /work/backend/vend or/beyondcode/laravel-dump-server/src/DumpServerServiceProvider.php on line 49 Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1 Installation failed, reverting ./composer.json to its original content.インストールに失敗してちょっとビビリました。
対策
https://github.com/beyondcode/laravel-dump-server/issues/48
こちらのイシューを見たところ、キャッシュが悪さしてるようです。
$ rm bootstrap/cache/config.phpキャッシュファイルを削除して、再度インストールしなおせばokです。
$ composer require --dev beyondcode/laravel-dump-server
- 投稿日:2020-04-30T18:04:59+09:00
CodeIgniter4でDB接続まで
インストール〜環境設定まではこちらをご覧ください。
DB接続テストの前にコントローラについてかんたんに説明
あなたのホストは
http://exapmle.com/だと仮定します。まずは、ブラウザでCI4のトップページが見えている状態にしてください。
そして、現在はci4tsetのディレクトリ内にいると仮定します。ディレクトリの構成(今回出てくるファイルのみ表示)/home/ci4test ├── .env <-- 前回作った環境設定ファイル ├── app │ └── Controllers │ └── Home.php <-- 今回操作するファイル ├── htdocs <-- 前回書き換えたドキュメントルート │ └── index.php └── writableこのページは
app/Controllers/Home.phpのコントローラで動いています。
CI4ではControllerディレクトリ配下の(拡張子を除いた)ファイル名=クラス名=URLのパスの第一階層というルールで動作しています。URLはどうなっているのか?
apacheでmod_rewriteが有効ならば、
htdocs/.htaccessが適切にURLの書き換えを行ってくれます。
この場合は、
http://example.com/コントローラのクラス名/メソッド名/[引数1/[引数2/]...]
という形でアクセスできます。無効の場合は
http://example.com/index.php/コントローラのクラス名/メソッド名/[引数1/[引数2/]...]
という形になります。
この辺はCI3の仕組みがそのまま踏襲されています。なぜトップページが
Home.phpなのか?これは
app/Config/Routes.phpにHome.phpのHomeクラスのindexというメソッド(関数)が/だぞという定義が記述してあるからなのですが、この辺は今回は割愛します。
(ここらへんのRoutingの仕組みはCI3とほぼ同じです)そしてCIのルーティングに不慣れな人は面食らうかもしれませんが、現在の設定において
http://exapmle.com/(クラス名、メソッド名が省略)
は
http://exapmle.com/Home(メソッド名が省略)
であり
http://exapmle.com/Home/index(両方ちゃんと表記したもの)
でもあり、これはすべて同じページを指します。この辺のURLの記述ルールは頭に入れておいたほうがいいと思います。
接続テスト
いよいよDBに接続するテストをしてみます。
まず
app/Controllers/Home.phpのコントローラをエディタで開いてください。
ファイルのソースは次のような感じになっているはずです。app/Controllers/Home.php<?php namespace App\Controllers; class Home extends BaseController { public function index() { return view('welcome_message'); } //-------------------------------------------------------------------- }ここに次のメソッドを追加してください。
app/Controllers/Home.php<?php namespace App\Controllers; use Config\Database; class Home extends BaseController { public function index() { return view('welcome_message'); } //-------------------------------------------------------------------- public function connectionTest() { $db = Database::connect(); echo "このDBのテーブル=" . implode( ',' , $db->listTables() ); return; } }動作をチェックするには
http://example.com/Home/connectionTest/にアクセスしてください。
すでにDBが存在し、何がしかのテーブルがあれば、そのDBのすべてのテーブル名がカンマ区切りで表示されます。
テーブルがない場合はこのDBのテーブル=のみが表示されるはずです。
もしDBが存在しない場合は、DBドライバがSQLite3以外の場合はエラー画面が表示されます。話が少しそれますが、
SQLite3の場合、DBが存在しないときは.envファイルのdatabase.default.databaseで設定された名前のSQLite3のDBファイルが作られます。このパラメータはのパスを省略した場合ドキュメントルート直下にDBファイルが生成されます。
なお、このディレクトリが書込み可能でない場合はエラーになります。
このファイル名はもちろん絶対パスや、ドキュメントルートを起点とした../writable/ci4test.dbのような相対パスで記述も可能です。照合順序も設定可能です
MySQLで文字コードや照合順序を指定する場合は、
.envに.envdatabase.default.charset = utf8mb4 あるいは utf8 など Collationに合わせた文字コード database.default.DBCollat = utf8mb4_general_ci や utf8_general_ci などお好みの照合順序を記述することで指定した文字コード及び照合順序で接続が可能になります。
次回はDBForgeを利用してDB自体を作る方法を解説したいと思います。
- 投稿日:2020-04-30T16:10:01+09:00
PHPでのMySQL (データベース)接続 PDO
PDOとは
PHP Data Objectsrの略称
PHPからデータベースのアクセスを抽象的にしてくれるものPHPからMySQLに接続するコード例(SELECT文)
<?php $mysql = 'mysql:host=localhost;dbname=xxxxxx,charet=utf8'; //xxxxxx === 自分のmysql中の接続したいデータベース名 $user = 'xxxxxx'; //xxxxxx === 自分のmysqlユーザー名 $passwoad = 'xxxxxx'; //xxxxxx === 自分のmysqlパスワード try { $db = new PDO($mysql, $user, $passwoad); $select = "SELECT * FROM" ; $res = $db->query($select); } catch (PDOException $e) { echo '接続エラー: ' . $e->getMessage(); } ?>
- 投稿日:2020-04-30T14:39:20+09:00
注意!あなたのWordPressも狙われている!?侵入手口と挙動について
皆さんが当たり前のように使っているWordPressには,実は脅威が存在します。
乗っ取られると素人ではなかなか解析できないような複雑な改ざんが行われて,復元しないとページが見られなくなります。
今回はそのハッキングの一例を取り上げます。
「こっちはセキュリティ対策してるから大丈夫」ってわけにはいかないみたいですよ...まえがき
該当する事例が前にあったようです。
https://qiita.com/mikkame/items/eec33df6863ed81740c2侵入経路
不明。
どこから入ってきたのかは分かりませんが,恐らくテーマやプラグインを脆弱性を突きXSSを利用してPHPコードを実行させて環境を整えたと見られます。挙動
この例としては
- /wp-load.php
- /wp-blog-header.php
- /index.php
- /wp-content/themes/twentyfifteen/inc/index.php
- /wp-content/themes/calliope/inc/index.php
が不正に書き換えられました。
何をされた?
/index.phpには,偽のサイトマップをGoogleなどに返す機能,ハッカー側がハッキングを完了したことを確認するために自らをGoogle検索してハッキングされているかを確かめる機能,botには普通のサイトのように見せかける機能などが追加されます。
一番危ないのが Twenty Fifteenのindex.phpです。
こちらをご覧ください。
なんと,ハッカーが使う隠しファイルマネージャーが用意されていたのです。
このファイルマネージャーはやけに高機能で,パーミッションの変更,ファイルのアップロード,さらにはローカルコンピューターへのアクセスも可能になっています。
これは非常に危ない脆弱性であり,WordPressを使っている皆さんは注意が必要です。侵入されないようにやっておくこと
まず大事なのは WordPressのアップデート です。
プラグインは定期的に更新する,評判の良くないものは使わない,テーマも定期的に更新する,そしてなにより,WordPressのシステムを最新に保つことが必要と言えます。おわりに
何かこの事に関して知っていることがあれば,ご教授ください。
- 投稿日:2020-04-30T11:03:31+09:00
raspberrypiとESP32を使った自分でIoTプラットホーム作成(その2)~ESP32設定編Lチカ
ESP32の設定
家に転がっていたESP32の動作確認をしました。
Arduino-IDE ver1.8.10を使ってESP32ボードを認識させて下記コードを実行します。
LEDが点滅したら成功です。LEDの+と接続するpinの場所は任意です。ちなみにLEDが壊れていて2回目で成功しました。
void setup() { // put your setup code here, to run once: pinMode(33,OUTPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(33,HIGH); delay(500); digitalWrite(33,LOW); delay(500); }
- 投稿日:2020-04-30T09:00:51+09:00
Laravel バリデーションを設定する ~コントローラ編~
目的
- 入力値をDBに保存する際にアプリケーション側でそのデータが要件を満たしているのかをフィルターする仕組みを実装する
実施環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.3) ハードウェア MacBook Pro (16-inch ,2019) プロセッサ 2.6 GHz 6コアIntel Core i7 メモリ 16 GB 2667 MHz DDR4 グラフィックス AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB
- ソフトウェア環境
項目 情報 備考 PHP バージョン 7.4.3 Homwbrewを用いて導入 Laravel バージョン 7.0.8 commposerを用いて導入 MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いて導入 説明に関する前提の説明
- 下記の方法、またはそれに準ずる方法でLaravelの環境を構築していること。
- Laravelのアプリケーションが存在すること。
説明に関する前提のコード
- 下記のような「ビューでの入力値をDBに格納する処理」が存在する事を前提として説明を行う。
ルーティングファイル
web.php//入力フォームを表示する Route::get('/new', 'ContentController@new'); //入力値を受け取ってDBに保存する Route::post('/create', 'ContentController@create');コントローラファイル(当該アクション部分のみ記載する)
ContentController.php//入力フォームを表示する contentディレクトリのnew.blade.phpを表示する public function new() { return view('content.new'); } //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する public function create(Request $request) { //受け取った値を連想配列に格納 $notice_info = $request->all(); //DBへの登録処理 }ビューファイル
content/new.blade.php<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="/create" method="POST"> <input type="text" name="input_content"> <input type="submit" value="送信"> </form> </body> </html>実施方法概要
- コントローラにバリデーションを記載する方法をまとめる。
- バリデーションルールの設定
- バリデーション本体の記載
- 確認
実施方法詳細
バリデーションルールの設定
- 下記のようにコントローラに記載してバリデーションルールを定義する。
- バリデーション内容は「空状態での送信をブロックする」ものとする
バリデーションルールに引っかかった場合、
/newのページ(入力を行って送信ボタンをクリックしたページ)にリダイレクトされるようにする。ContentController.php//入力フォームを表示する contentディレクトリのnew.blade.phpを表示する public function new() { return view('content.new'); } //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する public function create(Request $request) { //バリデーションのルール設定 $rules = [ //'ビューのinput要素のnameで指定したキーの名前' => ['バリデーションのルール'],のように記載する、requiredは空の状態での送信をブロックするルールである 'input_content' => ['required'], ]; //受け取った値を連想配列に格納 $notice_info = $request->all(); //DBへの登録処理 }バリデーション本体の記載
バリデーションの命令を記載する
ContentController.php//入力フォームを表示する contentディレクトリのnew.blade.phpを表示する public function new() { return view('content.new'); } //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する public function create(Request $request) { //バリデーションのルール設定 $rules = [ //'ビューのinput要素のnameで指定したキーの名前' => ['バリデーションのルール'],のように記載する、requiredは空の状態での送信をブロックするルールである 'input_content' => ['required'], ]; //下記のように記載してバリデーションを設定する //$this->validate(ビューのform要素から送られた値が格納された変数$request, バリデーションルールが格納された変数$rules);のように記載する $this->validate($request, $rules); //受け取った値を連想配列に格納 $notice_info = $request->all(); //DBへの登録処理 }ビューファイルを編集してエラーメッセージを出力する記載を追加する。
content/new.blade.php<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="/create" method="POST"> <!-- 下記を追記する --> <!-- バリデーションルールはひとつであるが、複数のエラーメッセージが出力される事を想定してforeach文でエラーを出力する --> <!-- 配列$errorsのキー'input_content'にメッセージが格納されているかの分岐 --> @if ($errors->has('input_content')) <!-- 配列$errorsのキー'input_content'に格納されているメッセージを行っこづつ変数$input_content_errorに格納する --> @foreach ($errors->get('input_content') as $input_content_error) <!-- 変数$input_content_errorを出力する --> <p>{{$input_content_errors}}</p> <br> @endforeach @endif <!-- ひとつのエラーメッセージのみ出力したい場合、下記の記載でも可 --> <!-- @if ($errors->has('input_content')) <p>{{$errors->first('input_content')}}</p> @endif --> <!-- 上記までを追記する --> <input type="text" name="input_content"> <input type="submit" value="送信"> </form> </body> </html>確認
/newにアクセスし、input要素で表示されている入力ボックスに何も入力せず「送信」ボタンをクリックする。/newが際表示される事を確認する。
- 投稿日:2020-04-30T01:58:39+09:00
【Laravel】Laravel DB設定
①MAMPを起動
アプリケーションからMAMPを開き、「サーバを起動」を押下する。
②phpMyAdminにアクセス
phpMyAdminにアクセスする。
③データベース作成
▪︎新規作成
左側のメニューから「新規作成」を押下する。▪︎データベース名入力
フォームに作成したいデータベース名を入力する。▪︎文字コード設定
プルダウンから文字コード「utf8_general_ci」を選択する。▪︎作成
「作成」ボタンを押下する。④特権の設定
▪︎データベースの選択
左側のメニューから特権を設定したいデータベースを選択する。
今回は先ほど③で作成したデータベースを選択する。▪︎特権タブを開く
上部から「特権タブ」を開く。▪︎ユーザアカウント追加
「ユーザアカウントを追加する」を押下する。▪︎ログイン情報フォーム入力
ユーザ名、パスワード、再入力を入力する。
他の設定は変えない。▪︎ユーザアカウント専用データベース設定
チェックボックスから「データベース laravel_task への全ての特権を与える。」を選択し、チェックを入れる。▪︎グローバル特権設定
チェックボックスから「すべてチェックする」を選択し、チェックを入れる。▪︎SSL設定
ラジオボタンから「REQUIRE NONE」を選択しする。▪︎実行
「実行」ボタンを押下する。⑤.envファイルのデータベース設定
.envファイルを開き、下記の通りデータベースを設定する。
公文) DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=8889 DB_DATABASE=【③で作成したデータベース名】 DB_USERNAME=【④で作成したユーザ名】 DB_PASSWORD=【④で設定したパスワード】 DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock 例) DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=8889 DB_DATABASE=laravel_task DB_USERNAME=laravel_user DB_PASSWORD=password123 DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock⑥DBマイグレート
▪︎ディレクトリ移動
公文) $ cd /Applications/MAMP/htdocs/プロジェクト名 例) $ cd /Applications/MAMP/htdocs/laravel_test▪︎DBマイグレート
$ php artisan migrate












