【8日目】HTTPとLaravelについて【作曲の補助ツールを作るまでの日記】

プログラミング

2023年7月17日~2023年7月19日

今度こそLaravelをやろう。

昨日まででVirtualBoxにAlmaLinuxを入れて、そこにPHP,Apache,Laravelの環境構築をしたわけだけど、これってgitかなんかでリポジトリ作って、ホストPCで編集するのがいいよね?

gitと連携する

gitのインストールと初期設定

まず、AlmaLinuxのgitのインストールと設定から。

‘sudo dnf install git -y’
-yは全ての選択をYesで答えるという意味。

‘git -v’でインストールされてるか一応確認。

git config --global user.name "ユーザー名"
git config --global user.email "ユーザー名@example.com"

で名前とメールアドレスを登録しとく。
確か、この設定をしないとgit使えない。ユーザー名とかはメールはcommitした時に載る情報でログインとかではないはず。

今回は–globalで全てに適応だけど、プロジェクト毎に分けたかったらその設定もある。

一応、master表記が気になる人は
‘git config –global init.defaultBranch main’
でデフォルトがブランチ名がmainになる。

githubのSSH設定

アカウント認証はSSH認証が推奨されてるし、後々を考えるとこちらの方が楽なのでやっておく。
やり方はGithub公式こちらの方を見るとよいかなと思う。※どちらも同じことをやってるが、Github公式の方は分かり難いが最新情報を取り扱ってる。

リポジトリの作成

私は/home/user/Laravel/test_appにアプリフォルダを作ったので、test_appごとgitリポジトリにする。

‘cd /home/user/Laravel/test_app’

git initをする前に、gitignoreの確認。
一応説明すると、gitにアップしないで無視するフォルダやディレクトリを設定できる。機密情報ファイルとかはアップロードするとまずいから設定しとかなきゃいけない。

‘cat .gitignore’

うーん。正直全然分かんないんだけど、最初から用意されてはいるのでこのままでとりあえずは大丈夫だと思い進める。

ってことで
’git init’

このディレクトリ以下の全ファイルを対象にしたいので、
’git add -A’

とりあえずcommit
‘git commit -m “Hello Laravel”’

ここまで来たら、一回Githubへ

readmeとかgitignoreは作らずに、privateで新しいリポジトリ作成。

‘git remote add origin githubリポジトリのURL’
でgithubリポジトリと連携。SSH接続の設定をした人はそっちのURL。
これは、originというリモートリポジトリをgithubにホストしてもらってるみたいな感じ。

‘git push -u origin main’
でpush。
これは、originというリモートリポジトリのブランチ名mainにpushするという感じ。-uを付けることで、以降のgit pushとかgit pullがmainブランチに固定される。

そうすると……

できた!

これ、readme.mdも初期からあったのね。

ホストPCでcloneする

とりあえず、githubに上げることはできたのでホストPC側でクローンしてホストPCで作業を進めよう。

私の場合はデスクトップにAlmaLinuxというフォルダを作ってそこにクローンした。

恐らくwindowsの方はgithubの認証を既にやっていたので何事も無く完了した。

最後に、スナップショットを忘れず取っとこう。

今度こそLaravelを弄ろう

なんだかんだgitやらgithubにまあまあ時間を取られてしまった。

ここからは書籍を頼りにVSCodeを使って進めていく。

HTTPリクエストやHTTPレスポンスとはなにか

色々調べているうちにここら辺の基礎知識がしっかりしていないと感じたので、ここから。

HTTPとは

HTTPはHypertext Transfer Protocolの略。
ハイパーテキストの送受信をする際のルールみたいな感じ。
ここではハイパーテキストとあるけど、Web通信を行う際のルールみたいな感じでいいと思う。

なぜHTTPが必要なのか

もし、各国、各デバイス、各ブラウザが独自にWeb通信のルールを持っていると「Aのルールでサーバーに話しかけたらよくわからんルールで返答されたんですけど~。マジわけワカメ」みたいな事が起きちゃう。ましてや処理をするのはプログラムなので、形式が少しでも違うとエラーを吐いちゃう。

