20220127のPHPに関する記事は9件です。

VaccImage SQLを如何にHTML側に反映させるか

今回は、部署の入力ページについて。 患者さん、職員、職員家族などの分類のみならず。 外来なのか、入院ならどこの病棟なのか、どこの部署の所属職員なのか。 分類というものが必須です。 そこで、下記を作りました。 CREATE TABLE departments ( dpts_symbol VARCHAR(120) NOT NULL, dpts_name VARCHAR(120) NOT NULL, PRIMARY KEY(dpts_symbol) ); 簡単ですね。 部署のシンボルをプライマリーキーにしました。 患者登録のページから、当然ながら患者のみならず職員について、部署を入れないといけませんよね。 部署については、下記SQLにあります。 select * from departments; +-------------+-----------+ | dpts_symbol | dpts_name | +-------------+-----------+ | gairai | 外来 | | kensa | 検査科 | | qq | 救急 | | ward3B | 3B病棟 | | ward4A | 4A病棟 | | ward4B | 4B病棟 | | ward5F | 5F病棟 | +-------------+-----------+ のような形式です。シンプルですね。 なお部署名は架空のものですよ。 部署入力ページのHTMLを示すと、 <tr> <td>所属部署</td> <td><select name="dpts_symbol"> <option value=""></option> <option value="gairai">外来</option><option value="kensa">検査科</option><option value="qq">救急</option><option value="ward3B">3B病棟</option><option value="ward4A">4A病棟</option><option value="ward4B">4B病棟</option><option value="ward5F">5F病棟</option></select> </td> </tr> のようになっているのですが。部署を変更するたびに、HTML側をいじるのは面倒ですよね。これがVer1での課題でした。 これに対してどう対処したか、というのが下記のPHPのCodeです。 まず下記の関数を作りまして、、、 function funcListMake(string $a, string $b, string $c): void { $db = getDb(); $sql = $a; $stt = $db->prepare($sql); $stt->execute(); foreach($stt as $row) { echo '<option value="', h($row[$b]) , '">'; echo '', h($row[$c]) , '</option>'; } }; PHPファイルで、実際には以下のように書きます(HTMLを部分的に取り上げています)。 <tr> <td>所属部署</td> <td><select name="dpts_symbol"> <option value=""></option> <?php funcListMake('SELECT * FROM departments;', 'dpts_symbol', 'dpts_name'); ?> </select> </td> </tr> すると、再掲しますが、 <tr> <td>所属部署</td> <td><select name="dpts_symbol"> <option value=""></option> <option value="gairai">外来</option><option value="kensa">検査科</option><option value="qq">救急</option><option value="ward3B">3B病棟</option><option value="ward4A">4A病棟</option><option value="ward4B">4B病棟</option><option value="ward5F">5F病棟</option></select> </td> </tr> のようになります。 理屈は簡単ですね。 SQLから読み取ってきて、配列を用いて並べているだけです。 皆さんはどのように対処しているのでしょうか? 何冊か書籍も参考にしたのですが、リストがSQLにあっても直接HTMLに記載しているものばかりでしたがどうなのでしょう。 この関数があるだけで、SQL側をいじると自動的にHTML側が変更されるので便利ですよね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelでのAmazonSES/SMTP設定

