- 投稿日:2019-12-23T23:43:56+09:00
GitHub ActionsでmasterにpushしたときにPHP-CS-Fixerを動かしてcommit&pushする
GitHubのmasterにpushしたらPHP-CS-Fixer動けば楽だなぁと思い、GitHub Actionsで実装
やり方は色々ありそうだが、自分がやったのはcomposer require --dev friendsofphp/php-cs-fixerでcomposerでインストールされるようにする
.github/php-cs-fixer.ymlname: PHP-CS-Fixer on: push: branches: - master jobs: php-cs-fixer: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: Install Dependencies run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist - name: Execute PHP-CS-Fixer run: vendor/bin/php-cs-fixer fix . - name: Commit files run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git commit -m "Add changes" -a - name: GitHub Push uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }}ad-m/github-push-actionは得体のしれなさもあるけど、GitHubActionsの中で星がたくさんついてたから大丈夫でしょうという感じ
master以外にプッシュするとかもad-m/github-push-actionの説明を見るとできる
https://github.com/ad-m/github-push-action
secrets.GITHUB_TOKENは勝手に入ります
- 投稿日:2019-12-23T22:20:05+09:00
[GCP] Cloud Run + PHP なチュートリアルこなしたよ
簡易 Cloud Run
-> Cloud Functions みたい関数がコンテナ実行できるようになってフレキシブルになったよ
-> App Engine standard に対する flexible environment みたいな
- コンテナだから
- Cloud Build でビルドできる
- 好きなライブラリを持って実装できる
- 環境に依存しない
- Container Registry で脆弱性診断できる
- サーバーレスなので
- スケーラブル
- インフラ気にせんでいい
参考になる記事 -> [Google Cloud] GKE と Cloud Run の使い分け
まぁ, 両方使いたいよね
話はそれたがチュートリアルはこれ
https://cloud.google.com/php/getting-started/background-processing#deploying_the_web_app内容的にはかなりよく, Cloud Run のよさをすぐ体感できた
Schweinchen
感想など
- git clone https://github.com/GoogleCloudPlatform/getting-started-php.git するのが早い
- PROJECT_ID, ZONE がベタ書きなのがつらかった
$PROJECT_ID
とか$ZONE
とか変数で書いといてくれー- stackdriver 強い, 情報細かい, 負荷試験捗りそう
- なぜか Datastore API が有効になったので Firestore API へ切り替える必要があった
- Datastore > ネイティブモードへ切替
GCPは公式ドキュメントがよく実際試して理解できるやつが多くて楽しいですね
- 投稿日:2019-12-23T21:43:39+09:00
【Laravel】Requestによるバリデーションは効かせつつ、他は共通エラー
Requestによるバリデーションチェックによるエラー表示は機能させつつ、
他のエラー発生時は共通エラー画面に遷移させる方法です。環境
- PHP:バージョン7.3.7
- Laravel:バージョン5.8
- OS:Windows10
はじめにやったこと
エラーが発生したら、とりあえずエラー画面に遷移させればいいんだよね、
というわけで、デフォルトの記述をコメントアウトし、以下のように変更。
※リダイレクト先は、\routes\web.php で制御しています。\app\Exceptions\Handler.phppublic function render($request, Exception $e) { return redirect('/'); /* 以下はデフォルトの記述 return parent::render($request, $e); */ }問題発生
ところが、問題発生。
Requestを使ったバリデーションチェックで、エラー発生時にも共通エラー画面に遷移してしまった。
この場合はエラー内容を自画面に表示させたいので、これでは困る・・・。解決方法
結論から言うと、\app\Exceptions\Handler.phpで、以下のように記述してあげればOK。
\app\Exceptions\Handler.php<?php namespace App\Exceptions; use Exception; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; // 以下を追記 use Illuminate\Validation\ValidationException; class Handler extends ExceptionHandler { ## ## 省略 ## public function render($request, Exception $e) { if($e instanceof ValidationException) { // バリデーションエラー発生時 return $this->convertValidationExceptionToResponse($e, $request); }else{ // それ以外は共通エラー画面へ(リダイレクト先は\routes\web.phpで指定) return redirect('/'); } } }use Illuminate\Validation\ValidationException;
して、バリデーションエラーの場合のみ、
return $this->convertValidationExceptionToResponse($e, $request);
で、バリデーションエラーが出るようにする。
それ以外は共通エラー画面へ。もう少し詳しく見てみる
\app\Exceptions\Handler.phpで読み込まれていた、
\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php
を見てみましょう。\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php## ## 省略 ## use Illuminate\Validation\ValidationException; ## ## 省略 ## class Handler implements ExceptionHandlerContract { ## ## 省略 ## // \app\Exceptions\Handler.phpのrenderファンクションの親に当たるメソッド public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { // この部分を拝借 return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); } ## ## 省略 ##上のように、バリデーションエラーに関する記述があったので、その部分を拝借しました。
※「ValidationException」で検索してみてください。感想
うまく条件分岐させれば、他のエラー発生時にも、応用効きそう。
そのうちやってみようと思います。参考
以下を参考にさせていただきました。
ありがとうございました!
- 投稿日:2019-12-23T20:32:06+09:00
MySQLにLinuxコマンドからエクスポート、インポートする方法
よく忘れるのでメモ用。
特定のデータベースの中身を全てエクスポート
以下のコマンドをクリック。
mysqldump -u root -p testdb > dump.sql以上の例では、
rootユーザー、testdbというデータベース名になります。
tesdbの中身を「dump.sql」というファイル名で出力します。以上のコマンドを打った後、パスワードが求められます。
特定にデータベースsqlファイルをインポート
以下のコマンドをクリック。
mysql -u root -p testdb < dump.sql以上の例では、
rootユーザー、testdbというデータベース名になります。
dump.sqlのファイルを、testdbにインポートします。以上のコマンドを打った後、パスワードが求められます。
以上
- 投稿日:2019-12-23T18:23:11+09:00
XAMPPでさえ躓いたときに
XAMPPをまだ使っています。
Dockerコンテナ管理(kubernetesでの管理が目標)を勉強中の私はまだまだPHPの環境を
XAMPPでやっています。そこでよく出くわすエラーをまとめました。
- 環境:Windows10
- 使用したXAMPP V7.2.5の直リンク
ApacheもMySQLも起動できない
XAMPPのControl PanelでApacheもMySQLも起動できないときがあります。
そんな時は
【xamppのルートディレクトリ】\setup_xampp.bat
を実行するとxampp-control.iniが作られて問題を解決することができます。MySQLで接続エラーが発生する。
以下のPHPファイルを
【xamppのルートディレクトリ】\htdocs
配下に置いて接続をテストしてみてくださいconnection_test.php<?php $link = mysqli_connect('localhost', 'username', 'password'); if (!$link) { die('Could not connect: ' . mysqli_error()); } echo 'Connected successfully'; mysqli_close($link); ?>更新履歴
- 2019/12/23 新規作成
- 投稿日:2019-12-23T18:21:27+09:00
[PHP]foreachで配列の中の要素をまとめてキャストする
たとえば…
こういう配列があったとしましょう。
<?php $results = array(); $results[] = array("success_count"=>"0", "failure_count"=>"1"); $results[] = array("success_count"=>"1", "failure_count"=>"0");array(2) { [0]=> array(2) { ["success_count"]=> string(1) "0" ["failure_count"]=> string(1) "1" } [1]=> array(2) { ["success_count"]=> string(1) "1" ["failure_count"]=> string(1) "0" } }全ての要素をintにしたい…!
クエリを叩いたりなんかして、全部の結果がint型も含めて全部Stringは困る…って場面があると思います。
例えば、このsuccess_count
が1件以上あったら、みたいな数値としての比較をしたい時にどうすれば良いか。やってみた
array_mapを使うやり方もあるのですが、今回は
foreach
を使ってやってみました。<?php $results = array(); $results[] = array("success_count"=>"0", "failure_count"=>"1"); $results[] = array("success_count"=>"1", "failure_count"=>"0"); foreach($results as &$result){ $result["success_count"] = (int)$result["success_count"]; $result["failure_count"] = (int)$result["failure_count"]; } unset($result);出力
array(2) { [0]=> array(2) { ["success_count"]=> int(0) ["failure_count"]=> int(1) } [1]=> array(2) { ["success_count"]=> int(1) ["failure_count"]=> int(0) } }ちょこっとポイント
foreachで回す時に、リファレンスを渡すことでforeachを抜けた後もキャストした値は捨てられずに配列に格納されます。
foreach($results as &$result){ここで注意しなければならないのが、foreachを抜けた後に
unset()
を使って参照を解除してあげなければならないことです。foreach($results as &$result){ $result["success_count"] = (int)$result["success_count"]; $result["failure_count"] = (int)$result["failure_count"]; } unset($result); //ここで$resultの参照を解除参照が解除されないままだと、最後の要素の値がどこか意図しないタイミングで書き換えられてしまう可能性があります。
PHPの公式マニュアルに詳細が載っていますので、こちらもぜひ一読ください。foreach($results as &$result){ $result["success_count"] = (int)$result["success_count"]; $result["failure_count"] = (int)$result["failure_count"]; } //unset($result); $result["success_count"] = 10000; //参照を保ったまま最後の要素の値を書き換え出力
array(2) { [0]=> array(2) { ["success_count"]=> int(0) ["failure_count"]=> int(1) } [1]=> &array(2) { ["success_count"]=> int(10000) ["failure_count"]=> int(0) } }
- 投稿日:2019-12-23T15:58:48+09:00
PHP Debug Bar on Slim3
composer require maximebf/debugbar composer require kriswallsmith/asseticdependencies.php... // PHP Debug Bar $container['debugBar'] = function($c) { $debugbar = new StandardDebugBar(); $debugbar->addCollector(new DebugBar\Bridge\MonologCollector($c['logger'])); $renderer = $debugbar->getJavascriptRenderer(); $renderer->setIncludeVendors(false); return $debugbar; }; ...routes.phpuse Slim\App; use Slim\Http\Request; use Slim\Http\Response; return function (App $app) { $container = $app->getContainer(); $app->get('/[{name}]', function (Request $request, Response $response, array $args) use ($container) { $debugbar = $container["debugBar"]; $debugbar["messages"]->addMessage("hello world!"); // Sample log message $container->get('logger')->info("Slim-Skeleton '/' route"); // Render index view return $container->get('renderer')->render($response, 'index.phtml', array_merge($args, [ "debugbarRenderer"=>$debugbar->getJavascriptRenderer() ])); }); };index.phtml<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Slim 3</title> <link href='//fonts.googleapis.com/css?family=Lato:300' rel='stylesheet' type='text/css'> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <style> body { margin: 50px 0 0 0; padding: 0; width: 100%; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; text-align: center; color: #aaa; font-size: 18px; } h1 { color: #719e40; letter-spacing: -3px; font-family: 'Lato', sans-serif; font-size: 100px; font-weight: 200; margin-bottom: 0; } + <?php $debugbarRenderer->dumpCssAssets(); ?> </style> + <script type="text/javascript"> + <?php $debugbarRenderer->dumpJsAssets(); ?> + </script> </head> <body> <h1>Slim</h1> <div>a microframework for PHP</div> <?php if (isset($name)) : ?> <h2>Hello <?= htmlspecialchars($name); ?>!</h2> <?php else: ?> <p>Try <a href="http://www.slimframework.com">SlimFramework</a></p> <?php endif; ?> + <?php echo $debugbarRenderer->render() ?> </body> </html>
- 投稿日:2019-12-23T15:51:56+09:00
pdo_oci "Unable to load dynamic library"
- 投稿日:2019-12-23T11:59:17+09:00
trim()について
なぜtrimで全角スペースを削れると思ったのか
$str = " sample "; trim($str); // 「 sample 」 のまま全角スペースを削るには色々手段がありますが、preg_replaceを使いたいと思います。
$str = " sample "; preg_replace('/[ ]/u', '', $str); // 「sample」「/(正規表現)/u」でUTF-8を明示的に指定するとなお安全。
- 投稿日:2019-12-23T11:00:09+09:00
レンタルサーバーでLaravelを動かす際の環境構築手順とTips
はじめに
この記事はLaravel Advent Calendar 2019の23日目の記事です
過去に培ったレンサバ(さくらサーバ、バリューサーバ)でLaravelを動かすためのアレコレを書いていきます.
.
.という予定だったんですが、さくらサーバーでの環境構築手順メモしか手元に残ってなかったのでほぼさくらサーバーでの環境構築手順になります(主語でかで申し訳ないです)
AWSとかわからんからレンサバでLaravelを動かす
というのはまあ半分冗談で、大体がコストになるとか、先方指定とかで最終的にレンタルサーバーにしてくださいって言われるので、世間的にもそうなのかな?と思いつつ記事書いていきます。
このTipsが誰かの役に立てれば我幸です。情報の鮮度的に19年9月ごろまでの話で今現在以下の通りでない可能性も無きにも非ずです
あとここで想定しているLaravelのバージョンは5.7~5.8系です。さくらのレンタルサーバーで環境構築
※ローカルで作成してプロジェクトがGitホスティングサービス(GitLabとかGithub)上に上がってる前提です。
1,sshでログイン
おそらく借りた直後にssh接続すると以下のような画面になると思います。
FreeBSD 11.2-RELEASE-p5 (GENERIC) #0: Tue Nov 27 09:33:52 UTC 2018 Welcome to FreeBSD! % % ls -la total 56 drwx------ 9 testtest users 512 Dec 13 19:23 . drwxr-xr-x 160 root wheel 3584 Jan 18 10:34 .. -rw-r--r-- 1 testtest users 773 Nov 29 17:01 .cshrc -rw-r--r-- 1 testtest users 258 Nov 29 17:01 .login -rw-r--r-- 1 testtest users 167 Nov 29 17:01 .login_conf -rw-r--r-- 1 testtest users 0 Nov 29 17:01 .php.module -rw-r--r-- 1 testtest users 762 Nov 29 17:01 .profile -rw-r--r-- 1 testtest users 980 Nov 29 17:01 .shrc drwx------ 2 testtest users 512 Nov 18 2009 .spamassassin drwx------ 2 testtest users 512 Nov 18 2009 .ssh drwx------ 3 testtest users 512 Nov 18 2009 MailBox drwx------ 2 testtest users 512 Nov 18 2009 db drwxr-xr-x 2 testtest users 512 Jan 28 2015 sakura_pocket drwxr-xr-x 2 testtest users 512 Nov 18 2009 sblo_files drwxr-xr-x 2 testtest users 512 Nov 18 2009 www2,リポジトリ用のディレクトリを生成する
root
ディレクトリで生成する。以下、ディレクトリ名
repos
で作成した例% mkdir /home/testtest/repos % ls -la total 60 drwx------ 10 testtest users 512 Jan 18 16:10 . drwxr-xr-x 160 root wheel 3584 Jan 18 10:34 .. -rw-r--r-- 1 testtest users 773 Nov 29 17:01 .cshrc -rw-r--r-- 1 testtest users 258 Nov 29 17:01 .login -rw-r--r-- 1 testtest users 167 Nov 29 17:01 .login_conf -rw-r--r-- 1 testtest users 0 Nov 29 17:01 .php.module -rw-r--r-- 1 testtest users 762 Nov 29 17:01 .profile -rw-r--r-- 1 testtest users 980 Nov 29 17:01 .shrc drwx------ 2 testtest users 512 Nov 18 2009 .spamassassin drwx------ 2 testtest users 512 Nov 18 2009 .ssh drwx------ 3 testtest users 512 Nov 18 2009 MailBox drwx------ 2 testtest users 512 Nov 18 2009 db drwxr-xr-x 2 testtest users 512 Jan 18 16:10 repos // これ drwxr-xr-x 2 testtest users 512 Jan 28 2015 sakura_pocket drwxr-xr-x 2 testtest users 512 Nov 18 2009 sblo_files drwxr-xr-x 2 testtest users 512 Nov 18 2009 www3,秘密鍵を生成
サーバーで作成した鍵を各々使っているGitホスティングサービス(GitlabやらGithubやら)から
pull
するのに秘密鍵を生成する。
ssh
ディレクトリがある場所でssh-keygen -t rsa -b 4096 -C "メールアドレス"
を実行その後、
.ssh/id_rsa.pub
の中身を確認し、GitLabやGithubのプロジェクトへ登録する% ssh-keygen -t rsa -b 4096 -C "hoge@example.com" Generating public/private rsa key pair. Enter file in which to save the key (/home/testtest/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/testtest/.ssh/id_rsa. Your public key has been saved in /home/testtest/.ssh/id_rsa.pub. The key fingerprint is: SHA256:************************************************** hoge@example.com The key's randomart image is: +---[RSA 4096]----+ | B .B..o++B=+| | .+o. o.=.+=| |B .o o. . .| |. o o . B . | |. o o . o. | | . oo . oo.| |. B .o. . . +.| |. . + . ++| | B . B ..*| +----[SHA256]-----+ % % ls -la total 60 drwx------ 10 testtest users 512 Jan 18 16:10 . drwxr-xr-x 160 root wheel 3584 Jan 18 10:34 .. -rw-r--r-- 1 testtest users 773 Nov 29 17:01 .cshrc -rw-r--r-- 1 testtest users 258 Nov 29 17:01 .login -rw-r--r-- 1 testtest users 167 Nov 29 17:01 .login_conf -rw-r--r-- 1 testtest users 0 Nov 29 17:01 .php.module -rw-r--r-- 1 testtest users 762 Nov 29 17:01 .profile -rw-r--r-- 1 testtest users 980 Nov 29 17:01 .shrc drwx------ 2 testtest users 512 Nov 18 2009 .spamassassin drwx------ 2 testtest users 512 Jan 18 16:13 .ssh drwx------ 3 testtest users 512 Nov 18 2009 MailBox drwx------ 2 testtest users 512 Nov 18 2009 db drwxr-xr-x 2 testtest users 512 Jan 18 16:10 repos drwxr-xr-x 2 testtest users 512 Jan 28 2015 sakura_pocket drwxr-xr-x 2 testtest users 512 Nov 18 2009 sblo_files drwxr-xr-x 2 testtest users 512 Nov 18 2009 www
.ssh
へ移動して生成されたか確認% cd .ssh/ % ls -la total 16 drwx------ 2 testtest users 512 Jan 18 16:13 . drwx------ 10 testtest users 512 Jan 18 16:10 .. -rw------- 1 testtest users 3247 Jan 18 16:13 id_rsa -rw-r--r-- 1 testtest users 742 Jan 18 16:13 id_rsa.pub % cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAAE/0H( 略 )fdg/tFm4WqQ== hoge@example.com4,秘密鍵を各々のサービスのプロジェクトへ登録
各々使っているGitホスティングサービス(GitlabやらGithubやら)上へ登録する。
GitLabの場合、
プロジェクトを開き、メニューから「Settings」→「Repository」→「Deploy Keys」のタブを開き、「key」に
.ssh/id_rsa.pub
の中身をコピー&ペーストする。
「title」にはわかりやすい名前(サーバー名)を、「Write access allowed」のチェックボックスに関してはそのままで「Add Key」をクリックして完了以下はGitHubの画面だがほぼ同じなので参考になる
5,
git clone
するターミナルに戻り、先程作ったreposディレクトリへ移動し、
git clone
コマンドを実行% cd repos/ % ls -la total 8 drwxr-xr-x 2 testtest users 512 Jan 18 16:10 . drwx------ 10 testtest users 512 Jan 18 16:10 .. % git clone git@gitlab.com:*******/test-project.git Cloning into 'test-project'... The authenticity of host 'gitlab.com (35.231.145.151)' can't be established. ECDSA key fingerprint is SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw. No matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'gitlab.com' (ECDSA) to the list of known hosts. remote: Enumerating objects: 1145, done. remote: Counting objects: 100% (1145/1145), done. remote: Compressing objects: 100% (416/416), done. remote: Total 1145 (delta 756), reused 1078 (delta 695) Receiving objects: 100% (1145/1145), 452.28 KiB | 640.00 KiB/s, done. Resolving deltas: 100% (756/756), done. % ls -la total 12 drwxr-xr-x 3 testtest users 512 Jan 18 16:46 . drwx------ 10 testtest users 512 Jan 18 16:10 .. drwxr-xr-x 4 testtest users 512 Jan 18 16:46 test-projectちなみにサーバーに二つの環境(ステージング環境・本番環境)作る場合は以下の例のように、
/repos
ディレクトリ以下にstaging
とproduction
のディレクトリを作りそれぞれでgit clone
する。[testtest@www4043 ~/repos]$ mkdir stg [testtest@www4043 ~/repos]$ mkdir production [testtest@www4043 ~/repos]$ ls -la total 16 drwxr-xr-x 4 testtest users 512 Jan 18 18:53 . drwx------ 12 testtest users 512 Jan 18 18:03 .. drwxr-xr-x 2 testtest users 512 Jan 18 18:53 production drwxr-xr-x 3 testtest users 512 Jan 18 18:40 stgここからは主に
production
ディレクトリ上での作業を例として説明していきます。【番外】シェルをbashに変更する
個人的に
bash
に慣れているのでchsh
から変更する方法も載せておきます。
which
コマンドでbashの実行ファイルを確認。
chsh
コマンドでオプション-s
(--shell)を指定し、ログインユーザーのシェルを変更する。% which bash /usr/local/bin/bash % chsh -s /usr/local/bin/bash Password: chsh: user information updated今後もこのbashを使用するためのファイルを作る。
root
へ移動してコマンドを叩く% vi .bash_profile以下を記述する
PATH=$PATH:$HOME/bin:$HOME/usr/local/bin export PATH保存(
!wq
)してssh
ログアウト→再ログインする[testtest@www4043 ~]$ cat .bash_profile PATH=$PATH:$HOME/bin:$HOME/usr/local/bin export PATHこれでお馴染みのbashが使えるようになる
6,composerをインストールする
さくらサーバーはComposer(PHPのパッケージ管理システム)が入ってない1
% composer -h composer: Command not found.ちなみにComposerとは
Composer は、PHP のプロジェクトが必要とするライブラリやパッケージを管理する「ライブラリ依存管理ツール」です。
root
へ移動してコマンドを叩く// rootへ移動 $ cd ~ // ディレクトリ生成 //「-p」オプションには「ディレクトリが存在しない場合は、自動で作成される」かつ「作ろうとしているディレクトリが存在していてもエラーにしない」 $ mkdir -p usr/local/bin/ // curl コマンドでcomposerをダウンロード&インストール // 「-sS」でエラーメッセージ表示 // 「--install-dir」で指定のディレクトリへインストールできる $ curl -sS https://getcomposer.org/installer | php -- --install-dir=usr/local/bin/ // composer.pharを上階層のcomposerディレクトリへ移動 $ mv usr/local/bin/composer.phar usr/local/bin/composerインストール後、入ってることを確認する(※
.bash_profile
にパスを通しておくこと)[testtest@www4043 ~]$ composer -v ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.8.0 2018-12-03 10:31:167,プロジェクト内で
composer install
するプロジェクトのディレクトリへ移動後、
composer install --no-dev
コマンドを実行[testtest@www4043 ~/repos/production/test-project/laravel]$ composer install --no-dev Loading composer repositories with package information Installing dependencies from lock file Package operations: 41 installs, 0 updates, 0 removals - Installing doctrine/event-manager (v1.0.0): Loading from cache - Installing doctrine/cache (v1.8.0): Loading from cache // 省略 - Installing psy/psysh (v0.9.9): Loading from cache - Installing laravel/tinker (v1.0.8): Loading from cache Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Package manifest generated successfully.※レンタルサーバーによってはPHPのモジュールがインストールされてなかったりしてエラーが出る場合があります。
リリース前に十分な余裕をもって事前に確認しておきましょう。8,環境設定ファイル(.env)生成
Laravelの標準に
.env.example
があるのでそれをこの環境用に設置するためにコピーコマンドで複製する[testtest@www4043 ~/repos/production/test-project/laravel]$ cp .env.example .env
.env
の中身の例APP_NAME=Laravel APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret // 以下略9,
key:generate
でアプリケーションのキーを発行する
.env
ファイルを作成後、同ディレクトリでphp artisan key:generate
コマンドを実行してください。
Laravelが内部で暗号化に用いるキーになるため、環境ごとに実行するようにしてください。APP_NAME=Laravel APP_ENV=local APP_KEY=****************************************** // ここにランダムなパラメータが生成される APP_DEBUG=true APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret // 以下略10,環境ごとの設定を
.env
に書き込むアプリケーションのキーが生成されたことを確認後、
vi
などで必要箇所(DBの設定や環境等)を編集してください。
(黒い画面慣れてないならFTPでつないで編集しても問題ないです)
ここでDBなどの情報が間違っていると次のフェーズでうまく動きませんあと絶対に
.env
ファイルをpublic
以下(外部から参照できる場所)に配置しないようにしてくださいDon't ? put ? your ? .env ? files ? in ? the ? web-server ?directory https://t.co/DWHmT6r6E3 pic.twitter.com/Qp5tun3CZh
— svbl (@svblxyz) September 26, 2018意外と多いみたいです
そして、構築している環境によって
APP_ENV
とAPP_DEBUG
を適切に設定するようにしてください。
(例:本番環境ならAPP_ENV=production
、APP_DEBUG=false
)特に
APP_DEBUG
が本番環境なのにtrue
に設定していて、バグを踏んだ際にWhoopsが表示されるWebアプリを今までに何個も発見しています。
どれだけ.env
ファイルを参照できない場所へ設置していてもWhoopsが表示されて環境変数を見れる状態だとなんの意味もないです。11,DBを作成(
php artisan migrate
)諸々と環境変数を設定後、
artisan
コマンドを実行してDBを構築[testtest@www4043 ~/repos/production/test-project/laravel]$ php artisan migrate ************************************** * Application In Production! * ************************************** Do you really wish to run this command? (yes/no) [no]: > yes Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table // 省略 // php artisan migrate:statusでできてるか確認 [testtest@www4043 ~/repos/production/test-project/laravel]$ php artisan migrate:status +------+-------------------------------------------------------------------------------------+ | Ran? | Migration | +------+-------------------------------------------------------------------------------------+ | Y | 2014_10_12_000000_create_users_table | | Y | 2014_10_12_100000_create_password_resets_table | | Y | 2018_12_20_122201_create_categories_table | +------+-------------------------------------------------------------------------------------+12,リポジトリとpublicとでシンボリックリンクを張る
root
へ戻ってwww
へ移動し、シンボリックリンクを貼ります。[testtest@www4043 ~/www]$ ln -s /home/testtest/repos/production/test-project/laravel/public/ production [testtest@www4043 ~/www]$ ls -la total 8 drwxr-xr-x 2 testtest users 512 Jan 18 19:23 . drwx------ 12 testtest users 512 Jan 18 19:02 .. lrwxr-xr-x 1 testtest users 64 Jan 18 19:23 production -> /home/testtest/repos/production/test-project/laravel/public/たまにうまくパスを指定していなくて失敗することがある(本人談)ので要注意
13、DBに初期値入れていく(※必要あるなら)
DBへマスタデータなど入れておく必要があるなら
Seeder
を実行しておく[testtest@www4043 ~/repos/production/test-project/laravel]$ php artisan db:seed --class=DatabaseSeeder ************************************** * Application In Production! * ************************************** Do you really wish to run this command? (yes/no) [no]: > yes Seeding: BasesTableSeeder Seeding: CategoriesTableSeeder [testtest@www4043 ~/repos/production/test-project/laravel]$これで一通りの準備ができたはずです。
URLへアクセスして正常に動いていることを確認してください。(ちなみにここまでしなくても「hello, world」したいだけなら10の段階ででできるはずです)
バリューサーバーで動かす(おまけ)
本当はバリューサーバーでの環境構築手順も書く予定でしたが、自分用にまとめた資料がどっか逝ったので覚えている限りのTipsを書いておきます。
PHPのバージョンをコンパネから7.2以上へ変更しておく
おそらくPHPのバージョンがデフォルトで5.6になっている1ので、コントロールパネルから7.2以上のバージョンへ変更してください。
でないとLaravelがそもそも動かないです
(確か5.4系だとPHP5.6でも動いたはずですがおすすめしません)
php
のエイリアスを張っておくデフォルトでコマンドをたたく際はコンパネから設定した
PHPバージョン
+実行したいコマンド
を打つ必要があるので、環境構築の初めにphpのエイリアスを張っておきましょう。
でないと、以下のようにphp56cli composer.phar -Vと、
php[version]cli
と書かないとコマンド実行できません。
xmlwriter
がインストールされてないPHPの拡張機能
xmlwriter
が入っていないため、PhpSpreadsheetなどのライブラリが動きませんでした。1
これに関してはレンタルサーバー側が対応してくれるまでどうしょうもないので、xmlwriter
機能を使うライブラリを仕様する場合は注意が必要かなとおわり
- 何回も行っておきますが情報の鮮度的に19年9月ごろまでの話で今現在上記の通りでない可能性も無きにしです。
- ちなみに自分が携わったプロジェクトに関して言えば8割くらい、業務システムはほぼ100%レンサバ指定でした
- ちなみにちなみに明日は前職の後輩@namizatopが記事書くようですよ(お
参考
- さくらのレンタルサーバーでcomposerめも - Qiita
- さくらのレンタルサーバにComposerをインストールする方法 – かきくけ子のブログ
- さくらのレンタルサーバのシェルをbashに変更する方法 – かきくけ子のブログ
2019年9月頃の話ですので現在は異なるかもしれません ↩
- 投稿日:2019-12-23T10:40:17+09:00
PHPStanで素のPHPをテンプレートとして使うとき、htmlspecialcharsをチェックする
前にテンプレートエンジンでも型チェックしたいということを書いたが、まだ一点不満があった。
そもそもテンプレートエンジンを使う唯一にして最大のメリットは、
htmlspecialchars
を漏れなく実行することにある。
PHP自体がテンプレートエンジンと言われていても、別途テンプレートエンジンのライブラリを使うのは<?= $message ?>というような出力を書いてしまってXSSが発生するということを防ぐのが目的である。
他の機能は、例えばBladeなら@if ($flg) <span>OK</span> @endif @foreach ($data as $key => $row) <div>{{ $row->id }}: {{ $row->name }}</div> @endforeach <?php if ($flg): ?> <span>OK</span> <?php endif; ?> <?php foreach ($data as $key => $row): ?> <div><?= $row->id ?>: <?= $row->name ?></div> <?php ehdforeach; ?>素のPHPを使ってもあまり変わらない。
違いは、<?= $row->name ?>
の箇所が少々危険である、ということぐらいだ。
おそらく<?= htmlspecialchars($row->name) ?>
と書きたかったはずだ。つまり、素のPHPをテンプレートエンジンとして使ってPHPStanで型チェックをするためには、あと一手
htmlspecialchars
をチェックする機能も必要になってくる。幸いPHPStanは拡張機能というプラグイン的な仕組みがあるので、ちょっとしたエラーチェックのルールを独自に追加できる。
なので作った。
https://github.com/nishimura/phpstan-echo-html-rulesrc/ProductDto.php<?php namespace App; class ProductDto { /** @var int */ public $product_id; /** @var string */ public $name; /** @var ?string */ public $description; }このようなデータがあるとき、表示用のHTMLを含むPHPテンプレートクラスは
src/ProductHtml.php<?php namespace App; class ProductHtml { public function view(ProductDto $product): void { ?> <div> <div> <?= $product->product_id ?> </div> <div> <?= $product->name ?> </div> <div> <?= $product->description ?> </div> </div> <?php } }こんな感じになるだろう。
phpstan-echo-html-rule
を使えば3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% ------ ---------------------------------------------------- Line ProductHtml.php ------ ---------------------------------------------------- 16 Parameter #1 (string) is not safehtml-string. 19 Parameter #1 (string|null) is not safehtml-string. ------ ---------------------------------------------------- [ERROR] Found 2 errors
htmlspecialchars
を使わずに出力している箇所のエラーを報告してくれるようにした。
独自の仮想的な型safehtml-string
を導入したので、htmlspecialchars
はsafehtml-string
を返す必要がある。functions.php<?php /** * @param int|string|null $input * @return safehtml-string */ function h($input) { return htmlspecialchars((string)$input); } /** * @param int|string|null $input * @return safehtml-string */ function raw($input) { return (string)$input; }このようなユーティリティ関数を用意する。
そしてエラーを修正する。
src/ProductHtml.php<?php namespace App; class ProductHtml { public function view(ProductDto $product): void { ?> <div> <div> <?= $product->product_id ?> </div> <div> <?= h($product->name) ?> </div> <div> <?= h($product->description) ?> </div> </div> <?php } }これでテンプレートエンジンを使わなくても
htmlspecialchars
なしの出力を網羅的にチェックできるようになった。
- 投稿日:2019-12-23T10:40:16+09:00
[WordPress]PHPCodeSniffer(phpcs)でWPコーディング規約をチェック&自動整形できるようにする
ちゃんとしようと思い、WordPressコーディング規約をちゃんと学び始めました。
でも自分で間違いを探し出すのはとっても大変だとうなだれてたら、構文エラーをチェックでき、自動整形もしてくれる方法を知ったので忘れないうちにまとめておきます。
野性味のあるまなちゃんも貼っておきます。
かわいい。WordPressコーディング規約(WordPress Coding Standard)とは
WordPressには、コーディング規約がある。
コーディング規約はCSS、HTML、JavaScript、PHPと言語ごとに存在する。
- CSS コーディング規約 - WordPress Codex 日本語版
- HTML コーディング規約 - WordPress Codex 日本語版
- JavaScript コーディング規約 - WordPress Codex 日本語版
- PHP コーディング規約 - WordPress Codex 日本語版
コーディング規約を理解するのに、よく参考にさせていただいてるサイト
WordPress コーディングスタンダードの正式な書き方をまとめてみる – ミルログ準備
コマンドからもろもろインストールして、チェック&自動整形の準備をしていく。
★
PHP CodeSniffer(phpcs)
をインストール1. まずは
composer
をインストール
Homebrew
を使ってcomposer
をインストールする。(Homebrew
が入ってて良かった)
php
のインストールも必要なので入ってなかったら、brew install php70
でインストール。$ brew install composer2.
composer
でPHP CodeSniffer(phpcs)
をインストール$ composer global require "squizlabs/php_codesniffer=*"インストールされたことを確認する
$ .composer/vendor/bin/phpcs --version下記が表示されればインストールOK!
$ .composer/vendor/bin/phpcs --version PHP_CodeSniffer version 3.5.3 (stable) by Squiz (http://www.squiz.net)3.
phpcs
のみでコマンド実行出来るように、パスを登録$ echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> ~/.bash_profile $ source ~/.bash_profile※パスが登録されたかバージョンを表示させるコマンドで確認
$ phpcs --version下記が表示されればパスの登録OK!
$ phpcs --version PHP_CodeSniffer version 3.5.3 (stable) by Squiz (http://www.squiz.net)★WordPressコーディング規約をインストールし、設定
PHP CodeSniffer
がインストールできたら、使用する規約であるWordPressコーディング規約(WordPress Coding Standard)
をインストール。
デフォルトでは PEAR, PHPCS, PSR1, PSR2, Squiz, Zend がインストールされてる。1.
Composer
でコーディング規約をインストールする。$ composer global require wp-coding-standards/wpcs2.
PHP CodeSniffer(phpcs)
にコーディング規約を設定$ phpcs --config-set installed_paths ~/.composer/vendor/squizlabs/php_codesniffer/Standards/WordPressインストールされたことを確認
$ phpcs -i下記が表示されたら、インストールOK!
$ phpcs -i The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1, PSR12, WordPress, WordPress-Extra, WordPress-Docs and WordPress-Core★普段PHPはWordPressでしか使わないのならデフォルトのコーディング規約として設定しておく
$ phpcs --config-set default_standard WordPress実行
準備が整ったので、コマンドラインで実行する。
★エラーチェックの実行(phpcs)
(例)$ phpcs wp-content/themes/theme-name/page.php※↑パスとファイル名を指定
エラーがあるとこんな感じで表示される
(例)$ phpcs wp-content/themes/theme-name/page.php FILE: ~{省略}~/wp-content/themes/theme-name/page.php ------------------------------------------------------------------------------------------------------ FOUND 1 ERROR AND 1 WARNING AFFECTING 2 LINES ------------------------------------------------------------------------------------------------------ 11 | WARNING | [ ] Found precision alignment of 3 spaces. 14 | ERROR | [x] Tabs must be used to indent lines; spaces are not allowed ------------------------------------------------------------------------------------------------------ PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY ------------------------------------------------------------------------------------------------------ Time: 120ms; Memory: 8MB※~{省略}~には絶対パスが出力される
WARNINGとERRORが一つずつでてることが確認できる。例のエラーは2つのエラーだが、たくさんエラーが出てしまっては一つずつ読んで治すのは骨が折れる。
PHP Code Beautifier and Fixer(phpcbf)
も同時にインストールされてるので、これを実行すれば自動整形ができる。★自動整形の実行(phpcbf)
(例)$ phpcbf wp-content/themes/theme-name/page.php※↑パスとファイル名を指定
自動整形され、こんな感じで表示される
(例)$ phpcbf wp-content/themes/theme-name/page.php PHPCBF RESULT SUMMARY --------------------------------------------------------------------------------------------------------------------- FILE FIXED REMAINING --------------------------------------------------------------------------------------------------------------------- ~{省略}~/wp-content/themes/theme-name/page.php 1 1 --------------------------------------------------------------------------------------------------------------------- A TOTAL OF 1 ERROR WERE FIXED IN 1 FILE --------------------------------------------------------------------------------------------------------------------- Time: 239ms; Memory: 8MB※~{省略}~には絶対パスが出力される
WARNINGで出てた部分は整形されてない、、、。自動整形だけでは修正されない部分もあるので、エラーを見ながら修正していく。
.
を指定すると、ディレクトリ内すべてにチェック(または自動整形)される(例)$ phpcs wp-content/themes/theme-name/.(例)$ phpcbf wp-content/themes/theme-name/.まとめ
実は、PHPの
PSR2
とWordPressコーディング規約
のルール同士が喧嘩しててうまく行かずはまりました。
でもデフォルトにWordPressコーディング規約
を設定することでうまく行ったので、大事であります。$ phpcs --config-set default_standard WordPress参考サイト
PHP CodeSniffer を使ってWPコーディングスタンダードのエラーをチェック&自動修正しよう [3.x 対応] – ミルログ
macOSのVisual Studio CodeでPHP CodeSniffer & WordPressコーディング規約によるコードチェック環境を構築 | taxaboxo.com
- 投稿日:2019-12-23T07:50:36+09:00
モバイル環境でNetwork Errorでハマった。「EC2にDocker Caddy Laravel, S3にVuejsの構成」
指摘などウェルカムです。
クロスオリジン(CORS)に関連するエラーなんだと思うけどPCでは動くが、携帯 IOS Iphone7(古い)からのブラウザ(最新)ではsafariもchromeも動かないって現象で結構ハマった。環境
大体の構成
route53から分岐
-> CloudFront+S3にvuejs
-> ALBからEC2(Ubuntu)にDocker Caddy Laravel解決策
サーバー側のクロスオリジンの設定をちゃんと設定する。
Access-Control-Allow-Origin
Access-Control-Allow-Headers
をざっくり設定して * としていた。
これが原因だった。
ちゃんとフロントs3側のホスト名を指定したら動いた。
この記事で必須と書いてあるので、ん?と思って設定したら動いた。:OK.php <?php namespace App\Http\Middleware; use Closure; class Cors { public function handle($request, Closure $next) { return $next($request) //ちゃんとホスティングしてるs3のドメインを指定 ->header(‘Access-Control-Allow-Origin’, ‘https://hoge.s3.com’) ->header(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’) ->header(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, X-Token-Auth, Authorization’); } }駄目.php<?php namespace App\Http\Middleware; use Closure; class Cors { public function handle($request, Closure $next) { return $next($request) ->header(‘Access-Control-Allow-Origin’, ‘*’) ->header(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’) ->header(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, X-Token-Auth, Authorization’); } }https://whatsupguys.net/programming-learning-135/
調べた履歴
Laravelのルーティングについて結構大事だと思う。
axiosでget, post以外にoptionも使うのでルーティング注意。Route::match(['options', 'patch']'/{test_id}', 'TestController@update'); Route::match(['options', 'delete'], '/{test_id}', 'TestController@destroy');CORSを許可したLaravel製APIサーバーでput, patch, deleteが出来なくて泣いてたけど、ようやく解決出来た話
CSRFが問題か?
X-Requested-Withヘッダか?Laravel/Vue SPAs: How to send AJAX requests and not run into CSRF token mismatch exceptions
https://medium.com/@serhii.matrunchyk/laravel-vue-spas-how-to-send-ajax-requests-and-not-run-into-csrf-tokens-mismatch-exceptions-da3b71b287ab
https://www.techalyst.com/posts/vuejs-axios-laravel-x-csrf-token-x-xsrf-token-csrf-protectionaxiosが悪いのか?
https://qiita.com/terrierscript/items/ccb56b6fc05aa7821c42crossのエラーぽいが。
https://stackoverflow.com/questions/50873764/cross-origin-read-blocking-corb
https://stackoverflow.com/questions/38749605/cors-access-control-allow-origin-on-laravel
https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-get-a-no-access-control-allow-origin-header-is-pr
https://github.com/laravel/framework/issues/13643
https://medium.com/@petehouston/allow-cors-in-laravel-2b574c51d0c1サーバの.htaccessが悪いのか?
https://forum.laragon.org/topic/1435/access-control-allow-origin-is-already-set/6モバイルではそもそも動かないのか?
Axios doesn't work with Android (emulator) raising a Network Error
https://github.com/axios/axios/issues/973
- 投稿日:2019-12-23T04:46:12+09:00
Laravel6系 に Vuetify を入れてみる
こんにばんわ! @ktoshi です。
今回は私が困ったときに縋りつく Laravel についてお話します。
ちなみに私はインフラエンジニアです。メインは。目的
Laravel6 に Vuetify を導入したい。
Laravel6 より Vue.js などが標準ライブラリから外れたため、Laravel5 以前の記事ではそのまま導入ができなくなりました。
毎度導入しているときに複数の記事を見ながら、導入しているので備忘録もかねて。Vuetify とは
公式HP
Vue.js のコンポーネント集です。
ボタンやテーブルなどを描画する際のコンポーネントがあつまっているので、
モダンなデザインを容易に作ることができます。環境
OS: Windows 10 Pro
PHP: 7.3.10Composer インストール
Laravel で使用するパッケージ管理に利用します。
みなさんご存じですよね。多くは語りません。
Composerインストール手順(Windows) を参考されたし。node.js インストール
node.js 自体をサーバとして利用も可能ですが、Laravel では主に Vue.js の
ビルドを目的に利用します。
みなさんご存じですよね。多くは語りません。
Node.js / npmをインストールする(for Windows) を参考されたし。
私の環境ではバージョンは下記でした。node --version v12.13.0 npm --version 6.12.0Laravel インストール
みなさんご存じですよね。多くは語りません。
composer create-project laravel/laravel --prefer-dist <PROJECT NAME>これでカレントディレクトリ以下に PROJECT_NAME のフォルダが作成され、
その配下に Laravel が導入された状態となっています。Vue.js のインストール
先でも述べたように Laravel5 以前であれば、この状態で
npm install
をしてやると
Vue.js が導入できましたが、 Laravel6 以降ではひと手間必要です。
ひと手間が料理をおいしくすると同じくひと手間が Laravel をおいしくします。(知りません# プロジェクトフォルダへ移動 cd <PROJECT NAME> # 必要なライブラリをインストール composer require laravel/ui # 私は Vue を使うねん!と宣言 php artisan ui vue # おら! npm installこれで Vue.js の導入が完了です。
Laravel5 以前でnpm install
を叩いた状態と同じですね。Vuetify インストール
Vuetify は npm(Node.js のパッケージ管理ツール)を用いてインストールします。
(いや、そのコマンドさっき使ってたのに今更説明かい。)# Vuetify の最新パッケージのインストール npm install vuetifyインストールが終われば、Laravel 側で Vuetify を利用するように設定します。
resoureces/js/app.js/** * First we will load all of this project's JavaScript dependencies which * includes Vue and other libraries. It is a great starting point when * building robust, powerful web applications using Vue and Laravel. */ require('./bootstrap'); window.Vue = require('vue'); import Vuetify from 'vuetify'; import 'vuetify/dist/vuetify.min.css'; Vue.use(Vuetify); /** * The following block of code may be used to automatically register your * Vue components. It will recursively scan this directory for the Vue * components and automatically register them with their "basename". * * Eg. ./components/ExampleComponent.vue -> <example-component></example-component> */ // const files = require.context('./', true, /\.vue$/i) // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default)) Vue.component('example-component', require('./components/ExampleComponent.vue').default); /** * Next, we will create a fresh Vue application instance and attach it to * the page. Then, you may begin adding components to this application * or customize the JavaScript scaffolding to fit your unique needs. */ const app = new Vue({ el: '#app', vuetify: new Vuetify(), });これで Laravel にてVuetify を利用できる状態となりました。
実践
では、実際にVuetify を使ったページを作ってみましょう。
元々用意されているサンプルのファイルを書き換えてみます。resources\js\components\ExampleComponent.vue<template> <v-app> <v-container> <v-row> <v-col> <v-card class="mx-auto"> <v-card-text> <p class="text--primary"> Hello Vuetify World!! </p> </v-card-text> <v-divider></v-divider> <v-card-actions> <v-btn>やったね!!</v-btn> </v-card-actions> </v-card> </v-col> </v-row> </v-container> </v-app> </template>resources\views\welcome.blade.php<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!-- Styles --> <link rel="stylesheet" href="{{ mix('css/app.css') }}"> </head> <body> <div id="app"> <v-app> <!-- これがさっき修正したファイル --> <example-component></example-component> </v-app> </div> <!-- Scripts --> <script src="{{ mix('js/app.js') }}"></script> </body> </html>次に Vue.js のビルドと Laravel を起動させます。
なお、各コマンドともに実行状態が続くので二つのプロンプトで作業をしてください。# Laravel の起動 php artisan serve Laravel development server started: http://127.0.0.1:8000 # これが出ればOK# ビルドコマンドを発行。watch にしておくと変更を検知して勝手にビルドしてくれるので楽。 npm run watch DONE Compiled successfully in XXXms # これが出ればOKそれぞれが起動すれば
http://localhost:8000/
へ接続してみましょう。
下記のようなページが表示されていればOKです。
まとめ
Laravel6 から標準でなくなった Vue.js のインストールまで行ってしまえば、
後は Laravel5 と同様の方法で Vuetify を利用することが可能です。私は今まで element-ui を主に使っていましたが、今回は Vuetify を利用する、という記事を書いてみました。
なんで変えたかって?飽きたからです。
ただ、実際に Vuetify を使ってみて思ったのはデザインなどは非常に好みでした。
テーブルに関しても element-ui より柔軟でよかったです。
ただ、timepicker のデザインが不満だったのと element-ui の datetimepicker がマジ神だなと感じました。それでは皆様、よい Vuetify ライブをお送りください。
- 投稿日:2019-12-23T01:06:04+09:00
CakePHP3をPHP7.2で動かすときは気をつけろ
PHP7.2は曲者!?
以下の記事でも書いたが、PHP7.2でCakePHP3を動かそうとすると思わぬ事態に遭遇する。
https://qiita.com/21century_girl_/items/5be2606b3bfa98514952元はといえば、サーバー移行の依頼を受けたため、「どうせならPHPのバージョンを上げるか」と軽い気持ちで、PHP7.1→PHP7.2にバージョンアップしたのです。
phpコマンドが動かん…
php -vいつものこれ。
phpのバージョンを確認するコマンドですが、これがcommand not foundと出て動かないわけですな。
php72 -vこれで動きます。
一応、簡易的な対応としては以下の記事に載せているのでここでは割愛
https://qiita.com/21century_girl_/items/5be2606b3bfa98514952cronに設定したshellが動かん..
/etc/cron.dに以下のように設定したのです。
* * * * * root /var/www/html/***/bin/cake test通常のcron設定ですね。
上記の場合は、cakephpのshell内のTestShell.phpを動かすといったイメージです。しかし以下のエラーが。。
Failed to find a CLI version of PHP; falling back to system standard php executable /var/www/html/service/bin/cake: line 72: exec: php: not foundどうやら該当のファイルの72行目を見ると、phpコマンドを叩いてる模様…
for TESTEXEC in php php-cli /usr/local/bin/phpただし、phpコマンドが効かない状態なので、このエラーが出ているわけです。
ではどうするか?
cronファイルに環境変数を設定
以下のように設定
PATH=/usr/local/bin:/sbin:/bin:/usr/bin:/usr/sbin/sendmail:/opt/remi/php72/root/usr/bin:/opt/remi/php72/root/usr/sbin * * * * * root /var/www/html/***/bin/cake testこれでphpコマンドも利用可能になり、cakephpのshellも実行されました。
- 投稿日:2019-12-23T00:51:06+09:00
メール認証(アクティベーション)機能を自前で実装【Laravel】
この記事は、認証認可技術 Advent Calendar 2019 の23日目の記事です。
1. はじめに
Laravelって便利ですよね。
Laravel5.7からは、
make:auth
コマンドやMustVerifyEmail
インターフェースを使えばすぐにメール認証機能の実装もできるようになりました。(Laravel6.0からはmake:auth
廃止されましたが)ただ便利な反面、途中から機能追加したり、変更頻度が多いことを見越して自前で実装して柔軟に対応できるようにしておきたいことがあります。
こういったことがあって自前で実装したのでその時の備忘録です。
(APIサーバをつくるときの話で、LaravelはフルスタックフレームワークなのでAPIサーバのみの利用はあまり無かった)少し前の実装なのでうる覚えな部分はありますがご容赦ください。
2. やりたいこと
タイトル通り、メール認証機能の実装です。
私が思っているメール認証機能の定義と流れは以下の通りです。
2.1. メール認証機能の定義
Webサービスでよくある新規登録時にほぼ間違いなくするメールアドレスの有効化のことです。
(メール認証==メール有効化==メールアクティベーション
だと思っています。。。色んな言い方をしてすみません。)この機能がないと偽りのメールアドレスを使って登録することができてしまうのでよく実装されています。(この他にもSMS認証とか)
要するにWebサービスを開発するときの必須機能の一つです。2.2. メール認証機能の流れ
- ユーザがサーバにメールアドレスを入力して送信
- サーバがユーザに入力されたメールアドレスに認証メールを送信
- ユーザが認証メール内のURLにアクセス
- サーバがURLの正誤判定
- 正しい場合、サーバがデータベースにメールアドレスを登録
一般的な流れはこんな感じでしょうか。
誰でも一度はユーザの立場でやったことがある流れだと思います。3. 実装方針
認証コードの作成・確認
認証コードの作成は、メールアドレスとサーバで定義しておいた秘密鍵を用いてハッシュ化をして行います。
確認は、
ユーザがアクセスしたURL内の認証コード==サーバ側に仮保存している認証コード
で行います。認証コードとメールアドレスの紐付け
考える必要があるのは紐付け方法です。
様々な紐付け方法がありますが、今回はデータベースにメール認証用のテーブルを作って、メールアドレスと認証コードをセットで保存するという方法をとります。
メールアドレスの認証が確認できた時点で、このテーブルのレコードは消していきます。おまけ: 様々な紐付け方法
- アクセス先のページでメールアドレスを再入力
- ユーザが手間(=UX悪い)なので却下
- URLにクエリとしてメールアドレスを付与
- ださいので却下、セキュリティ的にも心配(?)
- メールアドレスのセッション保存
- 他端末で認証できないので却下
- 認証ファイルの作成
- 個人的に実装が手間だったので迷った末に却下
- データベース使わなくて済むが小規模なサービスの場合だと誤差
4. 開発環境
- PHP7.3
- Laravel6.0(5.8でも動作確認済)
- MySQL8.0
5. 実装
5.1. テーブル作成(マイグレーション&モデル)
最初に、ユーザ用のテーブルとは別に、メール認証用のテーブルをつくっておきます。
MigrationとModelをつくります。$ php artisan make:model MailVerification -mMigration
mail_authentication
は認証コードを格納するカラムで、
database/migrations/2019_12_23_000000_create_mail_verifications_table.php<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateMailVerificationsTable extends Migration { public function up() { Schema::create('mail_verifications', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('mail_authentication'); $table->string('mail')->unique(); $table->timestamps(); }); } // 略 }Model
app/Models/MailVerification.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; class MailVerification extends Model { protected $table = 'mail_verifications'; protected $guarded = array('id'); public $timestamps = true; protected $fillable =[ 'mail_authentication' , 'mail' ]; }5.2. コントローラ作成
次に、コントローラをつくります。
Controller
store
メソッドで認証コードとメールアドレスを仮保存しておいて、ユーザに認証メールを送ります。
認証メールのURLにアクセスしたらverify
メソッドで確認して、仮保存しておいたレコードを削除し、認証完了メールを送ります。
createActivationCode
メソッドで、認証コードを作成しています。
ACTIVATE_SALT
が秘密鍵です。app/Http/Controllers/Api/MailVerificationsController.php<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; use App\Models\MailVerification; use App\Models\User; use App\Mail\MailVerification as MailVerificationMail; use App\Mail\MailVerificationConfimComplete as MailVerificationConfimCompleteMail; use App\Http\Controllers\Controller; define('ACTIVATE_SALT', '[秘密鍵]'); class MailVerificationsController extends Controller { public function store($mail) { $mail_verification = new MailVerification(); $mail_verification->mail_authentication = self::createActivationCode($mail); $mail_verification->mail = $mail; $mail_verification->save(); self::sendMailVerification($mail_verification); } public function verify($active_code) { $mail_verification = self::getMailInfoFromActiveCode($active_code); $mail = $mail_verification[0]->mail; $user = new User(); $user->isVerified($mail); self::destroy($mail_verification[0]->id); self::sendMailVerificationComplete($mail); } public function destroy($id) { $mail_verification = MailVerification::find($id); $mail_verification->delete(); } private function createActivationCode($mail) { return hash_hmac('sha256', $mail, ACTIVATE_SALT); } private function sendMailVerification($mail_verification) { Mail::to($mail_verification->mail) ->send(new MailVerificationMail($mail_verification->mail_authentication)); } private function sendMailVerificationComplete($mail) { Mail::to($mail) ->send(new MailVerificationConfimCompleteMail()); } private function getMailInfoFromActiveCode($active_code) { return MailVerification::where('mail_authentication', $active_code)->get(); } }念のため、Userコントローラも。
store
メソッドでユーザ登録処理をしています。
app()->make()
で別コントローラを呼ぶという力技・・・。app/Http/Controllers/Api/UsersController.php<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use App\Models\User; use App\Http\Controllers\Controller; class UsersController extends Controller { public function store(Request $request) { $user = new User(); $user->name = $request->input('name'); $user->mail = $request->input('mail'); $user->password = bcrypt($request->input('password')); $user->save(); self::callMailVerificationStore($user); return response([], 201); } private function callMailVerificationStore($user) { $mail_varification = app()->make('App\Http\Controllers\Api\MailVerificationsController'); $mail_varification->store($user->mail); } }5.3. ルーティング記述
この当たりで関係がある部分のルーティングを書いておきます。
routes/api.php<?php use Illuminate\Http\Request; Route::group(["middleware" => "api"], function () { Route::post('/user', 'Api\UsersController@store'); Route::get('/verify/{active_code}', 'Api\MailVerificationsController@verify'); });5.4. メール
必要ないかもしれませんがメモ程度に。
app/Mail/MailVerification.php<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; define('MAIL_VERIFICATION_SUBJECT', '[メールタイトル]'); class MailVerification extends Mailable { use Queueable, SerializesModels; protected $mail_verification; public function __construct($_mail_verification) { $this->mail_verification = $_mail_verification; } public function build() { $auth_url = config('const.BASE_URL') . '/verify/' . $this->mail_verification; return $this->from(config('mail.from.address')) ->subject(MAIL_VERIFICATION_SUBJECT) ->view('mails.verification', compact('auth_url')); } }簡単にですがBladeの方も。
resources/views/mails/verification.blade.php@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">メールアドレス認証</div> <div class="card-body"> <a href='{{$auth_url}}'>こちらのリンク</a>をクリックして、メールを認証してください。 </div> </div> </div> </div> </div> @endsection6. おわりに
以上、Laravelでメール認証機能を自前で実装してみた備忘録でした。
ご閲覧ありがとうございました!
質問やアドバイス等ありましたらコメントしてください。