そこで、全世界、全デバイス、全ブラウザで共通のHTTPというルールを使えば、どの世界のサーバーとも、どのデバイスとも、どのブラウザともWeb通信が出来るということ。

HTTPリクエスト・レスポンスとはなにか

恐らく例外もあるけど、
HTTPリクエストはクライアント側がサーバーに行う行為。
HTTPレスポンスはHTTPリクエストに応じてサーバー側がクライアントに行う行為。

また、基本的にクライアントから処理が始まる。だから、いきなりサーバーがレスポンスを送ることはない。

因みに、HTTPリクエストは

  1. リクエストライン
  2. ヘッダーフィールド
  3. ボディ

で構成されていて

HTTPレスポンスは

  1. ステータスライン
  2. ヘッダーフィールド
  3. ボディ

で構成されている。

HTTPの例

正直、例を見ずに何やってんのか聞いてもわけわかんないよね。

ChatGPTに例を出力してもらったので、それを見ながら理解していく。

リクエストの例

GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

これがHTTPリクエストの例。
1行目の
「GET /index.html HTTP/1.1」がリクエストラインと言われるところで、
メソッド URI HTTPのバージョン」を空白区切りで指定する。

それ以降の行は全てヘッダーフィールドというもので、「フィールド名:内容」で記述される。

今回出力してくれた例はメソッドがGETなのでwww.example.comの/index.htmlを要求していることになる。だから、リクエストラインとヘッダーフィールドしかないんだけど、もしサーバーに情報を送るとき(ログインする際のID・PWとか)はヘッダーフィールドより下の行にボディで入力したIDとかPWとかの情報を載せて送る。

レスポンスの例

HTTP/1.1 200 OK
Date: Mon, 23 May 2023 22:38:34 GMT
Server: Apache/2.4.1 (Unix)
Last-Modified: Sat, 20 May 2023 18:56:51 GMT
ETag: "1003-54a-41c9-4692"
Accept-Ranges: bytes
Content-Length: 51
Connection: close
Content-Type: text/html; charset=UTF-8

<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>

こちらがHTTPレスポンスの例。一応、リクエストに対応したレスポンスになっている。

1行目がステータスラインでリクエストの結果を載せている。よく見る404はクライアントエラーの番号で今回の200は成功を意味する。
2行目から空白行までがヘッダーフィールドになっている。内容はHTTPリクエストと同じ?
空白行から最後までがボディになっている。今回はクライアントにwww.example.comの/index.htmlを要求されていたので、HTMLをレスポンスしている。

リクエストの繰り返し

因みに、今回の例はHTMLだけだけど、実際は何回もHTTPリクエストとレスポンスを繰り返してWebページを作っている。
例えば、HTMLの中に<img src=”images/example.jpg”>という行があったらクライアントはimages/example.jpgを更にリクエストして、サーバーはそれを返す。

これが正確かはわかんないけど、デベロッパーモードでYoutubeを実際に開いてみると
9秒間ぐらいの間に63回のリクエストを行っている。

その中にはHTMLだけじゃなく、画像ファイルやCSSやJavaScriptとか色々含まれてた。

実際にHTTPを見てみたい!

やっぱりHTTPを実際に見てみたいよね。

実際に、好きなWebサイトでf12を押してデベロッパーツール→ネットワークに行くことでHTTPを見ることが出来る。
HTTPは通信内容を暗号化するHTTPSがあるくらいで、知識がない私にはちょっとどこまで見せていいのか分からないので各自で見てほしい。

クライアントとサーバーはどのような動作をするのか

実際にクライアントとサーバーはどのような動作をしてんのかもある程度知っておいた方が良いように感じたので、最後に大まかな処理を。

内容は大体「Webを支える技術」から。

クライアントが行うこと

  1. リクエストメッセージの作成
  2. リクエストメッセージの送信
  3. (レスポンスの待機)
  4. レスポンスの受信
  5. レスポンスメッセージの解析
  6. クライアントの目的を達成するための処理