経緯 LaravelからAmazon SESへの接続がタイムアウトしたりエラーになって試行錯誤したときのメモです。 環境は下記の通り。SESはAPI経由でもよいですが、ひとまずSMTPで設定してみることにしました。 基盤構成: EC2 → Amazon SES PHPフレームワーク: Laravel 8.x 試行錯誤してるときに出たエラーたち いずれもポートの設定などを誤っているために出力されていたものです。 (Swift_IoException(code: 0): Connection to tcp://email-smtp.ap-northeast-1.amazonaws.com:465 Timed Out at /***********************/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php:166 ERROR: Expected response code 220 but got code "", with message ERROR: Failed to authenticate on SMTP server with username "***********" using 2 possible authenticators. Authenticator LOGIN returned Expected response code 334 but got code "530", with message "530 Must issue a STARTTLS command first. Amazon SESの画面 先達の知恵を借りつつもAWSドキュメントなどにあたって調べてみたものの何が問題かがぱっとわからず。 AWSコンソールのデザイン変更で、参考例のキャプチャの項目が見当たらず困るのは日常茶飯事ですが、 今回もSMTPの設定項目がどこにあるかがわからず時間を取られました。 2022/01現在のコンソール設定では「Account dashboard」の中段に、エンドポイントやポートが表示されている模様です。 EC2では25番ポートはデフォルトで使用できず、申請が必要になるので、他のポートを使用することにしました。 SMTPで接続したいIAMユーザ設定がまだない場合は「Create SMTP credentials」から、ユーザ名を指定するだけで簡単にID/PWの接続情報を作成できます。 PORTとENCRYPTIONの関係性 試行錯誤したのは結局ここでした。 STARTTLSのポートでは tls 、TLSのポートでは ssl で指定するとうまくいきそうでした。 MAIL_PORT MAIL_ENCRYPTION 465 ssl 2465 ssl 587 tls 2587 tls Laravelの.env設定例 EC2からセキュリティグループのアウトバンドで対象ポートを絞っていなければ、下記の設定で疎通できました。 MAIL_DRIVER=smtp MAIL_HOST=email-smtp.ap-northeast-1.amazonaws.com MAIL_PORT=465 MAIL_ENCRYPTION=ssl または MAIL_DRIVER=smtp MAIL_HOST=email-smtp.ap-northeast-1.amazonaws.com MAIL_PORT=587 MAIL_ENCRYPTION=tls 書き換えたあとは設定キャッシュをリフレッシュして反映し、疎通成功です。 php artisan config:cache
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

テスト投稿

Markdownの練習 php <?php while ( have_posts() ) : the_post(); ?> <?php the_title(); ?> KEILOG
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PhpMetrics実行時に出力される指標の定義、数字の見方について調べてみたメモ

こういうやつです。 LOC Lines of code 13930 Logical lines of code 7666 Comment lines of code 6264 Average volume 73.08 Average comment weight 40.21 Average intelligent content 40.21 Logical lines of code by class 20 Logical lines of code by method 10 Object oriented programming Classes 381 Interface 74 Methods 772 Methods by class 2.03 Lack of cohesion of methods 1.51 Coupling Average afferent coupling 0.83 Average efferent coupling 3.03 Average instability 0.84 Depth of Inheritance Tree 1.26 Package Packages 113 Average classes per package 4.03 Average distance 0.14 Average incoming class dependencies 4.11 Average outgoing class dependencies 5.35 Average incoming package dependencies 1.9 Average outgoing package dependencies 3.35 Complexity Average Cyclomatic complexity by class 1.52 Average Weighted method count by class 3.43 Average Relative system complexity 33.29 Average Difficulty 2.08 Bugs Average bugs by class 0.02 Average defects by class (Kan) 0.18 Violations Critical 0 Error 1 Warning 32 Information 1 数字の見方、高いほうがいいのか低いほうがいいのか、そもそもどういう指標なのか、といったことがさっぱりわからなかったので、色々と調べてメモしつつ、以下にまとめてみました。基本的に日本語の資料が出てこないので悲しい。ググり方が悪いのか?? 途中、面倒になった箇所はサボっています。 PhpMetrics 実行結果に表示される指標 LOC lines of code ソースコード行数。 LOC が大きいから悪いわけでもないし、小さいから良いわけでもない。(当たり前だが) logical lines of code コメントを除いたソースコードの行数、だと思われる。 手元にあるいくつかのプロジェクトで計測してみたところ、どの場合でも (logical lines of code) + (comment lines of code) =(lines of code) となっていたので、たぶんあってる。 comment lines of code コメントの行数。 個人的には、ソースコード内のコメントが少なければ少ないほどよいと思っている(そもそもコメントが必要になるようなコードを書かないほうがえらい) しかし、PHPの構文上サポートされていない型に関する記述(特に配列の要素の型)や各種のアノテーションなど、クラスコメント、メソッドコメントは必要に応じて積極的に書いていくべきですよね。 psalmなどの静的解析が出す警告に対しての対処など、書くべきものは書いていきましょう。 Average volume volume の平均。 volume は、たぶんHalstead complexity measuresのVolume。 ざっくりソースコードの「仕事量」みたいな感じだと思う。 volumeの平均の数値を単体で見てもあまり意味がないんじゃない? volumeが極端に大きいクラスはリファクタリングした方がいいかも? ソースコードの量と複雑さを加味した指標っぽい。 量は、Program length。演算子の数(the total number of operators)とオペランドの数(the total number of operands)の和。 複雑さは、Program vocabulary。演算子の種類数(the number of distinct operators)とオペランドの種類数(the number of distinct operands)の和 Volumeは、Program length × log2(Program vocabulary) つまり、Volumeは、Program lengthに比例する。 つまり、Volumeは、Program vocabularyが増えるとちょっと増える。※log2(Program vocabulary)に比例する。 定義については、以下を参照。 https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md https://www.verifysoft.com/en_halstead_metrics.html#32 Average comment weight 未確認。 Average intelligent content 未確認。 Logical lines of code by class クラスごとの、コメントを除いた行数(多分) Logical lines of code by method メソッドごとの、コメントを除いた行数(多分) Object oriented programming Classes クラス数 Interface インターフェース数 Methods メソッド数。 Methods by class Classes ÷ Methods Lack of cohesion of methods 直訳するとメソッドの凝集性の欠如、となる。 Lack of cohesion of methods (LCOM) is a measure of the number of responsabilities of class. Thus, if you consider the SOLID principles, the ideal LCOM is LCOM=1. (適当訳)Lack of cohesion of methods (LCOM) は、クラスが持つ責任の数を示す指標である。 したがって、単一責任の原則を考慮するのであれば、理想的なLCOMの値は1となる。 https://www.phpmetrics.org/documentation/how-to-understand-metrics.html 「凝集度が高い」=「すべてのインスタンス変数がすべてのメソッドから使われている状態」 前述の通り、クラスの責務が1つだよ、という状態を理想とするなら1になるのがよい。 ただ、責務のサイズが大きい場合もあるよなー、とは思う リファクタリングするべきかどうかの指標、として扱うのが良いのだろう。 下記もあわせて参考 Coupling Average afferent coupling incoming。どれくらい他のパッケージから参照されているか。責任の大きさ。 Afferent Couplings (Ca): The number of classes in other packages that depend upon classes within the package is an indicator of the package's responsibility. Afferent = incoming. (適当訳)Afferent Couplings : 他のパッケージから参照されるクラスの数は、パッケージの責任の度合いを示すindicatorで~す。 https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md Average efferent coupling outgoing。どれくらい他のパッケージを参照しているか。依存の大きさ。 Efferent Couplings (Ce): The number of classes in other packages that the classes in the package depend upon is an indicator of the package's dependence on externalities. Efferent = outgoing. (適当訳) Efferent Couplings : パッケージ内のクラスが参照する外部パッケージのクラス数は、パッケージの依存の度合いを示すindicatorでーす。 https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md Average instability 不安定性。 Instability = Efferent couplings ÷ (Efferent couplings + afferent coupling) This metric is an indicator of the package's resilience to change (適当訳) この指標は、パッケージの変更に対するresilience を示すindicatorでっす The range for this metric is 0 to 1, この指標は0から1の範囲やで with I=0 indicating a completely stable package この指標が0っちゅうことは、完全にstableやで and I=1 indicating a completely unstable package. 逆に、この指標が1ちゅうことは、完全にunstableやで https://en.wikipedia.org/wiki/Software_package_metrics Depth of Inheritance Tree 未確認。 Complexity Average Cyclomatic complexity by class クラスごとに計測した循環的複雑度の平均値。 Cyclomatic complexity(循環的複雑度) については、ググれば色々と出てくるので詳細は割愛。 大雑把には、分岐とループが多ければ数値が大きくなる。(確か、ネストしてるとめっちゃ増える) 当然、低ければ低いほど単純な構造であることを示す。 経験的に、この指標はコードのメンテナンス性に大いに関わると思うよ。 phpmdなどで閾値を設定して、一定以下の循環的複雑度でなければコミットできないようにしておくと良い。 認知的複雑度という指標も併用するとよい。確かCodeClimateで計測できる。 認知的複雑度が一定の閾値を超える場合にアラートを出す、ってのもできる。(PHPCSを使う) Average Weighted method count by class 未確認。 Average Relative system complexity システムの複雑さ。 数値が高いほど、問題が発生する可能性が高いことを示唆する。 Relative system complexityの定義(面倒なので英語のまま) Fan-out = Structural fan-out = Number of other procedures this procedure calls v = number of input/output variables for a procedure (SC) Structural complexity = fan-out^2 (DC) Data complexity = v / (fan-out + 1) https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md#card-and-agresti-metric RSYSC = average (SC + DC) over all procedures. http://grahamberrisford.com/AM%202%20Methods%20support/10ComplexityAndAgility/Measures%20of%20size%20and%20complexity.htm なので、この指標を下げるには 呼び出すメソッドの数を減らす 入出力する変数の数を減らす をやればよい。 Relative system complexity (RSYSC) Card & Agresti defined system design complexity as composite measure of complexity inside procedures and between them. It measures the complexity of a system design in terms of procedure calls, parameter passing and data use. ・measures the average complexity of procedures in a system. システム内の処理の複雑さの平均を示す。 ・does not depend on the system size. システムのサイズには依存しない。 ・has been found to be a good predictor of the error rate in a system (a high RSYSC predicts lots of errors per lines of code). the error rate in a systemの良い予測因子であることが知られている。(RSYSCの値が高いと、1行ごとのエラー発生数がいっぱいだぜ?) Average Difficulty たぶん、Halstead complexity measures のDifficulty (the number of distinct operators ÷ 2)× (the total number of operands ÷ the number of distinct operands) 何を示しているのかはいまいちよくわからんが、低いほうが良いんだろうなー、という感じ Bugs Average bugs by class 未確認。 コードの複雑さから予測されるバグ数? Average defects by class (Kan) 未確認。 コードの複雑さから予測される不具合件数? 暫定結論 とりあえず Lack of cohesion of methods Average Cyclomatic complexity by class Average Relative system complexity あたりを継続的に見ていけば良いんじゃねーかなー、としておく メモ、参考情報、課題とか 対数について 対数ってよくわからないですよね(高校の数学を完全にサボったため) 計算式の中にlogが出てくると、急によくわからなくなる。感覚的に数字の意味が捉えにくくなるというか。 こういう説明はありがたいですね。log2(x)は、2進法にしたときの桁数、と考えれば良いのか。なるほど 実際、どれくらいの値になってれば品質が高いと判断できるの? この数字実際どうなん?がよくわからない。 いろいろなプロジェクトで計測して、プロジェクト間で比較したりしてみないと勘所が見えんのだろうなー
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel validation、第2引数を使ってのメッセージ設定

【環境】 windows10 64bit php 7.4.27 laravel 8 こんにちは、今回はこんなケースです。 まずは画像を見てもらいましょう。 こんな感じで設定を行って、 ➀ プレーヤまたはコンピュータのどちらにもチェックが入ってない場合にエラー ➁ 名前の欄が未記入ならエラー  という内容を、laravelのvalidationを使って表示させようとするという内容です。 完成図はこんな感じ ↓   ↓   ↓   ↓ 最初はこんなもん簡単にできるやろうと思ったが意外な落とし穴にはまってしまって苦戦しました。 まずこれの設定ですが、こんな感じ index.html {{-- エラーメッセージ --}} @if ($errors->any()) @foreach ($errors->all() as $error) <p> <strong style="color:red;">{{ $error }}</strong></p> @endforeach @endif {{-- ここまで --}} /** ラジオボタンの設定 **// //プレーヤにチェック  = "1”を返す //コンピュータにチェック  = "0"を返す //どちらにもチェックがない = nullを返す /** 名前入力の設定 **// //入力したものを返す。ただし、未記入の場合nullを返す <p><input type="radio" name="chara" id="chara" value="1">プレーヤ</p> <p>デーモン様のお名前を入力してください</p> <input type="text" id="player_name" name="player"> <p><input type="radio" name="chara" value="0">コンピューター</p> 共通しているのは、nullが返ってきたらバリデーションでエラーを返すと考えて、 "required"で設定すればいいかなと思ったが、 playersContoroller.php // バリデーション $validatedData = $request->validate([ 'chara' => 'required', 'player' => 'required' ]); そうするとこのように帰ってきます。 ↓  ↓  ↓ requiredの場合、このように設定されています。 validator.php 'required' => ':attributeは、必ず指定してください。 :attributeはここでは、それぞれのname属性の名前が返ってきてます (● ラジオボタン =>  name = "chara" , ● テキストボックス => name = "player") これでは見ている人から見れば、何のエラーかわかりにくいですよね? ましてや、名前を入れてないことのエラーが 「必ず指定してください」っていうのもなんか変((+_+)) というわけで、各々のrequiredにメッセージを入れるという設定をしないといけません。((+_+)) けど、私の知っているの方法としては、 ● ruleのディレクトリを設定する ● middlewareのディレクトリを設定する この2つの方法です。ちょっと面倒くさいと思いました、、、、が 「いやいや第2引数にメッセージを作ったらそれで完結するよ」 と教えてもらい、すんごく楽チンでした。 こんな感じです。 playersContoroller.php(第2引数にメッセージ追加) // バリデーション $validatedData = $request->validate([ 'chara' => 'required', 'player' => 'required' ], [ //ここから第2引数 'chara.required' => '【エラー】:チェックしてください',     'player.required' => '【エラー】:枠内を入力してください',   ここまで// ]); これでちゃんと設計通りにできました(^^)/ ↓   ↓   ↓   ↓ なお、今回の内容は、laravelの青本に書いてるとのことです。基本さえわかっていたら、そこまでググらなくても出てくるよ、、と まとめると・・・やっぱり基礎にもどる習慣をつけておこうと思ったのでした。 基礎を見なおす → なかったらググる 以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 超初心者講座①~ディレクトリ構造について~

Laravelの超初心者向けの講座です。 本記事は、普段LaravelやVue.jsを使っているWeb系エンジニアが「Laravelをこれから触ってみたい!」、「まずは簡単な掲示板を作れるようになりたい」と考えている方へ向けまとめた記事です。 とにかくわかりやすく短時間で読めることに重点を置いているため、細かい説明等は割愛していきますのでご了承ください。 まず第1回ではLaravelの全体像を掴むため、ディレクトリ構造(フォルダの構成)について解説していきます。 Laravelのディレクトリ構造 まずLaravelアプリケーションのディレクトリ構造は下記のようになっています。 下記ディレクトリについて、1つ1つざっくりと解説していきます。 application -app -bootstrap -config -database -public -resources -routes -storage -tests -vendor -.env app ディレクトリ アプリケーションの柱!最重要! このディレクトリは、「コントローラー」や「モデル」などアプリケーションを作っていく上でメインとなるものがこのディレクトリ配下にあります。最も使用するのがこのappディレクトリです。このフォルダの詳細は、超初心者講座②で解説します。 bootstrap ディレクトリ 初期起動時の処理 気にしなくて大丈夫 このディレクトリは、アプリケーションを立ち上げた際にデフォルトで生成されたファイルが配置されています。基本的にこのディレクトリ内のファイルを変更することはありません。はじめはあまり気にしなくて大丈夫です。 config ディレクトリ 各種設定 このディレクトリは、アプリケーション全体の設定ファイルが配置されています。必要に応じて設定のオプションをカスタマイズします。必要になればそのタイミングで触ることになるので、今は色々な設定がここにあるんだな程度で大丈夫です。 database ディレクトリ データベース関連 このディレクトリは、データベースに関連する次の3つが設置されています。 【 マイグレーション(migrations) 】・・・テーブルの作成や変更などで使用する。 【 シーダー(seeds) 】・・・テーブルにデータを自動で流す際に使用する。 【 ファクトリー(factories) 】・・・シーダーを使って大量のデータを流す際に使用する。 public ディレクトリ 画面に描画される関連ファイル このディレクトリには、リクエストを受けた際の窓口となるindex.phpファイルがあります。また、「画像」、「JavaScript」、「CSS」などのファイルもここに配置されています。 resources ディレクトリ 画面に描画される関連ファイルの元となるコード このディレクトリには、フロント(画面に表示されるもの)側に関連する下記4つが配置されています。 【 js 】・・・コンパイルする前のJavaScriptファイルが配置されています。コンパイル後に前述したpublicディレクトリ配下に反映されます。publicディレクトリを直接更新する場合は使用しません。 【 lang 】・・・言語ファイルが配置されています。デフォルトでは英語のみ。 【 sass 】・・・cssにコンパイルする前のsassファイルが配置されています。コンパイル後に前述したpublicディレクトリ配下に反映されます。publicディレクトリを直接更新する場合は使用しません。 【 views 】・・・コンパイルする前のhtmlファイルが配置されています。Laravelでは「.html」でなく「.blade.php」という拡張子でファイルを作成することでそのファイル内で、変数やif文、for文などPHPの処理が使用できるようになります。コンパイル後に後述のstorageディレクトリ配下に反映されます。 コンパイルとは、プログラミング言語で書かれたソースコードを、コンピュータが直接実行可能な形式に変換すること。 routes ディレクトリ ルート定義 このディレクトリには、ルートが定義されています。webサービスでいえば「https://〇〇〇.com/△△」というURLにアクセスがあった場合に、どの画面を表示するのか?どんな処理を返すのか?などが一覧で定義されています。デフォルトで「web.php」、「api.php」、「console.php」、「channels.php」という4つのファイルがありますが、Webサービスでは基本的に「web.php」にルートを定義します。APIを作成したい場合は「api.php」に定義します。「console.php」、「channels.php」は今は気にしなくて大丈夫です。 storage ディレクトリ 倉庫 このディレクトリには、「app」、「framework」、「logs」が配置されています。今はlogs配下にログが出力されるファイルがあることを覚えておきましょう。エラーログもここに出力されます。 tests ディレクトリ テスト関連 このディレクトリには、PHPUnitテストなどを行う際にしようするファイルを配置します。自動テストが必要な際に使用します。今は気にしなくて大丈夫です。 vendor ディレクトリ 依存パッケージ このディレクトリには、コンポーザーによって管理される便利機能の関連ファイルが配置されます。今は気にしなくて大丈夫です。 「コンポーザー(Composer)」とは、Laravelの様々な便利機能(パッケージやライブラリなど)のバージョンや依存関係の管理を行ってくれる機能のことです。 .env ファイル 環境変数 このファイルは、アプリケーションの根幹となる重要な設定を記載するファイルです。 データベースにアクセスするためのパスワードや暗号化するためのキーなど機密情報の設定もここに記載します。このファイルは外部に漏れないよう細心の注意が必要です。 以上。 まとめ Laravel 超初心者講座の第1回ではディレクトリ構造をざっくりと解説しました。 なんとなく全体像がイメージつきましたでしょうか? 次回はappディレクトリの配下にある「コントローラー」や「モデル」などについて深堀していきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 超初心者講座~ディレクトリ構造について~

Laravel初心者向けの内容です。 本記事は、普段LaravelやVue.jsを使っているWeb系エンジニアが「Laravelをこれから触ってみたい」、「まずは簡単な掲示板を作れるようになりたい」と考えている方へ向けまとめた記事です。 とにかくわかりやすく短時間で読めることに重点を置いているため、細かい説明等は割愛していきますのでご了承ください。 Laravelの全体像を掴んでいただくため、今回はディレクトリ構造(フォルダの構成)について解説していきます。 Laravelのディレクトリ構造 まずLaravelアプリケーションのディレクトリ構造は下記のようになっています。 下記ディレクトリについて、1つ1つざっくりと解説していきます。 application -app -bootstrap -config -database -public -resources -routes -storage -tests -vendor -.env app ディレクトリ 主にここにアプリケーションの処理を書いていく このディレクトリは、「コントローラー」や「モデル」などアプリケーションを作っていく上でメインとなる処理を記載します。最も使用するのがこのappディレクトリです。 このディレクトリ配下には重要度の高いものがたくさんあるので詳細は後述します。 bootstrap ディレクトリ 初期起動時の処理 このディレクトリは、アプリケーションを立ち上げた際にデフォルトで生成されたファイルが配置されています。基本的にこのディレクトリ内のファイルを変更することはありません。はじめはあまり気にしなくて大丈夫です。 config ディレクトリ 各種設定 このディレクトリは、アプリケーション全体の設定ファイルが配置されています。必要に応じて設定のオプションをカスタマイズします。 database ディレクトリ データベース関連 このディレクトリは、データベースに関連する次の3つが設置されています。 【 マイグレーション(migrations) 】  テーブルの作成や変更などで使用する。 【 シーダー(seeds) 】  テーブルにデータを自動で流す際に使用する。 【 ファクトリー(factories) 】  シーダーを使って大量のデータを流す際に使用する。 public ディレクトリ 画面に描画される関連ファイル このディレクトリには、リクエストを受けた際の窓口となるindex.phpファイルがあります。また、「画像」、「JavaScript」、「CSS」などのファイルもここに配置されています。 resources ディレクトリ 画面に描画される関連ファイルの元となるコード このディレクトリには、フロント(画面に表示されるもの)側に関連する下記4つが配置されています。 【 js 】  コンパイル¹する前のJavaScriptファイルが配置されています。コンパイル¹後に前述したpublicディレクトリ配下に反映されます。publicディレクトリを直接更新する場合は使用しません。 【 lang 】  言語ファイルが配置されています。デフォルトでは英語のみ。 【 sass 】  cssにコンパイル¹する前のsassファイルが配置されています。コンパイル¹後に前述したpublicディレクトリ配下に反映されます。publicディレクトリを直接更新する場合は使用しません。 【 views 】  MVCのVにあたる。コンパイル¹する前のhtmlファイルが配置されています。Laravelでは「.html」でなく「.blade.php」という拡張子でファイルを作成することでそのファイル内で、変数やif文、for文などPHPの処理が使用できるようになります。コンパイル¹後に後述のstorageディレクトリ配下に反映されます。 ※1 コンパイルとは、プログラミング言語で書かれたソースコードを、コンピュータが直接実行可能な形式に変換すること。 routes ディレクトリ ルート定義 このディレクトリには、ルートが定義されています。webサービスでいえば「https://〇〇〇.com/△△」というURLにアクセスがあった場合に、どの処理へ飛ぶのかが一覧で定義されています。デフォルトで「web.php」、「api.php」、「console.php」、「channels.php」という4つのファイルがありますが、Webサービスでは基本的に「web.php」にルートを定義します。APIを作成したい場合は「api.php」に定義します。「console.php」、「channels.php」は今は気にしなくて大丈夫です。 storage ディレクトリ 倉庫 このディレクトリには、「app」、「framework」、「logs」が配置されています。今はlogs配下にログが出力されるファイルがあることを覚えておきましょう。エラーログもここに出力されます。 tests ディレクトリ テスト関連 このディレクトリには、自動テストなどを行う際に使用するファイルを配置します。 vendor ディレクトリ 依存パッケージ このディレクトリには、コンポーザー*²によって管理される便利機能の関連ファイルが配置されます。今は気にしなくて大丈夫です。 ※2「コンポーザー(Composer)は、Laravelの様々な便利機能(パッケージやライブラリなど)のバージョンや依存関係の管理を行ってくれる機能のことです。 .env ファイル 環境変数 このファイルは、アプリケーションの根幹となる重要な設定を記載するファイルです。 データベースにアクセスするためのパスワードや暗号化するためのキーなど機密情報の設定もここに記載します。このファイルは外部に漏れないよう細心の注意が必要です。 次にappディレクトリ配下の構造について解説していきます。 app ディレクトリについて 前述したappディレクトリの配下の構造は下記のようになっています。 アプリケーションのメインとなる重要なディレクトリなので解説していきます。 app -Console -Exceptions -Http -Library -Models -Providers -Rules -Services Console ディレクトリ コマンド群 コマンドを自作するとここに生成されます。バッチ処理などコマンドで実行したい処理がある場合に利用します。 Exceptions ディレクトリ 例外処理の設定 エラーが起きた際の出力先や出力方法を設定できます。デフォルトではログに出力されます。 Http ディレクトリ アプリケーションの中心部 アプリケーションへのリクエストがあった際に実行される処理を記載する。 今は下記2つを覚えておこう。 【 コントローラー(Controllers) 】  MVCのCにあたる。アプリケーションの司令塔としての役割を担います。ユーザーからの要求(リクエスト)に対して、モデルなどから情報を取得し、必要な形に処理し、画面や値などといった何かしらの返答(レスポンス)を送ります。 【 リクエスト(Requests) 】  フォームに入力された値など、送られてきた値に対してバリデーションや加工を行う。 Models ディレクトリ データベースとの架け橋  MVCのMにあたる。DBからデータを取得、DBへデータを登録、DBのデータを更新・削除など、DBとのやりとりをする処理はここに記載しましょう。Laravel5以降ではModelsディレクトリはデフォルトでは無く自身で作成することが多かったがLaravel8から復活しました。 Providers ディレクトリ サービスコンテナへのサービスの登録 様々な処理をサービスコンテナへ登録し管理します。今は気にしなくて大丈夫です。 他のディレクトリ デフォルトではありませんが、appディレクトリの配下には上記以外にもEvents、Mail、Rulesなど良く使用するディレクトリがあるので、必要に応じて都度覚えていきましょう。 以上がLaravelのディレクトリ構造となります。 まとめ 今回はディレクトリ構造をざっくりと解説しました。 なんとなく全体像がイメージつきましたでしょうか? 次回はLaravelで簡単な掲示板を作りながら、アプリケーションの処理の流れを追っていきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP】認証と認可のちがいとJWTの検証について

Web APIを扱う場合、認証/認可についてある程度理解していないと正しく扱うことができません。 弊社の非エンジニアから質問されたことをきっかけに、自分自身の整理も兼ねてまとめておきます。 少しだけLINEログインと絡めて説明します。 認証/認可とは 認証 Authentication それが誰であるかを確認すること。 認可 Authorization 何らかの情報に対するアクセス権限を確認すること。 例えると、認証は「証明書による本人確認」、認可は「チケット(切符)の発行」です。 2つを分離して考えると、認証は本人確認であってそれによって何が行えるということはなく、認可は権限があるというだけでそれを使うのが誰かには関与しません。 引用:ウェブアプリにLINEログインを組み込む | LINE Developers LINEログインでいうと 認証 誰であるかを確認する。 認可 アプリケーションに対するアクセス権限を設定する。 処理の流れとしては、 LINEログインのためのURLをクリック。 LINEのログインを実施(認証)。 ログインしてなければメールパスワード認証やQRコードログインを行わせる。 ログインしていれば、自動ログインやSSOログインを行う。 認証できたら認可の画面で、アプリがLINEの情報を使うことを許可するかどうかをユーザーに確認する。 許可されたらその情報を用いてアプリでユーザーの情報を取得できる。 OAuth 2.0とOpen ID Connect 認証と認可を行う標準的な方法としてよく使われているのが、OAuth 2.0やOpenID Connectというプロトコルです。 LINEログインでもこれらに基づいたフローが実装されています。 OAuth 2.0 サードパーティアプリがHTTPサービスよる限定的なアクセスを可能にする認可フレームワーク。 私が以前作ったGoogle Photosに保存されている写真を取得して自動バックアップを行うアプリはOAuth 2.0によりサーバーに権限を付与して自動でバックアップを取得させています。 【Python】GooglePhotosAPIで写真・動画のバックアップを取得する方法 - Qiita OpenID Connect OAuth 2.0は本人であるかどうかを確認する術では本来ないのですが、使われ方として本人かどうかを確認したいというケースが多いです。 そのため、IDに関する情報を付与して、必要最低限のプロフィール情報を取得できるようにしたものがOpenID Connectです。 LINEログインにおけるユーザー情報の取得 上記のOpenID Connectの仕様に基づいて、LINEログインを行った後はid_tokenというものが渡ってきます。 このid_tokenはJWT(JSON Web Token)という仕様で渡ってきます。 response { "access_token": "bNl4YEFPI/hjFWhTqexp4MuEw5YPs...", "expires_in": 2592000, "id_token": "eyJhbGciOiJIUzI1NiJ9...", "refresh_token": "Aa1FdeggRhTnPNNpxr8p", "scope": "profile", "token_type": "Bearer" } このid_token eyJhbGciOiJIUzI1NiJ9...の部分を所定の方法でデコードして検証すると以下のような情報に変換できます。 JWTの例 { "iss": "https://access.line.me", "sub": "U1234567890abcdef1234567890abcdef", "aud": "1234567890", "exp": 1504169092, "iat": 1504263657, "nonce": "0987654asdf", "amr": [ "pwd" ], "name": "Taro Line", "picture": "https://sample_line.me/aBcdefg123456", "email": "taro.line@example.com" } 引用:IDトークンからプロフィール情報を取得する | LINE Developers Firebase/php-JWTの仕様 弊社のプロダクトの一部ではJWTの検証にphp-JWTを使用しています。 JWTの検証をWebアプリに組み込む場合は、公開されているライブラリを使うことをおすすめします。 言語ごとに以下のサイトでライブラリを調べる事ができます。 JSON Web Tokens - jwt.io 本題のFirebase/php-JWTのリポジトリは以下です。 GitHub - firebase/php-jwt: PHP package for JWT 具体的にはFirebase/JWT/decodeという関数を使用してデコードしています。 この中でやっていることをまとめておきます。 JWTの仕様と前提知識 JWTは.で3つのセクションに区切られてやってきます。<ヘッダ>.<ペイロード>.<シグネチャー>の形式で渡ってきます。 例) base64エンコード エンコードとデコードは暗号化と復号に似ていますが、base64だということを知っていれば誰でも変換が可能です。 データをある規則で文字列に置き換えることをエンコード、それをデータに戻すことをデコードといいます。 暗号化と似ていると言いましたが、暗号化のプロセスの中にbase64エンコードは大体入っています。 引用:JSON Web Tokens - jwt.io ヘッダー JWTであるという情報と署名アルゴリズムが書かれています。 ペイロード 実際のデータが入っているところです。 nbf(Not Before) : JWTが有効になる日時 iat(Issued At) : JWTの発行時間 exp(Expiration Time) : JWTの有効期限 シグネチャー 検証用の署名 HS256の場合、以下のように検証します。 base64エンコードされたヘッダーとペイロードをピリオドで連結した文字列をチャネルシークレットを鍵としてハッシュ化する。 これがデコードされたシグネチャーと一致するかを確認して、改ざんされていないかを検証する。 Firebase/JWT/decodeの処理 現在時刻を取得する。 必要な情報が渡ってきているか、形式がおかしくないかなどを確認する。 ヘッダー、ペイロード、シグネチャに分けて、それぞれbase64デコードする。 ヘッダーのアルゴリズムを確認して、渡ってきた鍵を使ってシグネチャを検証する ペイロードの中にnbtがもしあれば、現在時刻にleewayという設定値を足した時間よりあとになっているかを確認する。 → つまりJWTの有効日時よりあとかどうかを時刻誤差leewayを許容しつつ確認する。 ペイロードの中にiatがもしあれば、現在時刻にleewayという設定値を足した時間よりあとになっているかを確認する。 → つまりJWTの発行時間よりあとかどうかを時刻誤差leewayを許容しつつ確認する。 ペイロードの中にexpがもしあれば、現在時刻からleewayを引いた時間がexpより前であるかを確認する。 → つまりJWTの有効期限を時刻誤差leewayを許容しつつ確認する。 全部OKだったらペイロード部分を返却する。 おわりに 認証と認可についてまとめてみました。 深く理解するには、ネット上にたくさん文献があるのでそれを読むのが良さそうです。 個人的にJWTの検証部分を修正した際に、nbtやiatの意味がよくわかっておらず苦戦したので同じような方の助けになればと思います。 参考 一番分かりやすい OAuth の説明 - Qiita [レポート] 実装して理解するLINE LoginとOpenID Connect入門 に参加してOAuthとOpenID Connectについても学んできた #linedc | DevelopersIO 実装して理解するLINE LoginとOpenID Connect入門 OAuth 認証を真面目に考える | DevelopersIO よくわかる認証と認可 | DevelopersIO JSON Web Tokens - jwt.io
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

M1 Macにphp7系の環境を整える

概要 新しくM1のMacを購入したのだが、前に作っていたphp7系のコードを動かそうとして苦戦したのでメモ。 参考資料 https://tanakano-aster.com/note/m1-mac-php72/ この人の記事を参考に、自分はphp7.4を動かすようにしました。 やり方 下記のページのコマンドをコピーしてターミナルで実行 https://brew.sh/ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) brewアップデート brew update php7.4があるか確認 brew search php php7.4をインストール brew install php@7.4 php7.4を紐付ける brew link php@7.4 いまのphpをunlinkするかオーバーライドしろって言われたから brew link --overwrite php@7.4 最後にパスを通す(必要なかったかも) echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.zshrc echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む