- 投稿日:2019-08-22T23:27:56+09:00
[Laravel - デバッグ]自分で書いたプログラムをただ(var_dump()、var_export()、print_r())、dd()するよりもわかりやすくデバッグする(dump server)
前置き
今回は、(var_dump()、var_export()、print_r())は表示形式が少し異なるだけなので、var_export()とdd()を主に使います。
準備
テスト用にController,bladeを作成する。
Controller
SampleController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class SampleController extends Controller { public function sample(Request $request) { return view('sample'); } }blade
中身空のsample.blade.phpを作成する。
routes/web.php
Route::get('/sample', 'SampleController@sample')->name('sample');準備が完了しました。これで/sampleへアクセスすると、真っ白な画面が表示されます。
普通にvar_dump()、dd()を使ってみる。
var_dump()
SampleControllerの中身を変更する
public function sample(Request $request) { $string = 'あいうえお'; var_dump($string); $int = 1; var_dump($int); $array = ['name' => '太郎']; var_dump($array); $time = new Carbon(); var_dump($time); return view('sample'); }/sampleへアクセスすると、変数の中身の情報が表示されています。
dd()
SampleControllerの中身を変更する
public function sample(Request $request) { $string = 'あいうえお'; var_dump($string); $int = 1; var_dump($int); $array = ['name' => '太郎']; dd($array); $time = new Carbon(); var_dump($time); return view('sample'); }/sampleへアクセスすると、変数の中身の情報が表示されています。
dd()は実行された直後に処理が終了します。変数の中身が、複雑な配列な際や、そこまでの処理が正常に動作しているかの確認時に重宝します。(本題)Laravelでは、もっといい方法がある。
Laravelには、デバッグ用にdump serverというものが用意されている。こちらを使う。
コマンドをたたく。コマンドroot@75b98e12b61d:/var/www# php artisan dump-server Laravel Var Dump Server ======================= [OK] Server listening on tcp://127.0.0.1:9912 // Quit the server with CONTROL-C.dump-serverが起動できました。dump-serverは、出力内容をサーバー側で受け取り、表示することが可能になります。
このままの状態で、先ほどのdd()入りのコードを実行してみます。/sampleへアクセスします。
GET http://192.168.99.100/sample -------------------------------- ------------ ------------------------------------------- date Thu, 22 Aug 2019 14:14:59 +0000 controller "SampleController" source SampleController.php on line 19 file app/Http/Controllers/SampleController.php ------------ ------------------------------------------- array:1 [ "name" => "太郎" ]コマンドプロンプトでddの内容が表示されます。それ以外にも、日時やコントローラーの情報などが記述されています。ddとvar_dumpをdump()メソッドを使うように変えます。
public function sample(Request $request) { $string = 'あいうえお'; dump($string); $int = 1; dump($int); $array = ['name' => '太郎']; dump($array); $time = new Carbon(); dump($time); return view('sample'); }/sampleへアクセスします。
GET http://192.168.99.100/sample -------------------------------- ------------ ------------------------------------------- date Thu, 22 Aug 2019 14:18:14 +0000 controller "SampleController" source SampleController.php on line 13 file app/Http/Controllers/SampleController.php ------------ ------------------------------------------- "あいうえお" ------------ ------------------------------------------- date Thu, 22 Aug 2019 14:18:14 +0000 controller "SampleController" source SampleController.php on line 16 file app/Http/Controllers/SampleController.php ------------ ------------------------------------------- 1 ------------ ------------------------------------------- date Thu, 22 Aug 2019 14:18:14 +0000 controller "SampleController" source SampleController.php on line 19 file app/Http/Controllers/SampleController.php ------------ ------------------------------------------- array:1 [ "name" => "太郎" ] ------------ ------------------------------------------- date Thu, 22 Aug 2019 14:18:14 +0000 controller "SampleController" source SampleController.php on line 22 file app/Http/Controllers/SampleController.php ------------ ------------------------------------------- Carbon\Carbon @1566483494^ {#446 date: 2019-08-22 14:18:14.934425 UTC (+00:00) }ddを使うと、そこまでの内容を表示し処理を終了してくれます。
まとめ
var_dump()を使うと、viewのほうで場合によって、エラーが出ることがあったりしたり、見にくかったりするけど、dump-serverを使うと、きれいにわかりやすく簡単に変数の値を見ることができた。
- 投稿日:2019-08-22T22:49:15+09:00
Laravelでコマンド入れる時ってどこで動かすの?
Laravelでコマンドを使っていろいろなことをするときに、「コマンドラインで」って言われることが多いのだけれども、具体的にWindowsのコマンドプロンプトなの?sshでつないでlinux上で動かすの?ってちょっとわからない時が多すぎる気がする。
いつかまた泣きそうになる気がするので、泣く前に見られる情報を書いておく。
尚、環境は以下の通り。
・ホストOS:Windows10
・開発環境:Homestead→Vagrant上でLinuxが起動
DBはMySQL関係ないけど、VSCodeが使いやすくてびっくりだよ。
簡単に言っておくと
vagrantのコマンド→Windowsのコマンドプロンプトで実行
プロジェクトに対して実行するコマンド→linuxのコンソールで実行各論
Vagrantの起動(Vagrant up)
さすがにこれはWindowsのコマンドプロンプトから起動ってわかるね。
Homesteadをインストールしたフォルダーに移動してからコマンド実行してください。C:{Homesteadをインストールしたフォルダ}>vagrant upVagrantの終了(Vagrant halt)
当然起動と同じ、Windowsのコマンドプロンプトです。Homesteadをインストールしたフォルダに移動してコマンド実行してください。
C:{Homesteadをインストールしたフォルダ}>vagrant haltLaravelプロジェクトの作成(composer)
これはVagrant上のlinuxから実行します。
Vagrant上のLinuxにアクセスするには、Vagrant sshでVagrant上のlinuxのコンソールを開きます。
Vagrant sshはWindows10のコマンドプロンプトから入れます。C:{Homesteadをインストールしたフォルダ}>vagrant sshそうするとあら不思議、今までWindows10のコマンドプロンプトだった画面がlinuxのコンソール画面に早変わり!
linux上でコマンドを入力する場合は、vagrant sshでlinuxに接続してからコマンド実行する。
尚、laravelプロジェクトを作成するときはlinux上でプロジェクトを作成するディレクトリに移動してからコマンドを実行する。
Homesteadのデフォルトの開発ディレクトリはcodeなので、通常はcodeディレクトリに移動してからプロジェクトを作成する。※note
Homesteadでは、VagrantでホストOS(ここではWindows10)とゲストOS(ここではlinux Ubuntu)で共有する共有フォルダーが設定される。
[設定される共有フォルダー]
home_vagrabt_code C:¥{ユーザーフォルダ}¥code
vagrant C:¥{ユーザーフォルダ}¥Homestead
これらのフォルダーはホストOSからもゲストOSからも参照・更新することができる。【コマンド例】
vagrant@homestead:~$ cd code vagrant@homestead:~code$ composer create-project laraavel/laravel testProjectartisanコマンド
linuxのコンソール画面で実行する。
プロジェクトのフォルダに移動してから実行する。実行した結果は移動したプロジェクト内に反映される。【コマンド例】
vagrant@homestead:~/code/myProject$ php artisan make:test testCodeMySQLを立ち上げる
linuxコンソールで実行する。
MySQLコマンドはどのディレクトリにいても実行できます。【コマンド例:homesteadのhomeディレクトリで実行】
vagrant@homestead:~$ mysql -u homestead -pデフォルトの設定値では、ユーザーは「homestead」、パスワードは「secret」です。
変更する場合は、プロジェクト内の.envファイル内の「DB_USERNAME」、「DB_PASSWORD」の設定値を変更してみ。
- 投稿日:2019-08-22T19:55:42+09:00
docker-composeで、一つのWebサーバーコンテナ上に複数のLaravelアプリを立ち上げる
同じDBを参照する、2つのLaravelアプリをdocker-composeで立ち上げる方法について書いていきます。一つのWebサーバー上で2つのLaravelアプリが動いていて、それぞれが同じDBを見ている、といった構成です。
ググったらいくらでも出てくるかな?と思ったら、Laradocを使った方法しかなかったので意外でした。
コンテナの構成
コンテナ関連のディレクトリ構成は、以下の記事を参考にしています。今回やることは、以下の記事のゴールの状態から、立ち上げるLaravelアプリを1つ追加する、みたいなイメージです。
docker-compose.ymlを変更
webサーバーにnginxを使っている場合、docker-compose.ymlは以下のような記述になっているかと思います。
docker-compose.ymlversion: "3" services: app: context: ./docker/php // アプリコンテナの記述 web: image: nginx:1.17-alpine depends_on: app // portsなどの記述別のLaravelアプリを立ち上げる場合は、起動するアプリコンテナを一つ増やします。記述例としてはこんな感じ。
docker-compose.ymlversion: "3" services: app: context: ./docker/php // アプリコンテナの記述 other: context: ./docker/php // アプリコンテナの記述 web: image: nginx:1.17-alpine depends_on: app other ports: 3500:80 3501:79 volumes: - ./app:/work/app - ./other:/work/other - ./logs:/var/log/nginx - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.confこれにより、docker-compose upを実行すると、otherコンテナが立ち上がります。参照するDockerfileは、appと同じものをにするか、新しく定義するかはお好みで。
また、nginxコンテナのdepends_onにotherコンテナを指定し、加えてportsの設定を一つ増やします。これにより、「localhost:3500」でサーバーコンテナの80番ポートに、「localhost:3501」で79番ポートにアクセスできるようになります。
あと、volumesにも変更を加えています。docker-compose.ymlがあるディレクトリの、app/配下がwebサーバーコンテナの/work/appに、other/配下が/work/otherに配置されるようにしています。
default.confの変更
次に、nginxの設定ファイルを変更しています。変更前はこんな感じになっているはず。
default.confserver { listen 80; root /work/app/public; index index.php; charset utf-8; location / { root /work/app/public; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /work/app/public/index.php; fastcgi_param PATH_INFO $fastcgi_path_info; } }80番ポートにアクセスが来るとnginxがそれに対応する、みたいな標準的な設定です。80番ポートはapp/に配置されているLaravelアプリに対応するようになっています。
今回、otherコンテナに配置するLaravelアプリは79番ポートで受け付けられるようにするので、以下のように記述を追加します。
default.confserver { // 80番ポートの設定 } server { listen 79; root /work/other/public; index index.php; charset utf-8; location / { root /work/other/public; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass other:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /work/other/public/index.php; fastcgi_param PATH_INFO $fastcgi_path_info; } }listenを79番に、rootを/work/other/publicに変更しています。docker-compose.ymlのvolumesに対応するようにrootを設定しましょう。(publicはLaravelの公開ディレクトリです)。
webサーバーコンテナの中が、/work/other/(Laravelのディレクトリ群)のような構成になることを想定した記述ですね。
また、「location ~ .php」の中の記述も少し変更しています。
まず、「fastcgi_pass」がapp:9000から、other:9000になっています。app、otherはアプリコンテナのことで、PHP-FPMとの通信ポートをそれぞれ指定しています。
あと、「fastcgi_param SCRIPT_FILENAME」以下の記述も変更しており、Laravelアプリのpublicフォルダ内のindex.phpを参照するようにしています。ここがズレているとphpファイルが正しく読み込まれず、「File not Found」と表示されて悲しい気持ちになるので忘れずに変更しておいてください。
今回は直接パスを記述していますが、「\$document_root/index.php」みたいな書き方もあります。($document_rootにはrootで指定したパスが入る)
これで、app/配下、other配下にLaravelをインストールし、.envやディレクトリの権限変更を正しく行えば、localhost:10080、localhost:10079にアクセスするとそれぞれLaravelのWelcomeページが表示されるはずです。
今回は、それぞれのアプリが同じDBを参照するようにしたいので、.envを変更して参照先が同じになるよう設定しておきましょう。
ページが表示されねぇ!みたいなときは、./logs配下のaccess.logやerror.logをヒントに対応してください。
まとめ
docker-composeでバシッと環境が整うと気持ちいいですよね。nginxの設定は基本的なものだけしか記述していないので、勉強がてらいろいろイジり倒そうと思います。
- 投稿日:2019-08-22T19:40:23+09:00
StaticPress S3のスクリプトをAWS SDK for PHP3に対応させて書く
急ですが、EC2上に構築しているWordPressの記事をHTMLに変換してS3のバケットに送るということをやりたくなりました。
StaticPressとStaticPress S3を試したのですが、ファイルをS3に送るところだけ別でいろいろとしたいなぁ、と考えました。
(この記事に載せるには「いろいろ」は大人の事情でかけません…。なので、バージョン上げた部分だけ書きます)ファイルをS3に送信するスクリプトは「StaticPress S3」のドキュメントにて公開されていました。
http://ja.staticpress.net/2013/06/11/69/
現在は2019年なので、内容が古いです。
AWS SDK for PHPのバージョンが2の時の内容ですね。現在はAWS SDK for PHPはバージョン3になってます。
https://aws.amazon.com/jp/sdk-for-php/
なので、このスクリプトを3を使って書き直してみました。
PHP7.3
AWS SDK for PHPはpharで落としてきて読み込んでいます。<?php require_once('aws.phar'); use Aws\S3\S3Client; use Aws\Exception\AwsException; use Aws\Credentials\Credentials; $key = 'Your Access Key'; $secret = 'Your Secret Key'; $region = 'ap-northeast-1'; $bucket = 'bucket_name'; $dir = '/var/www/html/fugafuga/'; /** * 指定されたディレクトリのファイル一覧を取得 */ function get_dir_file_list($dir) { $check_dirs = [$dir]; $file_paths = []; $file_name = []; while( $check_dirs ) { $dir_path = $check_dirs[0] ; if( is_dir ( $dir_path ) && $handle = opendir ( $dir_path ) ) { while( ( $file = readdir ( $handle ) ) !== false ) { if( in_array ( $file, [ ".", ".." ] ) !== false ) { continue; } $path = rtrim ( $dir_path, "/" ) . "/" . $file ; if ( filetype ( $path ) === "dir" ) { $check_dirs[] = $path ; } else { $file_name[] = $path; } } } array_shift( $check_dirs ) ; } return $file_name; } /** * ここから実際の処理 */ try { $credentials = new Credentials($key, $secret); // Create a S3Client $s3Client = new S3Client([ 'region' => $region, 'version' => 'latest', 'credentials' => $credentials, ]); $files = get_dir_file_list($dir); $info = new Finfo(FILEINFO_MIME_TYPE); foreach ($files as $filename) { $filetype = $info->file($filename); $filebody = fopen($filename, 'r'); if ( $filetype == 'text/plain') { if (preg_match('/\.css$/i', $filename)) { $filetype = 'text/css'; } else if(preg_match('/\.js$/i', $filename)) { $filetype = 'application/x-javascript'; } else if(preg_match('/\.html?$/i', $filename)) { $filetype = 'text/html'; } else if(preg_match('/\.xml$/i', $filename)) { $filetype = 'application/xml'; } } echo $filetype . ':' . str_replace($dir, '', $filename) . "\n"; $response = $s3Client->putObject([ 'Bucket' => $bucket, 'Key' => str_replace($dir, '', $filename), 'Body' => $filebody, 'ContentType' => $filetype, // 'StorageClass' => 'STANDARD', // 'ACL' => 'public-read', ]); } } catch(S3Exception $e) { echo $e->getMessage(); }ディレクトリ下のファイルを取得する関数を書き直しました。
拡張子である程度しぼって取得するほうがよかったかもなぁ、とも思います。ContentTypeも決めているので…。コメントにしてあるStorageClassとACLは必須パラメータではないです。
APIドキュメントはこちらを。
https://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html
- 投稿日:2019-08-22T18:56:16+09:00
PhpStormでCRLF/LF/CRを切り替える
改行コード 「CRLF」「LF」「CR」の違い。
CR(Carriage Return キャリッジリターン)
カーソルを左端の位置に戻すこと
LF(Line Feed ラインフィード)
カーソルを新しい行に移動すること
CRLF
CRとLFを組み合わせたもの。左端にカーソルを戻して改行する。
PhpStormでのCRLF/LF/CR切替方法
PhpStorm右下のCRLFをクリックで切替可能
備忘録
PhpStorm上でシェルスクリプトを書くとき、CRLFだと改行が入りシェルが実行されないので、LFに変えてから書きましょう。
参考URL
備忘録:改行コード「LF」と「CR」と「CRLF」の違い
https://marusunrise2.blogspot.com/2014/06/lfcrcrlf.html
- 投稿日:2019-08-22T15:59:58+09:00
PHPの配列をjson_encodeしたら、全角文字がユニコードになってハマった話。
タイトルのとおりの現象で、少々ハマりました。
結論としては、json_encodeの第2引数にJSON_UNESCAPED_UNICODEを指定すれば解決。
$array = [ 'ほげ', 'ふが', ]; $json = json_encode( $array, JSON_UNESCAPED_UNICODE );みたいな感じで。
- 投稿日:2019-08-22T14:58:37+09:00
【初心者向け】Laravel プロジェクトを clone してブラウザ表示するまで
Laravel のプロジェクトを clone してきて、SQLite3 に接続して、ブラウザで表示する方法は意外とまとまっていなかったので記事にしました。
推奨環境
- MacOS Mojave バージョン10.14.2
- Laravel Framework 5.8.31
- sqlite3 3.24.0
やり方
1. 対象の Laravel プロジェクトを clone してくる
$ git clone リポジトリ URL2. プロジェクトのリポジトリに移動し、vendor ディレクトリがないことを確認
$ cd projectName $ ls3. Composer がインストールされていなかったら
$ brew install composer4. ライブラリインストール
$ composer installvendor ディレクトリが作成されるはず。
5. ディレクトリ下の
.env.exampleの内容を.envにコピー$ cp .env.example .envclone してきた Laravel プロジェクトは
.envではなく.env.exampleというファイル名になっているので変更する必要がある。6. アプリケーションキー(APP_KEY)を設定する
$ php artisan key:generate.env ファイルの中身を見ると、
APP_KEYの内容がAPP_KEY=SomeRandomStringとなっているため、変更する必要がある。7. SQLite3 の準備
$ touch database/database.sqlitedatabase ディレクトリに
database.sqliteが作られる。8. .env ファイルの設定
エディタや vim などで .env ファイルの該当箇所を以下のように書き換える
~略~ DB_CONNECTION=sqlite # DB_HOST=127.0.0.1 # DB_PORT=3306 # DB_DATABASE=homestead # DB_USERNAME=homestead # DB_PASSWORD=secret ~略~DB_HOST以下はいらないのでコメントアウト。
SQLite3 の配置場所やファイル名を変更する場合は、DB_DATABASEに絶対パスで指定しましょう。9. migrate 実行
$ php artisan migrate10. いつものようにサーバーを立ち上げる
$ php artisan servehttp://127.0.0.1:8000 にアクセス
- 投稿日:2019-08-22T14:19:50+09:00
webarenaでubuntu その24
概要
webarenaでubuntu18.04やってみた。
php7.2やってみた。
session認証やってみた。login.php
<?php session_start(); header ('Content-Type: text/html; charset=Shift_JIS'); ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> </head> <body> <form action="index.php" method="POST"> ログインID:<input type="text" size="15" name="fLoginID"><br> パスワード:<input type="password" size="8" name="fPassword"><br> <input type="submit" value="ログイン"> </form> </body> </html>index.php
<?php session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $fLoginID = $_POST['fLoginID']; $fPassword = $_POST['fPassword']; $db = new PDO("mysql:host=localhost;dbname=mydb;", 'arena', 'pass'); $sql = "SELECT pass FROM test where flag='1' AND ID='$fLoginID'"; $res = $db->query($sql); if ($res->rowCount() != 1) { header ('Content-Type: text/html; charset=Shift_JIS'); print "アカウントが違う、もしくはユーザ登録されていません。"; print '<a href="../">こちらから登録してください。</a>'; session_destroy(); exit; } $user = $res->fetch(); if ($user["pass"] != $fPassword) { header ('Content-Type: text/html; charset=Shift_JIS'); print "パスワードが違います。"; session_destroy(); exit; } $_SESSION['sLogin'] = "ok"; $_SESSION['sId'] = $fLoginID; header("Location: contents.php"); } else if ($_SESSION['sLogin'] <> "ok") { header("Location: login.php"); } else { header("Location: contents.php"); } ?>以上。
- 投稿日:2019-08-22T14:07:25+09:00
BEAR.Sundayのモジュールを実装・CI・公開する
TL;DR
https://github.com/piotzkhider/Ray.FirebaseModule
記事のゴール
FirebaseをBEAR.Sundayで利用するためのモジュールを実装・公開する
既存のパッケージがあった…
https://github.com/ray-di/Ray.FirebaseModule
内容としてはまさにこれが欲しかったんだけど、3年前からメンテされていないようで使われているFirebaseのライブラリも現在主流のものとは異なっている様子。
こういうときどうしたらいいんだろう…
依存しているライブラリまでガッツリ変えちゃうようなPRを送る?
別ライブラリとして実装する?とりあえず今回はさくっとcomposerでインストールして使いたかったので別ライブラリとして実装する。
追記
既存のライブラリをForkしてガッツリ内容を変えたPRを提出して
- マージされるまではcomposer.jsonのrepositoryにForkして実装したGitHubを使う
- リジェクトされたら別ライブラリとしてpackagistにsubmitする
- マージされたら
composer requireでよかったのかも?
参考:
packagistを使わないcomposerのgitリポジトリの作成
https://getcomposer.org/doc/05-repositories.md#vcs実装
https://github.com/koriym/Koriym.PhpSkeleton
上記のスケルトンを利用してプロジェクトを作成する
CIやら静的(動的)解析ツールやらの設定が色々同梱されているので最低限のことは全部やってくれる。
PSR-12とは設定がずれている部分があったので、気になる人は下記を参考にして下さい。.php_cs.dist-'return_type_declaration' => ['space_before' => 'one'], +'return_type_declaration' => ['space_before' => 'none'],テスト
$ composer test // phpunit $ composer tests // php-cs-fixer & phpcs & phpmd & phpstan & phpunitどちらもエラーが出なくなったらGitHubに
commit&pushREADME.mdの作成
https://github.com/ray-di/Ray.DbalModule/blob/1.x/README.md
上記を参考にREADMEを作る
バッジを設定する
参考:
https://qiita.com/dtan4/items/13b0ea9edf5b99926446Travis CI
設定ファイル(.travis.yml)がスケルトンに入っているのでCIとしての設定はほとんど必要なし。
ただし今回はNightlyバージョンのPHPは必要ないので設定から削る.travis.ymlphp: - 7.1 - 7.2 - 7.3 - - nightly ... jobs: ... allow_failures: - - php: nightly画像の赤枠部分をクリックすることでバッジのコードを取得できる。
このままだと
Lowest dependenciesにエラーが出ているようなので修正が必要
Lowest dependencies?
通常与えられた条件の最新のバージョンがインストールされます。テストは最新の依存だけをテストすることになり。^や~で指定した最低のバージョンのテストは行われません。
これが問題になるのは、他のパッケージが特定のパッケージの低いバージョンのものに依存していて、また他のパッケージではその高いバージョンのみにある機能を使用している場合です。依存解決は低いバージョンで行われ、最新バージョンに依存したパッケージはエラーを引き起こしたりBugの元になったりします。
エラーが出ないよう修正する
> vendor/bin/phpunit PHPUnit 7.5.0 by Sebastian Bergmann and contributors. EEEEE 5 / 5 (100%) Time: 43 ms, Memory: 4.00MB There were 5 errors: 1) Piotzkhider\FirebaseModule\FirebaseModuleTest::testModule Error: Class 'PhpParser\ParserFactory' not found /PhpStormProjects/Ray.FirebaseModule/vendor/ray/aop/src/ParserFactory.php:13 /PhpStormProjects/Ray.FirebaseModule/vendor/ray/aop/src/Compiler.php:35 /PhpStormProjects/Ray.FirebaseModule/vendor/ray/di/src/Injector.php:32 ...phpstan-shimに存在しているこの問題のよう。
issueによるとbootstrap.phpでこの問題は解決しているようなので、bootstrap.phpが存在するバージョンを最低バージョンに指定する。参考:
http://blog.a-way-out.net/blog/2015/06/19/composer-version-tilde-and-caret/composer.json"require-dev": { "phpunit/phpunit": "^7.5", "squizlabs/php_codesniffer": "^3.2", "friendsofphp/php-cs-fixer": "^2.12", "phpmd/phpmd": "^2.6", - "phpstan/phpstan-shim": "^0.10" + "phpstan/phpstan-shim": "^0.10.2" },> vendor/bin/phpunit PHPUnit 7.5.0 by Sebastian Bergmann and contributors. EEEEE 5 / 5 (100%) Time: 109 ms, Memory: 12.00MB There were 5 errors: 1) Piotzkhider\FirebaseModule\FirebaseModuleTest::testModule Error: Class 'Google\Cloud\Core\ServiceBuilder' not found /Users/ysato/PhpStormProjects/Ray.FirebaseModule/vendor/kreait/firebase-php/src/Firebase/Factory.php:370 /Users/ysato/PhpStormProjects/Ray.FirebaseModule/vendor/kreait/firebase-php/src/Firebase/Factory.php:344 /Users/ysato/PhpStormProjects/Ray.FirebaseModule/vendor/kreait/firebase-php/src/Firebase/Factory.php:165 ...1つ目のエラーは解消されたが、また別のエラーが発生しているよう。
こちらも前回のエラーと同様に、低いバージョンでは必要となるファイルが存在していないことが問題になっているので、存在するバージョンを指定する。composer.json"require": { "php": ">=7.1.0", "ray/di": "^2.9", "kreait/firebase-php": "^4.30", + "google/cloud-core": "^1.19" },> vendor/bin/phpunit PHPUnit 7.5.0 by Sebastian Bergmann and contributors. ..... 5 / 5 (100%) Time: 123 ms, Memory: 16.00MB無事ローカルでのエラーも消え、Travis CIでのエラーがなくなりました!
scrutinizer
こちらも設定ファイル(.scrutinizer.yml)がスケルトンに入っているのでCIとしての設定は特に必要なし
画像の赤枠内の各バッジをクリックすることでバッジのコードを取得できる。
coverageがNot enabled
スケルトンの設定でTravis CIで出力されたカバレッジがscrutinizerに送られているが、設定がデグレしているようなので修正。
.travis.ymlscript: - - ./vendor/bin/phpunit -v --coverage-clover ./build/logs/clover.xml + - ./vendor/bin/phpunit -v --coverage-clover=coverage.clover after_script: - wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover;ついでにPRも出しておきます
全て正常に表示されました!
Packagistで公開
Submit Packageしておしまい!
と思ったのですが、タグをつけてあげないと
dev-masterになってしまうため、minimum-stability:devでないとインストールすることができなくなるようです。
(ブランチ名でもバージョン制御をしてくれるようですが、そちらもdev扱いになってしまいます)
1.0.0としてタグを登録します。$ git tag 1.0.0 [revision-number] $ git push origin 1.0.0参考:
https://getcomposer.org/doc/articles/versions.md#tags
git tagの使い方まとめ
- 投稿日:2019-08-22T03:10:24+09:00
PHP For Beginnersチュートリアル その15 会員登録フォームにパスワードリセットを実装する
このシリーズの目的
体系的なwebコーディングの訓練ができるようになるためにPHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために
上記のチュートリアルを進めているのでその備忘録。
内容
今回のチュートリアル
How To Create Forgot Password System In PHP & MySQLi [2018]
このチュートリアルでやること
・ログインフォームにパスワードリセットを実装する
(その12で作成した成果物に追加する)成果物
forgotPassword.php<?php $msg = ""; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; use PHPMailer\PHPMailer\SMPT; require_once 'function.php'; if (isset($_POST['email'])) { $conn = new mysqli('localhost','root','','register'); $email = $conn->real_escape_string($_POST['email']); $sql = $conn->query("SELECT id FROM users WHERE email='$email' "); if ($sql->num_rows > 0) { $token = generateNewString(); $conn->query("UPDATE users SET token='$token', tokenExpire = DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE email = '$email' "); mb_language("japanese"); mb_internal_encoding("UTF-8"); require 'vendor/autoload.php'; require 'Mailtrap-config.php'; $mail = new PHPMailer(); // Server $mail->SMTPDebug = 0; //本番では0とかにする。 $mail->isSMTP(); $mail->SMTPAuth = true; $mail->Host = MAIL_HOST; $mail->Username = MAIL_USERNAME; $mail->Password = MAIL_PASSWORD; $mail->SMTPSecure = MAIL_ENCRPT; $mail->Port = SMTP_PORT; // Recipients $mail->setFrom(FROM_MAIL); // $toname = mb_encode_mimeheader("$name", 'ISO-2022-JP', 'B', "\n"); $mail->addAddress($email); // $mail->addAttachment($attachment); // Content $mail->Subject = mb_encode_mimeheader("Reset Your Password", "ISO-2022-JP", "UTF-8"); $mail->Body = mb_convert_encoding(" パスワードリセットのリクエストがありましたので以下のリンクをクリックしてパスワードのリセットを行ってください。:<br><br> <a href='http://localhost/Laravel/PHPMailer/Training/phptutorial17/resetPassword.php?email=$email&token=$token'>パスワードリセットはこちらから</a><br> 七花 京 ","JIS","UTF-8"); $mail->CharSet = 'ISO-2022-JP'; $mail->Encoding = "7bit"; // Select HTML or NOT $mail->isHTML(true); if ($mail->send()) exit(json_encode(array("status" => 1, "msg" => 'Please Check Your Email Inbox!'))); else exit(json_encode(array("status" => 0, "msg" => 'Something Wrong Just Happened'))); } else exit(json_encode(array("status" => 0, "msg" => 'Please Check Your Input!'))); } ?> <!DOCTYPE html> <html> <head> <title>Forgot Password?</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"> </script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" type="text/javascript"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"> </script> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"> </script> <link rel="stylesheet" type="text/css" href="css/forgotPassword.css"> </head> <body> <div class="container"> <div class="row justify-content-center"> <div class="form col-md-6"> <form action="forgotPassword.php" method="post" enctype="multipart/form-data"> <input class="form-control" id="email" placeholder="Your Email Address"><br><br> <input type="button" class="btn btn-primary" value="Reset Your Password"><br><br> <p id="response"></p> </form> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.4.1.min.js"integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="crossorigin="anonymous"></script> <script> let email = $('#email'); $(document).ready(function () { $(".btn-primary").on('click',function () { if(email.val() !="") { email.css("border","1px solid green"); $.ajax({ url:'forgotPassword.php', method:'POST', dataType:'json', data:{ email:email.val() }, success:function(response) { if (!response.success) $("#response").html(response.msg).css('color','red'); else $("#response").html(response.msg).css('color','green'); } }); } else email.css("border","1px solid red"); }); }); </script> </body> </html>function.php<?php function generateNewString($len = 10) { $token = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789!$/()*'; $token = str_shuffle($token); $token = substr($token, 0, $len); return $token; } function redirectToLoginPage() { header('location:login.php'); exit(); } ?>resetPassword.php<?php require_once "function.php"; if (isset($_GET['email']) && isset($_GET['token'])) { $conn = new mysqli('localhost','root','','register'); $email = $conn->real_escape_string($_GET['email']); $token = $conn->real_escape_string($_GET['token']); $sql = $conn->query("SELECT id FROM users WHERE email='$email' AND token='$token' AND token<>'' AND tokenExpire > NOW() "); if ($sql->num_rows > 0) { $newPassword = generateNewString(); $newPasswordEncrypted = password_hash($newPassword, PASSWORD_BCRYPT); $conn->query("UPDATE users SET token='', password = '$newPasswordEncrypted' WHERE email='$email' "); echo "Your New Password Is $newPassword<br><a href='login.php'>Click Here To Log In</a>"; } else redirectToLoginPage(); } else { redirectToLoginPage(); } ?>動作
手順
・大枠のアルゴリズムを考える
1.まず、パスワードリセット申請フォーム(以下forgotPassword.php)に入力されたEmailアドレスが、登録情報が登録されているテーブルに存在するか検証
2.検証の結果、存在するのであれば任意の時間制限付きのトークンを発行し、再登録フォームへのリンク誘導を添えたEmailを送信する。
(その12でやったEmail認証リンクの仕組みに時間制限トークンを導入する)3.リンクをクリックした際にトークン及びEmail認証が正常に通った場合、ランダム文字列でパスワードを作りそれを新しいパスワードとして、成功メッセージとともに画面上に表示し、同時にそれをハッシュ化してデータベースに新しいパスワードとして登録し直す。
なお、通常の実装の場合はこれの後にユーザーがログインして任意のパスワードに自分で登録し直すかまたは、3の段階でユーザーに新しいパスワードを登録させることが考えられる。
・各段階でのアルゴリズムを考える
*データベースの接続などは割愛。
1.forgotPassword.php
→
・フォームに入力された文字列をエスケープする
・データベースにアクセスする
・エスケープした文字列を変数に代入する
・メールアドレスを検索フォームにし、入力されたメールアドレスがテーブルに存在する時はidを返す。存在しない時はエラーメッセージを表示する・idが返ってきたらトークンを生成し、検索フォームをメールアドレスにし、データベースに再度アクセスして該当するメールアドレスが存在するデータに時間制限付きのトークンを発行する
・認証リンク付きのメールアドレスを送信し、送信完了の旨のメッセージを表示する。メールが送信できない場合はエラーメッセージを表示する
・PHPMaillerなどを用いて、テーブルに登録されたユーザー宛に認証リンクが記載されたメールを送信する。
2.function.php
→
・ランダム文字列を生成する処理とリダイレクト処理を書いておいて、requireなどで呼び出せるようにしていおく。
文字列生成とリダイレクトはこれまでのチュートリアルでやったことなのでここでは割愛。3.resetPassword.php
→
・その12 で作ったものと同じ処理をさせる。・トークンとメールアドレスを取得する(認証リンクが踏まれているか確認する)。取得できたらデータベースに接続し、取得したメールアドレス及びトークンをエスケープして変数に代入する
・データベースに接続し、メールアドレス・トークン(空ではないという条件を付随する)・トークンに設定された有効期限が現在の時刻より先であるという条件で検索しする
・該当するデータが有ればデータベースに接続し、新しいパスワードを生成する。それをハッシュ化し、データのトークンを削除し、新しく生成したパスワードを登録する。該当するデータがない場合はログインフォームへリダイレクトする
・生成したパスワードとログインフォームへのリンクを表示する
今回のコードの注釈
tokenExpire周りについて>query("UPDATE users SET token='$token', tokenExpire = DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE email = '$email' ");今回新しく出てきたのはDATE_ADD(NOW(), INTERVAL)の形。
DATE_ADDは日付と時刻を取得する関数、第一引数に取得する日付及び時刻を設定する。
今回のNOW()は現在の日付と時刻を取得する、つまり処理が行われた時点での日付と時刻を取得することになる。
INTERVALには任意の時間を設定することで第一引数に指定した時刻から設定した分先の時間を取得する。
つまり、今回はINTERVALに5分と設定したので処理をが行われた時点の日付と時刻から5分先の時間を取得し、tokenExpaireに代入するということになる。<>演算子$sql = $conn->query("SELECT id FROM users WHERE email='$email' AND token='$token' AND token <> '' AND tokenExpire > NOW() ");<>は左辺と右辺が等しくないということを表す比較演算子及び配列演算子。
今回は万が一他者にメールアドレスと認証リンク及び空のトークン利用されてパスワードをリセットされないようにするために用いている。
- 投稿日:2019-08-22T02:08:08+09:00
Laravel【準備編】
環境:mac
初laravelのため、備忘録です。phpのバージョンを確認
$ php -vcomposerの用意
- https://getcomposer.org/download/ で最新のcomposerをダウンロードします。
composerを移動、パーミッション設定
##ダウンロードしたcomposer.pharが入っているフォルダに移動します。 $ cd /Users/ユーザー名/Downloads ※ユーザー名には自分のユーザー名を入れてください。 ##composer.pharをbinに移動します $ sudo mv composer.phar /usr/local/bin/composer ※binがなかったら作成しましょう。 $ udo mkdir /usr/local/bin ##パーミッション設定 $ chmod a+x /usr/local/bin/composerLaravelをインストール
$ composer global require "laravel/installer"環境変数を設定
$ echo export PATH=\"$HOME/.composer/vendor/bin:\$PATH\" >> ~/.bash_profile環境変数を読み込み
$ source ~/.bash_profileプロジェクトのテンプレートを生成
$ laravel new appディレクトリ移動
$ cd appローカルサーバーを起動
$ php artisan serveブラウザで開く
http://127.0.0.1:8000
へアクセスし、この画面が表示されれば成功です。
- 投稿日:2019-08-22T02:08:08+09:00
初めてのLaravel【準備編】
環境:mac
初laravelのため、備忘録です。phpのバージョンを確認
$ php -vcomposerの用意
- https://getcomposer.org/download/ で最新のcomposerをダウンロードします。
composerを移動、パーミッション設定
##ダウンロードしたcomposer.pharが入っているフォルダに移動します。 $ cd /Users/ユーザー名/Downloads ※ユーザー名には自分のユーザー名を入れてください。 ##composer.pharをbinに移動します $ sudo mv composer.phar /usr/local/bin/composer ※binがなかったら作成しましょう。 $ sudo mkdir /usr/local/bin ##パーミッション設定 $ chmod a+x /usr/local/bin/composerLaravelをインストール
$ composer global require "laravel/installer"環境変数を設定
$ echo export PATH=\"$HOME/.composer/vendor/bin:\$PATH\" >> ~/.bash_profile環境変数を読み込み
$ source ~/.bash_profileプロジェクトのテンプレートを生成
$ laravel new appディレクトリ移動
$ cd appローカルサーバーを起動
$ php artisan serveブラウザで開く
http://127.0.0.1:8000
へアクセスし、この画面が表示されれば成功です。
- 投稿日:2019-08-22T00:57:58+09:00
【cakePHP3.x】常時SSL化対応
cakePHPで作ったPJをさくらレンタルサーバに反映させたのですが、さくらの案内通りだとうまくいかなかったので.htaccessファイルのメモ
さくらの案内
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]実際はwebroot/.htaccessを下記に変更
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>