サーバーが行うこと

  1. (リクエストの待機)
  2. リクエストの受信
  3. リクエストメッセージの解析
  4. 適切なアプリケーションに処理を委譲
  5. アプリケーションからの処理結果を取得
  6. レスポンスメッセージの作成
  7. レスポンスメッセージの送信

HTTPリクエストとHTTPレスポンスがどんなものかを知りたかっただけなのに、結構書いちゃった。全てが正確に合ってるわけではないと思うけど、大まかには合ってるはず。

書籍メモ

書籍の通りに進める過程を残してもいいんだけど、色々面倒なのでメモだけ残していく。

  • エントリポイント
    HTTPリクエストは最初にpublic/index.phpに来る。要するに、アプリケーションの委譲がindex.phpに来るってこと!?

    これは、たとえhttps://example.com/test/にアクセスしたとしても、/public/index.phpにリダイレクトするという話らしい。
    実際に.htaccessファイルを見ると、index.phpの記述を確認できる。


    要するに、Laravelで作ったアプリ内のどのURIにアクセスしても、先ずはindex.phpに行ってそこから処理が始まるということ。
    index.phpをある程度詳しく解説してくれている人もいるのだけど、マジでチンプンカンプンなのでいったんそういうもんだと思ってスルー。
  • ルーティング
    ルーティングとは「○○のURLにアクセスがあったら××の処理を呼び出す」ということらしい。
    ルーティングを定義するファイルはroutesフォルダにあって、Webアプリケーションの処理はweb.phpが行っているらしい。

    実際にweb.phpを見てみると以下のようになっている。

    つまり、Webサイトのトップページの「/」にアクセスした場合、welcomeという名前のviewを出すよう処理されている。
  • ビュー
    じゃあ、そのviewってなんやねんと。
    viewはresources/viewsに入っている。
    実際に見てみるとwelcome.blade.phpというのがある。


    これを先ず見ると、.blade.phpというのが気になると思うんだけど「.blade.php」というのが拡張子で、Laravelが提供するBladeというテンプレートエンジンを利用する際に付ける拡張子らしい。

    実際にwelcome.blade.phpを見てみると、htmlの中に@if等の見慣れない処理が入っている。


    これがBladeを使った処理の書き方で、ifやforの処理とか色んな処理の補助をしてくれるみたい。

    Bladeは最終的にhtmlを出力する。
    つまり、さっきのルーティングはview(“welcome”)だったので、トップページにアクセスすると、welcome.blade.phpで出力されたhtmlを取得し、HTTPレスポンスで返信するということになる?
  • 新しく作ったルーティングをApacheが読み込んでくれない問題
    解決方法 /etc/httpd/conf.d/test_app.confの記述に「AllowOverride All」を追加した。
    具体的には以下のようになった。
    <VirtualHost *:80>
        DocumentRoot /home/toppakou/Laravel/test_app/public
        ServerName laravel.test
        <Directory /home/toppakou/Laravel/test_app/public>
            Require ip 192.168
            AllowOverride All
        </Directory>
    </VirtualHost>

    どういうことか?
    AllowOverride Allはそのディレクトリ以下の.htaccessの指示を全て受け入れるという設定。
    Laravelはルーティングにこの.htaccessを使うらしく、初期の何も設定していない状態だとApacheがこの.htaccessを無視していたので正しくルーティングできなかったっぽい。

    ChatGPTありがとう。
  • テストコードってなんだ?
    書籍ではなんかいきなりテストコードの話に入った。
    そもそもテストコードって何を指すのかよくわからんので、テストコードについて調べる。

    そもそもテストコードとは
    テストコードとは、書いたコードが正しく動作するかを確かめる為のコード。
    競プロやってる人は、自分で自分のコードのジャッジシステムを作るみたいなイメージしてくれればいいと思う。

    現時点ではWebページをindex.phpとhomeの2つしか作ってないわけだけど、これが増えてくると全部のページが正しく動作しているか毎回検証するのって面倒。
    そこで、ルーティングに登録されてるURLに全てに飛んでステータスコード200が返ってくるかを確認するコードがあったら便利そうじゃない? 他にもセキュリティとかパフォーマンスとかそういう様々な検証をしてくれるコードをテストコードと言うらしい。

    テストコードのメリット
    1.コードさえ書けば、繰り返し何回も気軽にテストできる。バグの早期検知に繋がる。
    2.テストの条件さえ間違えてなければ、最低限要件を保証できる
    3.リファクタリングの促進
    4.一貫性
    1と2は何となくわかると思う。
    3は、リファクタリングして意図せぬバグが発生したとしてもテストコードがあれば発見しやすいので気軽にできるよね的な意味っぽい。
    4は使ってみて思ったんだけど、!と!の区別とか、型が文字列なのかDateなのかみたいな細かいところに一貫性を求められると感じた。

    一応テスト駆動(テストファースト)という先にテストを作ってしまう開発手法もあるらしいんだけど、結構賛否両論だったので紹介だけ。

    Laravelのテストコード
    Laravelではこのテストコードを簡単に書けるようPHPUnitやLaravel Duskといったツールが入っていて、テストコード記述の支援をしてくれるみたい。

    実際、テストコードを書いたら「php artisan test」で全部のテストコードを実行して正誤を判定してくれるので、かなり楽だし気軽にできる。
  • マイグレーションとは
    マイグレーション(migration)の意味自体は”移行”と言う意味。
    Laravelでのマイグレーションは、PHPでDBのテーブルの定義を行うこと。
    DBを作るわけではなく、あくまでもDBの設計図を書くみたいな感じ。その設計図を元にMySQLなどのDBに反映させるイメージ。

    そもそも本来、例えばMySQLというDBの場合、MySQLサーバーの方でDBを設計してLaravelと連携させるという作業が必要。このとき、複数人で作業するときとかにDBを連携させたくてもDBそのものはデータ量やセキュリティの面からgitには挙げるべきじゃない。だからDBそのものをgitで連携させるのが困難なので、設計図だけ共有しようというのがマイグレーションの意味。

    DBの設計図を作ることで、変更があった時とかにも簡単に連携が可能になるし、マイグレーションには変更履歴機能があるので過去に遡れたりもする。ちょっとしたgitみたいなもん?
  • MySQLをインストールして使えるようにしよう
    MySQLとか使うの結構後の方だと思ったけど、もう使う必要があるっぽい。

    まず、mysqlが入ってないかの確認。

    そりゃあ入れてないんだからないよね。

    mysqlのバージョンを確認
    ‘dnf info mysql’



    ‘sudo dnf install -y mysql-server’
    でインストール。

    MySQLを起動しないとコマンド類は使えないっぽいので、とりあえず起動。
    ‘sudo systemctl status mysqld’
    mysqldのdはデーモンのd。

    ‘sudo systemctl status mysqld’
    で起動確認。


    インストールしたばかりではセキュリティ面に不安があるそうなので、
    ‘sudo mysql_secure_installation’
    でセキュリティ初期設定。

    最初にパスワードの条件を付けるかどうかを聞いてくる。

    MySQLもサーバーなのでrootやパスワードの概念がある。そのパスワード。
    今回はローカル環境なので必要ないっちゃないと思うんだけど、本番を想定してパスワードを付けていく。
    だからy。

    LOWは8文字以上。MEDIUMはそれに加えて数字・大小文字の混在・記号を含む。STRONGはそれに加えて辞書に登録された単語を含まない。
    辞書って何? → ’apple’とか’password’とかのよくある単語を登録されたもの。ここに登録されたものとパスワードの一部が被るとNGっぽい。

    お好きなものを選択し、パスワードを入力。

    次に、匿名ユーザーを削除するか聞かれた。
    PWなしでログインできて、一部読み書きができるユーザーっぽい。
    本番環境を想定すると要らないので、削除のy。


    次に、リモートrootログインを許可するか否かを聞かれた。
    もしリモートでrootにログインする場合は専用のユーザーを作成し許可させるらしいので、今回は許可しないのy。


    次に、テストデータベースを削除するかの問。別に要らないと思うのでy。


    最後に変更した権限などを考慮した上でテーブルリロードをするか聞かれたのでy。


    よし、最後にLinux開いた時に自動でMySQLが開くようにして
    ‘sudo systemctl enable mysqld’
    これでMySQLの初期設定は完了。

    次に、Laravelと連携させるために.envファイルを弄る。
    .envファイルはLaravelアプリディレクトリ/.envにあるのと、gitignoreに入ってるのでLinux側で弄る。

    この、DBの欄を弄る。
    vimとかで弄ってもらえれば。


    MySQLであれば恐らく、DB_PASSWORDのところにさっき設定したパスワードを入れるだけで後は初期で良いと思われる。
    DB_DATABASEはお好きな名前を。
  • MySQLをつかってみよう
    設定を終えたばかりであれば、
    systemctl restart mysqld
    php artisan config:cache
    でMySQLの再起動と.envのキャッシュの削除を行っといたほうがいいかも。

    ‘systemctl status mysqld’でアクティブなのを確認したら、
    ‘mysql -u root -p’でrootにログイン。「-u ユーザー名」でユーザ―の指定で、-pはパスワードを設定している時だけつける。

    ‘show databases;’でデータベース一覧が見れる。

    既に何個かある?

    前述した通り、マイグレーションはDBを作成する訳ではないので、ここで作っておく必要がある。
    DB_DATABASEで設定した名前でDBを新規作成する。
    ‘create database DB名;’で作成。


    ‘show databases;’で確認


    ‘exit’や’quit’でログアウトできる。

    Laravelで作成したアプリディレクトリに移り、
    ‘php artisan migrate’
    でマイグレーションの実行。

    ……ん?

    なんかドライバが無いと言われた。

    ‘sudo dnf install -y php-pdo php-mysqlnd’でドライバをインストールしてみる。

    もっかいマイグレーション実行!

    おk!

    mysqlにログインしてDBの確認。
    ‘use DB名;’でDBにアクセスして、’show tables;’で確認。


    よし、完了。

    最後に絶対スナップショットを取っておこう。
  • メールサーバーを建てよう
    マジかよ。メール送信機能の確認で使うっぽい。
    MailHogというSMTPサーバーのツールを利用してメールサーバーを構築する。

    そもそも、MailHogはGo言語で出来ているのでGoの環境構築から行う。
    ここ1週間、環境構築しかしてない。

    Goの環境構築
    ここから現在のGoの最新バージョンを確認する。
    今は1.20.6が最新っぽいね。
    1.20.6の場合は
    ‘wget https://dl.google.com/go/go1.20.6.linux-amd64.tar.gz’でダウンロード。
    ‘sudo tar -C /usr/local -xvf go1.20.6.linux-amd64.tar.gz’で解凍して/user/localに移動。

    ‘vim ~/.bash_profile’で編集して、’PATH=$PATH:$HOME/bin:/usr/local/go/bin’を記述。


    ‘source ~/.bash_profile’で反映。

    ‘go version’でバージョン確認ができればパスは通ってる。

    MailHogの導入
    ‘go install github.com/mailhog/MailHog@latest’で最新版のMailHogをダウンロード。

    パスを通す為、’vim ~/.bashrc’で’export PATH=$PATH:$HOME/go/bin/’を追加。
    ‘source ~/.bashrc’で更新。

    .envの編集
    次に.envの編集。

    私と同じようにVirtualBoxでブリッジ接続ならこんな感じで。
    VirtualBoxからブリッジ接続じゃないならMAIL_HOSTが人によって違うかも。

    ファイアウォールの設定
    8025番ポートを開放する。
    ‘sudo firewall-cmd –add-port=8025/tcp –zone=public –permanent’
    で再起動後も永遠に開放
    ‘sudo firewall-cmd –reload’でリロード。

    これで’MailHog’とやると

    8025番ポートで開いたよ! と言われるので、私と同じようにVirtualBoxでブリッジ接続の人は「http://ゲストPCのIP:8025」でアクセスするとホストPCでMailHogがブラウザで利用できる。

おわりに

なんか3日くらいに渡ってしまった。
外を見るともう人が働き始めている時間になっている。

まだ論理的にというより、まず動かしてみて何となく理解しているレベルだと思うので、これからも学び続けて自由自在になんか面白いサイトをつくりたい。