- 投稿日:2020-05-13T22:17:32+09:00
某×サーバ宛のdeployerが動かなくなった件
事件編
某×サーバへのデプロイ、deploy:vendorsタスクでエラる
エラー概要(意訳 このエラーはパッケージがPHP7.2を要求しているがオメーのPHP環境5.4だぜ!出直してこい!)
Loading composer repositories with package information Installing dependencies from lock file Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them. Dependency resolution completed in 0.000 seconds Your requirements could not be resolved to an installable set of packages. Problem 1 - This package requires php ^7.2 but your PHP version (5.4.16) does not satisfy that requirement.この前まではできていたはず。
なぜか急にできなくなった。
サーバのコンパネ上の設定ではPHP7.3を使う設定になっている。
これに関してはHTTPサーバの設定なのでCLIのPHPバージョンはデフォの5.4というのがよくある症状なのは知っていたしset('bin/php', function () { return '/usr/bin/php7.3'; });という感じで指定のPHPを使うように設定していた。
この設定を入れるとphp コマンドを /usr/bin/php7.3 と置き換えてくれる。
いままではこれで問題が発生しなかった。調査編
/usr/bin/composer install --verbose --prefer-dist --no-progress --no-interaction --no-dev --optimize-autoloader --no-sug gest失敗したコマンドをよく見る
あれれー?おかしいぞー?
/usr/bin/composerどうやらサーバー側のcomposerを使用しているようである。
おそらくこのcomposerのshebangがデフォルトのphpを指しているのであろう。
このせいで5.4のphpと認識されているようである。解決編
deployerはリモートにcomposerがインストールされていれば
そのcomposerを自動的に使う。
入っていない場合はcomposer.pharをインストールしてつかう。
どうやれば強制的にcomposer.pharを使わせられるか謎だったので
ソースを見ることとする
https://github.com/deployphp/deployer/blob/master/recipe/common.php#L117
ここだ。set('bin/composer', 'なにがし')
で上書きすることが可能そうだ。
私はめんどくさかったのでset('bin/composer', function () { run("cd {{release_path}} && curl -sS https://getcomposer.org/installer | {{bin/php}}"); $composer = '{{bin/php}} {{release_path}}/composer.phar'; return $composer; });こんな感じで常にcomposerをインストールするようにと書き換えることにした。
エピローグ
サーバ選定がアレという件はクライアントにいってください
- 投稿日:2020-05-13T22:15:47+09:00
Laravelの開発環境構築
環境
Mac Catalina10.15
Homebrewをインストールする
Homebrewはソフトウェアの導入を単純化するパッケージ管理システムのひとつです
以下コマンドを実行
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"インストールできたか確認
$ brew -vPHPをインストールする
以下のコマンドでphp7.4をインストールする
$ brew install php@7.4インストールできたか確認
$ php -vComposerをインストールする
Composerとは、PHP向けのパッケージ管理システムです
Homebrewでインストールする
$ brew install composerインストールできたか確認
$ composer -VLaravelのインストール
Composerを用いてLaravelをインストールします
方法は2通りあります。方法1
#Laravelインストール&プロジェクト作成 $ composer create-project laravel/laravel --prefer-dist プロジェクト名方法2
#Laravelインストール $ composer global require "laravel/installer" #プロジェクト作成 $ laravel new プロジェクト名laravelのバージョン確認
$ php artisan -Vデバッガーのインストール
$ composer require barryvdh/laravel-debugbar
- 投稿日:2020-05-13T20:27:31+09:00
Dockerインストール -> Docker ComposeでWordPressローカルで動かしてMySQLに外から接続したり、編集を外からしたり。(Mac)
色々とうまくいかなかったのでメモを残します。
WordPressをdocker-composeで動かすまで
Dockerのインストール
下記URLからアプリをダウンロードしてインストール
https://www.docker.com/get-startedDockerのアイコンが上のバーに出てくるのでdocker.hubのアカウントでログイン
UIでDockerの状況をお手軽に見れるので結構便利
docker-composeの導入
下記ドキュメントを参考にcurlで導入したが、なぜか動かなかった
http://docs.docker.jp/compose/install.htmlcurl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composeどうやらバージョンが古かったようなので、下記URLを元に最新のstable版のdocker-composeを指定。
https://github.com/docker/compose/releasescurl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composeこれでチュートリアルに記載されているyamlを指定して動くようになった
[参考]http://docs.docker.jp/compose/wordpress.html
(ローカルのMySQLとポートが被ると嫌なのでローカルの33060ポートを利用して外から確認するため、dbのportsに記述を追記してある)$ docker-compose up -d Creating my-wordpress_db_1 ... done Creating my-wordpress_wordpress_1 ... donedocker-compose.ymlversion: '2' services: db: image: mysql:5.7 volumes: - "./.data/db:/var/lib/mysql" ports: - "33060:3306" restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest links: - db ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpress試しに動かして見ると正常に動作することを確認できた
http://localhost:8000/ローカルからMySQLの中身を確認する
外からDBに接続したいのでMacにMySQLを入れる。
[参考]https://brew.sh/index_ja$ brew update $ brew install mysql接続を試みるが失敗する
$ mysql -u root -p -h 127.0.0.1 -P 33060 Enter password: ERROR 2007 (HY000): Protocol mismatch; server version = 11, client version = 10余談だが、hostはlocalhostではなく127.0.0.1を指定しなければならないらしい
[参考]https://teratail.com/questions/139019原因はbrew installでインストールされたMySQLのバージョンが8系だったことのようだった
$ mysql --version mysql Ver 8.0.19 for osx10.13 on x86_64 (Homebrew)なので下記記事を参考にローカルマシンのMySQLを5.7系へ変更した
https://qiita.com/t_oginogin/items/76ca2b6ce18d53988dc3$ brew search mysql@5.7 ==> Formulae mysql@5.7 $ brew install mysql@5.7 (中略) We've installed your MySQL database without a root password. To secure it run: mysql_secure_installation MySQL is configured to only allow connections from localhost by default To connect run: mysql -uroot mysql@5.7 is keg-only, which means it was not symlinked into /usr/local, because this is an alternate version of another formula. If you need to have mysql@5.7 first in your PATH run: echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile For compilers to find mysql@5.7 you may need to set: export LDFLAGS="-L/usr/local/opt/mysql@5.7/lib" export CPPFLAGS="-I/usr/local/opt/mysql@5.7/include" For pkg-config to find mysql@5.7 you may need to set: export PKG_CONFIG_PATH="/usr/local/opt/mysql@5.7/lib/pkgconfig" To have launchd start mysql@5.7 now and restart at login: brew services start mysql@5.7 Or, if you don't want/need a background service you can just run: /usr/local/opt/mysql@5.7/bin/mysql.server start ==> Summary ? /usr/local/Cellar/mysql@5.7/5.7.29: 319 files, 235.4MBとりあえずインストールはできたみたい。
ただ、mysqlコマンドは依然8系を利用していた$ brew services Name Status User Plist mysql started hoge /Users/hoge/Library/LaunchAgents/homebrew.mxcl.mysql.plist mysql@5.7 stopped $ brew services stop mysql Stopping `mysql`... (might take a while) ==> Successfully stopped `mysql` (label: homebrew.mxcl.mysql) $ brew services start mysql@5.7 ==> Successfully started `mysql@5.7` (label: homebrew.mxcl.mysql@5.7) $ mysql --version mysql Ver 8.0.19 for osx10.13 on x86_64 (Homebrew)mysqlコマンドが指す設定を8系から5.7にしたいので、以下の処理をした
$ mv /usr/local/var/mysql/ /usr/local/var/mysql_80 $ brew unlink mysql Unlinking /usr/local/Cellar/mysql/8.0.19... 88 symlinks removed $ brew link mysql@5.7 --force Linking /usr/local/Cellar/mysql@5.7/5.7.29... 87 symlinks created If you need to have this software first in your PATH instead consider running: echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profileなんか出てたけど気にせず進める。
MySQLのバージョンの確認$ brew services stop mysql@5.7 Stopping `mysql@5.7`... (might take a while) ==> Successfully stopped `mysql@5.7` (label: homebrew.mxcl.mysql@5.7) $ brew services Name Status User Plist mysql stopped mysql@5.7 stopped $ brew services start mysql@5.7 ==> Successfully started `mysql@5.7` (label: homebrew.mxcl.mysql@5.7) $ mysql --version mysql Ver 14.14 Distrib 5.7.29, for osx10.13 (x86_64) using EditLine wrappermysqlコマンドのバージョンが5.7に切り替わったっぽいので、接続を試みる。
$ mysql -u root -p -h 127.0.0.1 -P 33060 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.7.30 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | wordpress | +--------------------+繋がった、よかった。
WordPressをローカルで編集する
ただ、このままだとWordPressを外から開発しづらいので、外からマウンドできるような設定にする
docker-compose.ymlversion: '2' services: db: image: mysql:5.7 volumes: - "./.data/db:/var/lib/mysql" ports: - "33060:3306" restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - "$PWD/wordpress:/var/www/html" links: - db ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpressvolumesにローカルでダウンロードしたWordPressを指定する
最新のWordPressのダウンロードは以下でささっと。$ curl -LO https://ja.wordpress.org/latest-ja.zip && unzip latest-ja.zipローカルの編集がすぐにdockerに反映されるので、サーバ上で開発しているような感覚でできてかなり楽でした。
ログを後からgrepしたい気がしたけど、とりあえず参考になりそうなリンクを見つけてお終い
このままだとエラーが起きた時に開発しづらいなと思ったので、logファイルの特定をしようと思ったが、そんなファイルはなかった
[参考]https://qiita.com/tily/items/adb433505da6c7812725/var/log/apache2/access.logが/dev/stdoutに出力されていて、docker内部には残っっていないので、どうしようか悩み中。。。
以下を参考にローカルに落とす仕組みを作りたいけど、今の所困っていないので、その設定はまた今度にする。
[参考]https://hacknote.jp/archives/26996/(追記)
以下のようにアクセスログを外にマウントすればいいのでは?と実験してみたらいい感じに全部ログに落ちたので、取り急ぎはこんな感じで中身を確認するためのログを落とすことにする。volumes: - "$PWD/wordpress:/var/www/html" - "$PWD/access.log:/var/log/apache2/access.log"終わりに
Dockerで実際にWordPressを開発するまでの流れの知識が散り散りになっていたので、これを機にまとめました。
- 投稿日:2020-05-13T19:20:05+09:00
PDO
PHPを用いてデータベースにアクセスするにはPDOを利用する。
PDOとは
PDOとは PHP Data Objects の略。
データベースは種類によって、接続方法や操作方法が異なる。
PDOを用いれば、使用しているデータベースが異なっていてもコードの書き方を変える必要はない。使用例
//データベースへの接続 try { $pdo = new PDO('mysql:host=' . $this->DB_HOST . ';dbname=' . $this->DB_NAME, $this->DB_USER, $this->DB_PASSWORD); //プリペアドステートメントのエミュレーションを無効にする $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //例外がスローされるようにする $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //接続を解除する $pdo = NULL; } catch (PDOException $e) { echo "エラーがありました。: " . $e->getMessage() . "<br />"; die(); }
- 投稿日:2020-05-13T17:36:49+09:00
PHP配列表示
はじめに
こちらではphpで配列の表示について書いていきたいと思います。
受け取ったものに対し内容が何であるかを把握するのはその後の処理において必要になると思います。環境
CentOS
PHP 7.3.17内容
具体的な内容・・・・と言っても基本的な内容ですが・・・
主に使うのはvar_dump
print_r
var_exportこの三種類を使っていこうかとおもいます。
と言ってもやることはシンプルなんですけどね・・・index.html<!DOCTYPE html> <html lang="ja"> <head> <title>index</title> </head> <form action = "test.php" method = "post"> <input type = "text" name ="comment"><br> <select name="select"> <option value="option1">option1</option> <option value="option2">option2</option> <option value="option3">option3</option> </select> <input type="submit" value="送信"> </form> </html>test.php<?php //入力チェック if(empty($_POST["comment"])){ echo "未入力です。"; }else{ $comment=$_POST["comment"]; } echo $comment; echo "<br>"; //入力チェック if(empty($_POST["select"])){ echo "未入力です。"; }else{ $select=$_POST["select"]; } echo $select; echo "<br>"; //配列格納 $arrey = [ $comment, $select ]; echo "var_dump → "; var_dump($arrey); echo"<br>"; echo"print_r → "; print_r($arrey); echo"<br>"; echo"var_ecport → "; var_export($arrey); ?>まとめ
いかがだったでしょうか
それぞれ表示される内容が違うと思います。
その時々で使い分けていきたいですね。
- 投稿日:2020-05-13T17:15:37+09:00
Composer によるパッケージのアップデート入門
はじめに
「パッケージをアップデートしたらなんかエラー出た」
なんてことにならないために、雰囲気でやっている Composer によるパッケージのアップデートをちゃんと理解しながら行いたい。そんな人向けの記事になります。
環境
- Composer 1.10.x (Installed with Homebrew)
事前知識
- PHP と Framework のバージョン
- セマンティック・バージョニング
- Composer によるバージョン指定方法いろいろ
- composer.lock ファイル
入門なんで細かなことは抜きにしたいですが、最低でも上記の 4 つはおさえておきましょう。
PHP と Framework のバージョン
「フレームワークをメジャーアップデートしたらなんかエラー出た」。雰囲気でやっていると起こりうるものですが、特にメジャーアップデートは互換性のない変更が含まれている可能性が高いので、アップデートを行う前に、どのような変更がなされているのか、どういう風に修正していけばいいのか、事前に公式ドキュメントをしっかり確認しておくこと。
また、フレームワークのメジャーアップデートは PHP の最低バージョンの要求も変わってくる可能性があるので、そこもしっかり確認しておくこと (拡張モジュールやミドルウェアも含む) 。
それらをクリアした上でアップデートを行い、プログラムの修正をしていきます。これで「なんかエラー出た」ということは少なくなりますし、ユニットテストなどを書いていれば尚良し、よりスムーズにメジャーアップデート作業はできるかと思います。
あと欲を言えば、開発/ステージング/本番環境で使用する言語やミドルウェアのバージョンを合わせておくのが理想ですが、それはまた別のところで。
備考: フレームワークによっては LTS バージョン (長期サポート版) が提供されているものもあるので、もしあればそれを選ぶことをおすすめします (メジャーアップデートによる大幅な修正/変更回数を減らせるため) 。またメジャーアップデート版がリリースされたからといってすぐに飛びつくのではなく、ある程度期間をあけてパッチバージョンがいくつか出てから手を出したほうがよりバグを踏むことが少なくなるのでおすすめです。
セマンティック・バージョニング
(セマンティック・バージョニングがわからない人はまずはこれを読んでください)
依存しているパッケージがセマンティック・バージョニングの取り決めに従っているかは実際のところパッと見ではわかりません。ということは、とあるパッケージのパッチバージョンをアップデートしただけで互換性のない変更が行われ「エラーが出てしまった」ということもあり得るわけです。
じゃあどのように対策すればいいかというわけですが、基本的には使用しているフレームワークのバージョン指定方法を変えないこと。例えば Laravel の 5.5 系だと composer.json には
"laravel/framework": "5.5.*"と書かれており、7.x 系だと"laravel/framework": "^7.0"と書かれています。これにはちゃんと意味があり、互換性を保つための指定方法で書かれています。なのでこの場合は雰囲気でパッチバージョンのアップデートをしてもそうそう壊れることはありません (フレームワーク側のバグで壊れることもありますが...) 。またフレームワークに関連するパッケージも初期の指定方法から変えないことで安定したアップデートができるかと思います。
あとは composer.json に書かれているパッケージすべてにおいてセマンティック・バージョニングの取り決めに従っているかを GitHub なり公式ドキュメントで確認する他ありません。しっかりやっておきましょう。
特に注意すべき点は、セマンティック・バージョニングの取り決めに従っていたとしても、バージョンが 0 系ならマイナー/パッチバージョンのアップデートでも互換性のない変更が行われる可能性があるということです。
しっかり把握しておきましょう。Composer によるバージョン指定方法いろいろ
Composer のパッケージのバージョン指定方法にはいくつかのやり方があり、正直とてもわかりにくいです。ただここがわからないと雰囲気でアップデートするはめになるので、しっかり覚えておきましょう。具体的には以下:
{ "require": { "vendor/package": "1.3.2", // 1.3.2 "vendor/package": ">=1.3.2", // 1.3.2 以上 "vendor/package": "<1.3.2", // 1.3.2 未満 "vendor/package": "1.3.*", // 1.3.0 から 1.4.0 未満 "vendor/package": "~1.3.2", // 1.3.2 から 1.4.0 未満 "vendor/package": "~1.3", // 1.3.0 から 2.0.0 未満 "vendor/package": "^1.3.2", // 1.3.2 から 2.0.0 未満 "vendor/package": "^1.3", // 1.3.0 から 2.0.0 未満 } }キャレットでの指定方法はセマンティック・バージョニングの取り決めに従っているパッケージかな?と読み取ることもできますね (従っているかはわからない、あくまで読み取れるだけ) 。
指定方法はまだまだありますが、アップデートで指定するものは上記らへんかなと。その他は Versions and constraints - Composer で確認できます。
composer.lock ファイル
Composer による依存パッケージのインストール、およびアップデート/削除などを行うと composer.lock ファイルが自動で生成/更新されます。以降はパッケージの更新がない限り composer.lock ファイルに書かれたバージョンがインストールされます。
要は別の誰かが composer install しても composer.lock ファイルがあるかぎり同じバージョンのパッケージがインストールされるわけなので、パッケージの更新などをした場合でバージョン管理システムを使っているなら、composer.lock ファイルもガンガン add して commit して push しておきましょう。僕と誰かしらを繋ぐとても重要なファイルなのです。
パッケージのアップデートをしてみる
事前知識が長くなってしまいましたが、では実際にパッケージのアップデートをやっていきましょう。
以下のようにします...か?:
composer updateうーん...ちょっと待った。違いますよ。上記のような大雑把なアップデートはなるべく避けましょう。
まずはどのパッケージがアップデート可能な状態であるか以下のコマンドで確認します:
composer outdated -Dで、個別にパッケージのアップデートをやっていきます:
composer require "vendor/package:^1.3" --update-with-dependencies開発環境でのみ使用するパッケージには
--devを付けます:composer require --dev "phpunit/phpunit:^8.0" --update-with-dependenciesで、ユニットテストなどを走らせてバグがないか確認していきます。で、また次のパッケージのアップデートをやっていきます。以下のようなことを繰り返していく感じです:
composer outdated -D composer require "vendor/package:^2.1" --update-with-dependencies vendor/bin/phpunitいきなり
composer updateをやってしまうと、もしバグなどが発生した場合にどのパッケージによるバグなのか把握するのに時間がかかるので、そこは踏みとどまって、しっかり個別にアップデートを行い、正常に動作しているか確認した後に、また他のパッケージのアップデートをやる、という流れでやっていきましょう。また、互換性のない変更があった場合に、パッケージによっては標準出力にて Changelog などを流してくれるものもあるので、これもしっかり確認しておきましょう。
備考: 個人的に一番確実なのは、パッケージを個別にアップデートするのと、GitHub のコミットや Changelog などで変更を確認しつつ、パッチバージョンであってもひとつひとつバージョンを決め打ちして上げていくことです:
composer outdated -D composer require "vendor/package:1.3.2" --update-with-dependencies vendor/bin/phpunitこうすることによって、どのバージョンでバグが発生したかわかりますし、どのパッケージがセマンティック・バージョニングの取り決めに従っているかどうかも把握しなくていいし結果的には楽です。ただ依存するパッケージの数が多いとちょっとめんどくさいのと、バージョンの指定が手入力になるので、最悪の場合、脆弱性の含んだバージョンを誤って指定してしまうこともなくはないので (自分は
composer outdated -Dで出力されたものをコピペしてるので安心...でもないが)、プロジェクトによってはおすすめできない。あとはアップデートをする前に GitHub の issue を確認しておくこと。意外とパッチバージョンのアップデートでもバグは発生します...。まとめ
一つのアプリケーションは非常に多くのパッケージに依存しているし、機能が多ければ多いほどプログラムもより複雑になり、そんな中でバグを 0 % にするのは非常に難しいとは思いますが、雰囲気でやっているあれやこれやを少しでも減らすことによって、どのパッケージのバグであるかなどの把握に繋がることもあります。そういう意味で、あらためて、Composer によるパッケージのアップデート入門という記事を書いてみました。
でもまだまだ雰囲気ですよ。完全に理解なんかできない。
関連リンク
セマンティック バージョニング
Basic usage - Composer
Versions and constraints - Composer
- 投稿日:2020-05-13T16:57:04+09:00
Phalconのバージョンアップ対応についてざっくりまとめ
はじめに
筆者はPHP歴1年半、Phalcon歴1ヶ月程度のひよっこです。
記事は調査した上で実際に手を動かして検証した内容にしていますが、もしかしたら誤りがあるかもしれません。
その際は遠慮なくご指摘ください!Phalconとは?
PHPの軽量フレームワークで、メジャーなPHPフレームワークでは最速レベルのようです。
理由はフレームワークの本体がC言語 or Zephirで書かれているPHP拡張モジュールだからです。
MVCモデルでフルスタックフレームワークでもありますが、ディレクトリ構造のしばりがゆるくて自由な実装が可能です。
その分玄人向けで、日本語情報も少ないので学習コストは高めのようです。1系~3系と4系以降の違い
バージョンアップ時に大事なのが後方互換性です。
メジャーバージョンが同じである場合は確実な後方互換性があるようです。
メジャーバージョンは変わっていますが、1系~3系は後方互換性が高いです。
4系以降とそれ以前はかなり仕様が変わっていて、1系~3系から4系以降にバージョンアップする場合はある程度大きな改修になることを覚悟したほうが良さそうです。Phalconのインストール方法
いくつかインストール方法はありますが、一番楽なのはpeclコマンドを用いた方法です。
$ pecl channel-update pecl.php.net $ pecl install phalconpeclコマンドだと最新バージョンが指定されるので、バージョンを指定する場合はGit経由でソースを取得してビルドする必要があります。
$ yum -y install git $ git clone git://github.com/phalcon/cphalcon.git \ $ cd cphalcon/build \ $ git checkout 3.4.x \ $ ./installフレームワークの有効化
PHP拡張モジュールなので、他の拡張モジュールと同じ場所に配置されます。
php.ini等で読み込んであげる必要があります。phalcon.iniextension=psr.so extension=phalcon.soコードを修正
参考資料
公式ドキュメント
王道ですね。
Phalconは公式が複数言語のドキュメントを提供しており、日本語も対応してます。
が、有志による翻訳作業のようで一部英語だったり、ページよってはほとんど英語の場合も…。
その場合はGoogle翻訳などで頑張りましょう。
公式ページを見る限りVer3.4とVer4.0のドキュメントがありますが、多少バージョン違いでも参考にできると思います。
また、新・旧の変更内容についてはリリースノートが参考になります。
4系へのアップグレードガイドもあるようです。Google先生
困ったときのGoogle先生ですが、Phalconについては日本語で検索するとあまり情報が出てきません。
まずは公式ドキュメントで関連する箇所の仕様を把握した上で、英語情報も積極的に対象に含めつつ調べたほうが良さそうです。静的解析
多くの場合、PhalconだけでなくPHPのバージョンアップを伴うと思います。
そういった場合は、PHPStanなどの静的解析ツールを使用すると修正が必要な箇所を洗い出しできます。
PHPStanを実行するPHPがPhalconのPHP拡張モジュールを読み込んだ状態で実行すれば、フレームワーク部分の処理は認識してくれるみたいです。
※私はオートロードを上手く解決できなかったのでPHPStanでの解析は諦めました…デバッグ
強引ですが最終的に確実なのは、アプリケーションを動かしながらエラーを潰していく方法です。
Xdebugを導入したり、PHPのエラー出力(display_errors・error_reportingなどの指定)範囲をできるだけ低くしてみるのが手っ取り早いと思います。
事前に調査・解析して修正しても最終的には動作検証は必要でしょう。
テストコードがちゃんと書かれている場合はもっと楽できるかもしれませんね。バージョンアップでエラーになりがちだった箇所
私はPhalcon 1系 → 3系、PHP 5.3 → 7.3へのバージョンアップを行いました。
Phalconの処理でエラー(実際には警告レベルも含む)になった箇所は、非推奨になったメソッドやForm系のクラスの挙動が微妙に変わっててハマったぐらいです。(いまだに細かい仕様は理解できてないですが…)
非推奨になった箇所は代替が全て存在していたので公式ドキュメントを読んで置き換えていくだけでした。PHP5.3 → PHP 7.3に上がったことによって今まで顕在化しなかったバグの修正のほうがはるかに多かったです…。
おわり
ざっくりした内容になってしまいましたが参考になれば嬉しいです。
- 投稿日:2020-05-13T16:06:32+09:00
C#アプリケーションからPHP経由でデータベースにデータを一括登録する方法
背景
従来Excelで管理していたデータをデータベース管理に移行したいと思い、いろいろと調べていたのですが、WindowsアプリケーションからWeb系へアクセスするような事をされている方が少ないのか、なかなか情報が見つかりませんでした。
Excelから直接MySQLへのアクセスも検討したのですが、Excelからだと使用者のPCにODBCドライバのインストールが必要になり、PC毎にインストールをしてもらうのは大変なので、ODBCに頼らないデータ転送手法を模索しました。構成
元々Excelの帳票とそれをVBAのマクロでかき集めたシートで構成していたものを、Excelの帳票を読み込み、Web経由でデータベースへ流し込むという構成を検討しました。
Excelに限らず様々なデータを転送できるようにするため、帳票の読み込みはC#のアプリケーションによって作成することにしました。
また、登録するデータは複数のレコードを一括登録するために、構造体渡しのような形をとりたく、流行りのJSONフォーマットを使用。
データの受け渡しイメージは次の通りです。
C#アプリケーション > PHPページ > SQLデータベースサンプルコード
送信するデータ
一括送信に使いたいデータ内容は次の通り。
元々はPOSTにてデータを渡す予定であったため、rootという頭のデータを作り、その中に実際に使用するデータを入れていますが、後述のPHP側の呼び出しでは平のデータでも大丈夫なのかもしれません。data.json{ "root": [ { "data1": 100, "data2": "sample" } ] }送り側処理
JSONデータを生成し、送信するためのコードです。
予めJSONで渡したいデータと同じ構造を定義し、構造体のようにセットすることでやりとりが簡単になります。
下記サンプルでは前述のように一旦rootという親を設けている関係で、データのセットはDataクラスで直接作成し、後でDataContainerにセットする形をとっています。
送信について、WebRequestで指定するデータの送り先は、受信処理を記述した自作のページregist.php(後述)となります。
URLについてはphpコードの設置先の環境に合わせて変更してください。sender.cs// =========================== // データ定義 // =========================== [DataContract] public class DataContainer { [DataMember] public Data root { get; set; } } [DataContract] public class Data { [DataMember] public int data1 { get; set; } [DataMember] public string data2 { get; set; } } // =========================== // 送信処理 // =========================== private void Proc() { // データの生成(実際にはフォームや帳票データからの転記) Data _data = new Data(); _data.data1 = 100; // 数値データ _data.data2 = "sample"; // 文字列データ // 送信データの生成(JSONコードへの変換) DataContainer _container = new DataContainer(); _container.root = _data; var _serializer = new DataContractJsonSerializer(typeof(DataContainer)); MemoryStream _stream = new MemoryStream(); _serializer.WriteObject(_stream, _container); string _param = Encoding.UTF8.GetString(_stream.ToArray()); byte[] _postData = Encoding.UTF8.GetBytes(_param); // 送信準備 System.Net.WebRequest _req = System.Net.WebRequest.Create("http://sample.com/regist.php"); _req.Method = "POST"; _req.ContentType = "application/json"; _req.ContentLength = _postData.Length; // 送信データの書き込み using(Stream _reqStream = _req.GetRequestStream()) { _reqStream.Write(_postData, 0, _postData.Length); _reqStream.Close(); } // 送信及び結果応答確認 using(WebResponse _response = req.GetResponse()) { switch(((HttpWebResponse)_response).StatusCode) { case HttpStatusCode.OK: // OK時の処理 break; default: // その他の処理 break; } } }受信側処理
通常POSTによって渡されたデータは
$_POSTによって受信しますが、JSON形式についてはうまく受信できないため、file_get_contentsを使用します。
受信後のデータをjson_decodeによって連想配列に格納し利用します。regist.php// 送信されたデータを一括受信する $json = file_get_contents("php://input"); // 送られたデータをJSON形式として認識し、連想配列に格納 $inputs = json_decode( $json, true); // データ登録 $sql = "insert into db_name ( data1, data2 ) values (". $inputs['root']['data1']. ", \"". $inputs['root']['data2']. "\")"; // SQLによるデータベースへの登録 // Query($sql); // 応答 http_response_code(200); // OK何かのお役に立てば幸いです。
参考サイト
- 投稿日:2020-05-13T15:53:09+09:00
Laravelでフラッシュデータ(直後のHTTPリクエストの間だけセッションに保存されるデータ)を使う
フラッシュデータ
Laravelでは直後のHTTPリクエストの間だけセッションにデータを保存し、それ以降は削除されるフラッシュデータという仕組みが提供されています
これまで下記記事で扱ってきました
Laravelでリクエストデータを取得する
Laravelで入力値エラーチェック(validate)を実装する
Laravelでリダイレクトを使う
いずれの場合もリクエストデータをフラッシュデータとして保存していましたが、今回はリクエストデータではなく、サーバサイドで好きな値をフラッシュデータに格納します前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っていますControllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにflashメソッドを追記
public function flash(Request $request) { $request->getSession()->flash('key', 'value1'); $request->getSession()->flashInput(array_merge($request->input(), ['key' => 'value2'])); return view('sample.flash'); }
$request->getSession()->flashでフラッシュデータに保存した場合、old関数で取得できません
$request->getSession()->flashInputでフラッシュデータに保存した場合、old関数を使って取得します(2) /sample/routes/web.phpに下記を追記
Route::get('sample/flash', 'SampleController@flash');viewの作成
/sample/resources/views/sample/flash.blade.phpファイル作成
flash.blade.php<html> <head> <title>sample</title> </head> <body> <div>{{ session('key') }}</div> <div>{{ old('key') }}</div> </body> </html>動作確認
http://localhost/laravelSample/sample/flash実行結果
value1 value2
$request->getSession()->flash
$request->getSession()->flashInput
どちらで保存したフラッシュデータも出力されました
- 投稿日:2020-05-13T15:18:40+09:00
CakePHP3+ HTTP_Request2
というか、プラグインのインストールに手こずった。
ポイントは、"/var/www/html/my_app"ディレクトリでインストール作業しなさいってことだった。参考
https://book.cakephp.org/3/ja/plugins.html
Dockerfile
FROM amazonlinux:2 # こんなにインストールいらないかもしれない RUN yum update -y && \ yum clean all && \ amazon-linux-extras install php7.3 && \ yum install -y wget zip unzip tar httpd && \ yum install -y php php-gd php-mbstring php-xml php-pecl-zip php-pgsql php-pear php-intl && \ yum clean all RUN curl -s http://getcomposer.org/installer | php && \ mv composer.phar /usr/local/bin/composer WORKDIR /var/www/html RUN composer create-project --prefer-dist --no-dev cakephp/app:3.8.* my_app # http_request2 WORKDIR /var/www/html/my_app RUN composer require pear/http_request2:2.3.* CMD ["/usr/sbin/httpd","-D","FOREGROUND"] EXPOSE 80使用
/var/www/html/my_app/src/Controller/ExampleController.php<?php namespace App\Controller; use App\Controller\AppController; use HTTP_Request2; class ExampleController extends AppController { /** * */ public function test() { ・・・ $req = new HTTP_Request2(・・・); ・・・ } }
- 投稿日:2020-05-13T14:31:24+09:00
PHPエラー出力
はじめに
こちらではphpのエラーを出力するやりかたを紹介できればと思います。
コードを書く上でミスを絶対にしないなんてありえないでしょう。
小さなミス・初歩的なミスから動かないなんていうのもザラだと思います。
その上でエラーを表示させるのは重要な問題解決になります。環境
Cent0S
PHP 7.3.17
Apache/2.4.6やりかた
まずphp.iniを設定します
xampp
C:\xampp\php\php.iniLinux
/etc/php.ini今回はわかりやすく画面に表示させるようにしたいと思います。
変更点php.ini#display_errors=Off display_errors=Onapacheを再起動します。
実行結果
では試しに
test.php<?php echo "<div class=red>"; echo "エラー部分" echo "</div>"; ?>画面に
Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting ',' or ';' in /var/www/html/test.php on line 4エラーが表示され4行目周辺が怪しいと出ているのがわかるとおもいます。(今回はその前の行に;(セミコロン)がないためのエラーでした。)
まとめ
いかがだったでしょうかコードを書く上で何が原因かわからないときエラー(エラーログ)を表示させれるようにしていきましょう。(英語ですが。。。)
- 投稿日:2020-05-13T13:29:21+09:00
Laravelでリダイレクトを使う
前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っていますControllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにredirect1メソッド、redirect2、redirect3メソッドを追記
public function redirect1(Request $request) { return view('sample.redirect1'); } public function redirect2(Request $request) { return redirect('sample/redirect3')->withInput(); } public function redirect3(Request $request) { return view('sample.redirect3'); }redirect('sample/redirect3')でsample/redirect3にリダイレクトするRedirectResponseクラスのインスタンスが返ってきます。これをreturnするとリダイレクトされるのですが、
さらに、redirect2へのリクエストデータをredirect3でもold関数で使えるようにするためにwithInputを呼んでいます
withInputを実行すると、入力値が次のユーザーリクエストの処理中だけ利用できるフラッシュデータとしてセッションに保存されます(2) /sample/routes/web.phpに下記を追記
Route::get('sample/redirect1', 'SampleController@redirect1');
Route::post('sample/redirect2', 'SampleController@redirect2');
Route::get('sample/redirect3', 'SampleController@redirect3');viewの作成
(1) /sample/resources/views/sample/redirect1.blade.phpファイル作成
redirect1.blade.php<html> <head> <title>sample</title> </head> <body> <form action="{{ url('sample/redirect2') }}" method="post"> @csrf <div>a<input type="text" name="a" value="{{ old('a') }}"></div> <div>b<input type="text" name="b" value="{{ old('b') }}"></div> <div>c<input type="text" name="c" value="{{ old('c') }}"></div> <input type="submit" > </form> </body> </html>(2) /sample/resources/views/sample/redirect3.blade.phpファイル作成
redirect3.blade.php<html> <head> <title>sample</title> </head> <body> <div>{{ old('a') }}</div> <div>{{ old('b') }}</div> <div>{{ old('c') }}</div> </body> </html>動作確認
http://localhost/laravelSample/sample/redirect1a、b、cに何か値を入力して送信ボタンクリック
sample/redirect3にリダイレクトされました
- 投稿日:2020-05-13T13:20:42+09:00
wordpressでドキュメントの有効期限切れ対策
現象
POSTで検索結果を送信した後にブラウザバックするとこれが出る。
対策
バージョン
wordpress 5.4.1
対策方法
これをfunctions.phpに貼り付けたら終わり。
function add_header_session() { header("Cache-Control: private"); header("Pragma: no-cahce"); header("Expires: "); header("Last-Modified: "); } add_action( 'send_headers', 'add_header_session' );備考
調べると以下のような対応方法も出てきますが、wordpressだとうまくいかないです。
session_cache_limiter("none"); // or session_cache_limiter("private_no_expire"); // をsession_start()の前につける
- 投稿日:2020-05-13T10:10:55+09:00
PHP 入力データから一致した指定値の取り出し複数パターン 連想配列
まだまだPHP勉強し始めです。
題名にある通り配列取り出しの例が何個かできましたので
見直す時用です。
上に感想でその下に該当コード1,これはarray_searchとarray_columnの組み合わせでpostされたデータと一致させる方法
$data = [ ['id' => '1','pass' => '111', 'name' => '山田'], ['id' => '2','pass' => '2222', 'name' => '田中'], ['id' => '3','pass' => '3333', 'name' => '佐藤'], ]; if (isset($_POST['id'], $_POST['pass'])){ if(empty($_POST['id']) ||empty($_POST['pass'])) { $notice = "値がどれか入ってないよ"; }elseif (array_search($_POST['id'], array_column($data, 'id')) && array_search($_POST['pass'], array_column($data, 'pass'))) { $result = array_search($_POST['id'], array_column($data, 'name')); $notice = $data[$result]['name']; } else{ $notice = '一致してません。'; } } print_r ($notice);2,こいつはpasswordCheckと言う関数を作成し、
貰ったデータの処理を中でひとまとめにする方法
関数内にforeachですねfunction passwordCheck($id, $pass) { $data = [ ['id' => '1', 'pass' => '1111', 'name' => '山田'], ['id' => '2', 'pass' => '2222', 'name' => '田中'], ['id' => '3', 'pass' => '3333', 'name' => '佐藤'], ]; foreach ($data as $row) { if ($row['id'] === $id && $row['pass'] === $pass) { return $row['name']; } } return false; } $name = passwordCheck($_POST['id'], $_POST['pass']); var_dump($name);3,これが一番わかりやすいかな、、、?
if文がtrueなら代入するよーって
foreach使ってますね。$data = [ '山田' => ['id' => '10','pass' => '1111'], '田中' => ['id' => '20','pass' => '2222'], '佐藤' => ['id' => '30','pass' => '3333'], ]; $id = filter_input(INPUT_POST, 'id'); $pass = filter_input(INPUT_POST, 'pass'); $matched = false; $matched_name = ''; foreach ($data as $name => $val) { if (($val['id'] === $id) && ($val['pass'] === $pass)) { $matched = true; $matched_name = $name; } } if ($matched == true) { echo $matched_name; } else { echo '一致してません。'; }4,これも多次元配列での取り出し方
$data = ['名前1' => ['id' => '1','pass' => '1111'], '名前2' => ['id' => '2','pass' => '2222'], '名前3' => ['id' => '3','pass' => '3333'], ]; if(isset($_POST['id'], $_POST['pass'])) { // 値があるかをチェックします(どちらも入ってないと処理しない) if(empty($_POST['id']) || empty($_POST['pass'])) { // どちらかの値が未入力なのでエラー $getName = "値がどれか入ってないよ"; } else { // $dataを回します foreach($data as $name => $val) { // そもそも$valをさらに回す必要はなくて、$va['id']で取得できるので // idとpassの両方が送られた値と同じであるか確認して if($val['id'] === $id && $val['pass'] === $pass) { // 二つとも一致したらその名前の部分$nameを一旦なんかにいれて $getName = $name; } } } } // 外に出してあげれば echo $getName;配列内のデータを探すのにはarray_columnかforeachが基本的に使われる。
まだまだPHP歴浅いですが色々と、、
- 投稿日:2020-05-13T03:31:25+09:00
複数プログラミング言語より Factom ブロックチェーンのアクセス
Kompendium LLC は色んなプログラミング言語知識と効果的な Factom のグループです。
グループのいずれかの目標は Factom エコシステムに多くの開発者を引き続け、案内や簡単に
の理解等を申し上げることです。ブロックチェーンには継続的な拡張のシステムがあるのでソ
フトウェア遷移することが大変です。Factom に興味がある開発者ために様々なプログラミン
グ言語でスムーズに扱うクライアントライブラリの収集を提供し、Factom エコシステムの開
発ツールボックスも拡大する。顧客の選択言語に利用できないライブラリは思いとどまらせる
原因です。それを防止するように Factom エコシステムの開発ツーリングの改善を努力してい
ます。大分のブロックチェーンはスマートコントラクト機能が無いですが Factom コミュニティと開
発者はスマートコントラクトの統合と標準に向け、ブロックチェーンへすぐに低レベルアクセ
ス機能を要求して続けます。普通に5~10 までの多くライブラリの言語があります。多重の Factom クライアントは Java、
C#、パーソンに利用可能があります。人気がない言語も Factom プロトコルに広い API システ
ムを利用することです。三つの API エコシステム
-factomdAPI サブセット
-walletdAPI サブセット
-debugAPI サブセット
上の API サブセットは Factom プロトコルのリファレンス実装である実行ファイルにより表示
させます。ソフトウェアエンジニアとプログラミング言語のコミュニティを収容するため大きなライブ
ラリを下記のプログラミング言語に作成していました。
-PHPhttps://github.com/kompendium-ano/factom-php-client
-Rubyhttps://github.com/kompendium-ano/factom-ruby-client
-Swifthttps://github.com/kompendium-ano/factom-swift-client
-Haskellhttps://github.com/kompendium-ano/factom-haskell-client
-Rusthttps://github.com/kompendium-ano/factom-rust-client上のクライアントはネイティブの JSON RPC API 用です。Remote Procedure Call (RPC) という強
いデータ移動技術ですが頻りに作りつらいです。 RPC の実用一部は開発者へ高いレベルの一般
性と柔軟性を提供することです。 PHP と Ruby は動的な言語ので幅広い用途です。私たちの PHP
と Ruby ライブラリは実行中の品質を確認するため疲労テスト範囲行いを実施しています。Rust と Haskell は安全的な言語として少ないテスティングがあってもバグ無しソフトウェアが
実現することできます。開発の最初でが頻りに加速できます。静的タイプのシステムはビルド
する前に似合わないコーディングや正式以外等のコーディングを検出し、手動的なテスティン
グ・広いテスト範囲をコンパイラに行います。私たちの Haskell と Rust にあるライブラリは広
範囲テストを組み込むと開発にすでに利用できるし、正しさを確保します。私たちのライブラリは JSON データを指定言語型に割り付けます。ビジネスアプリケーション
向け、データ変換の前に Factom プロトコルで出しいオブジェクト・型を直接に検証です。
次の記事は各 Kompendium Factom プロトコルのコミュニティライブラリの特徴と小さなアプ
リケーションのビルドの説明をさせて頂けます。
- 投稿日:2020-05-13T01:38:34+09:00
PHPで初めてのWebアプリケーション開発 DB(MySQL)設定 備忘録6
前提
PHPを使ったWebアプリケーションの開発知識が必要になったので、開発過程の備忘録、知識のインプット・アウトプットを目的としている。
環境
macOS Catalina 10.15.3
Laravel 7.10.3
PHP 7.3.11備忘録6 目次
MySQL接続
- MySQLのインストール
- MySQLの認証プラグインの変更
- データベースの作成
- Laravelの.envファイルの修正
- laravelのconfig/databese.phpファイルの修正
テーブルの作成
- マイグレーションファイルの作成
- シーダーファイルの作成
- マイグレートの実行
- テーブルを画面に表示する
MySQLに接続
手元にある「Laravel 入門」ではSQLiteの接続方法を紹介しているが、MySQLを利用したかったので、MySQLの接続方法を確認。
MySQLのインストール
MySQLもHomebrewでインストール。
参考にした記事→「【Laravel】MySQLの接続方法を徹底解説【コピペでOK】」
MySQLの認証プラグインの変更
認証プラグインの変更も参考にした記事通りに実行したら、特にエラーも無く接続できた。
参考にした記事→「【Laravel】MySQLの接続方法を徹底解説【コピペでOK】」
データベースの作成
作成しているアプリのデータベースを作成する。
ターミナルでMySQLにログイン後、以下のコマンドを入力。create database NanaitaApp(データベース名);データベースができているか確認
show databases;Laravelの.envファイルの修正
変更箇所のみ記載
「DB_DATABASE=''」は作成したデータベース名。DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=NanaitaApp DB_USERNAME=root DB_PASSWORD=secretlaravelのconfig/databese.phpファイルの修正
変更箇所のみ記載
databese.php'mysql' => [ 'database' => env('DB_DATABASE', 'NanaitaApp'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', 'secret'), ],テーブルの作成
テーブルの作成は、勉強も兼ねてLaravel側からマイグレーションとシーディングを使って行う。
マイグレーションファイルの作成
マイグレーションファイルはターミナルから作成
カレントディレクトリをプロジェクトフォルダに移動してから、以下のコマンドを実行。php artisan make:migration create_nana_users_tableマイグレーションファイル
マイグレーションファイルにテーブルの中身を追加nana_userspublic function up() { Schema::create('nana_users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('mail'); $table->string('password'); $table->timestamps(); }); }ファイルに追記したら以下のコマンドでマイグレートを実行
php artisan migrateMySQLにログインしてテーブルとカラムが作成されているか確認
use NanaitaApp; show tables; desc nana_users;データベースの中にテーブルが作成されていることを確認
テーブルの中にカラムが作成されていることを確認
シーダーファイルの作成
ダミーレコードを作成するためにシーディング機能を使ってシーダーファイルを作成
シーダーファイルはターミナルから作成
カレントディレクトリをプロジェクトフォルダに移動してから、以下のコマンドを実行php srtisan make:seeder NanaUsersTableSeederプロジェクトフォルダでdatabase/seedsにNanaUsersTableSeeder.phpファイルが作成されているのを確認
シードを作成する処理を追記
NanaUsersTableSeeder<?php use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; class NanaUsersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $param = [ 'name' => 'taro', 'mail' => 'taro@yamada.jp', 'password' => '12', ]; DB::table('nana_users')->insert($param); $param = [ 'name' => 'hanako', 'mail' => 'hanako@flower.jp', 'password' => '34', ]; DB::table('nana_users')->insert($param); $param = [ 'name' => 'sachiko', 'mail' => 'sachiko@happy.jp', 'password' => '56', ]; DB::table('nana_users')->insert($param); } }作成したファイルが実行されるように、デフォルトで用意されているDatabaseSeeder.phpに登録する。
database/seedsにあるDatabaseSeeder.phpを以下のように修正DatabaseSeeder.php<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call(NanaUsersTableSeeder::class); } }最後にターミナルからシーディング処理を実行する
php artisan db:seedテーブルを画面に表示する
今回はテスト用にtest.blade.phpを作成して表示
test.blade.index@extends('layouts.loginform') @section('title','test') @section('content') <div class='list-card'> <table> <tr><th>Name</th><th>Mail</th><th>Password</th></tr> @foreach ($items as $item) <tr> <td>{{$item->name}}</td> <td>{{$item->mail}}</td> <td>{{$item->password}}</td> </tr> @endforeach </table> </div> @endsectionサーバーを起動してlocalhost:8000/testにアクセス
無事表示された。
おわりに
次回は掲示板機能の実装を行っていきたいと思う。











