- 投稿日:2019-07-14T22:44:51+09:00
php-master-changes 2019-07-13
今日は <?php に続いて空白文字が来なかった場合に T_INLINE_HTML を分割しないようにする修正、不要コードの削除、php_error_docref0() の php_error_docref() への置き換え、テストこけの修正、ドキュメントの更新があった!
2019-07-13
nikic: Don't split T_INLINE_HTML at partial PHP tag
- https://github.com/php/php-src/commit/0d568b9fd5bab4471219ed249c6c1c378bb46216
- [7.4~]
- 字句解析器で
<?php
に続いて空白文字が来なかった場合に T_INLINE_HTML を分割しないよう修正cmb69: No more need to cater to pre-PHP-5.3 or PHP-6 versions
- https://github.com/php/php-src/commit/a6fa097cebcd13baf6e152afcdbc0d1d5ae98d51
- [7.4~]
- ext/mysqli で、PHP 5.3 以前や PHP 6 でのバージョン表現を考慮した処理を削除
petk: Remove tsrm_config_common.h
- https://github.com/php/php-src/commit/33994ebd95c3c42b0dca4e0f161692ecee7d741b
- [7.4~]
- 不要ファイル tsrm_config_common.h の削除
Girgias: Convert all php_error_docref0 to php_error_docref
- https://github.com/php/php-src/commit/1c1de0c41a74b4deadd11cb18f00f115db0568ec
- [7.4~]
- php_error_docref0() を全て php_error_docref() に置き換え
- 経緯は PR:4254 あたりから
cmb69: Fix #78282: atime and mtime mismatch
- https://github.com/php/php-src/commit/bf242d58e77d50d4d8fdaaaca7ede686ec4467c0
- [7.4~]
- atime / mtime 関連のテストこけの修正
- 先日の別の修正で time_t が 64 ビットであることを仮定した内容になっていたため
cmb69: Fix #78283: no output for explicit environment
- https://github.com/php/php-src/commit/8c76d898a95cc91ef987c5efb77c1b43fd64a32c
- [7.4~]
- Windows での proc_open() のテストこけを修正
- php.ini で opcache 有効だけど環境変数 TEMP がセットされていない、となると子プロセスが起動できなくて死ぬので、子プロセス起動時に php.ini を読まないように、という修正
petk: Remove WARNING_LEVEL fix for QNX
- https://github.com/php/php-src/commit/499f2ac1328c6021b2557026b76f5154e24608d8
- [7.4~]
- ビルドシステムで、QNX 用のハックで WARNING_LEVEL を使っていたが不要になっていたので削除
petk: Remove checks for always enabled spl and pcre
- https://github.com/php/php-src/commit/f5e47718249a292c358cb1a3b4a333106540b6e1
- [7.4~]
- テストと run-tests.php で、常時有効な拡張 spl と pcre のチェックコードがあったのを削除
petk: Remove unused recode extension artefacts
- https://github.com/php/php-src/commit/f3cf8966be9fcbf25f5efe49640d4af409eb9864
- [7.4~]
- バンドルから外した recode の残骸を削除
petk: Remove php_multiple_shlib_versions_ok
- https://github.com/php/php-src/commit/4e0af6d8625e278956791237f874499afd26d34b
- [7.4~]
- ビルドシステムで、不要変数 php_multiple_shlib_versions_ok の削除
petk: Update changelogs
- https://github.com/php/php-src/commit/f573ba1948a8d5b1356d7741d03f1a18f4921d5d
- [7.4~]
- NEWS、UPGRADING、UPGRADING.INTERNALS の更新
- 投稿日:2019-07-14T18:56:17+09:00
Laravelのインストール
自分のパソコンにLaravelの開発環境を作ったので、
コマンド諸々忘れないように記録。1, composerインストール
$ brew install homebrew/php/composer
もしこれで、
Error: homebrew/php was deprecated.
This tap is now empty as all its formulae were migrated.こんなエラーが出たら、
$ brew install homebrew/core/composerこっちをうってみてください!これでいけます。
2, Laravelのインストール
Composerを使って、Laravelのインストーラーを
ダウンロードします。$ composer global require "laravel/installer"
そしたらパスを設定します。
$ vi ~/.bashrcで開いて、中身に
export PATH="$PATH:$HOME/.composer/vendor/bin"
を記述しました。そしたら読み込みます。
$ source ~/.bashrc3,プロジェクトを作成する
ここまでできたらプロジェクトを作るのですが、
composerコマンドでプロジェクトを作成します。$ laravel new {プロジェクト名}
というコマンドはよくない。らしい(理由が追えていない。。調べます。)
$ composer create-project --prefer-dist laravel/laravel {プロジェクト名}
できた!
そしたらサーバを起動しましょう!
$ php artisan serve
Laravel development server started: http://127.0.0.1:8000アクセスするとLaravelのページが表示されます。
(止める時はcontrol + c)無事完成です!
まとめ
composerって言うのがしれっと出たけど、
PHPのプロジェクトが必要とするライブラリやパッケージを管理する
「ライブラリ依存管理ツール」で、依存関係の解決に便利みたい。
(例えばAというパッケージの利用にBが必要な場合、
パッケージAを宣言すれば自動的にBインストールしてくれる、
みたいな感じ。これが手作業だとAもBもいちいちインストールしなきゃいけない。
めんどくさいですね。)ここから色々やっていくぞ〜
- 投稿日:2019-07-14T17:47:47+09:00
Raspberry Piで Laravel5.8 PHP7.3 nginx1.14の環境構築
Raspberry Pi 3 Model B+ を購入。Laravelで作成したいアプリケーションがあったため環境構築。
それとpythonスクリプトを使って有機ELにいろいろ表示させるものを作ってみようかと。
とりあえずLaravelインストールまで。ラズパイということでApacheでなく軽量なnginxにしました。
あまり効率的でない手順かもしれないですがご勘弁を。[前提]
Raspberry Piセットアップ済み (OSはRaspbian)
あとはvimをインストール、デフォルトエディタ変更とbashrcを自分用に修正したくらいですとりあえずアップデート
rootユーザからの作業 $ sudo su - アップデート # apt-get updatenginxインストール・設定
インストール # apt-get install nginx 確認 # nginx -v 起動、自動起動設定 ##systemctl start nginx # systemctl enable nginxブラウザで表示確認。
http://Raspberry PiのIPアドレスphp-fpmインストール・設定
インストール # apt-get install php7.3-fpm nginx + php設定 # vi /etc/nginx/sites-available/default ※44行目あたり (index.php追加) [変更前] # Add index.php to the list if you are using php index index.html index.htm index.ngin-debian.html; [変更後] # Add index.php to the list if you are using php index index.html index.htm index.ngin-debian.html index.php; ※56から63行目のコメントアウト削除 (62行目のfastcgi_passの行のみコメントのまま) location ~ \.php$ { … fastcgi_pass unix:/run/php/php7.3-fpm.sock; … # fastcgi_pass 127.0.0.1:9000; } PHP設定 # vi /etc/php/7.1/fpm/php.ini ※775行目 [変更前] ;cgi.fix_pathingo=1 [変更後] cgi.fix_pathingo=0 再起動 # systemctl restart php7.3-fpm # systemctl enable php7.3-fpm # systemctl restart nginx PHP確認用 # echo '<?php phpinfo(); ?>' > /var/www/html/test.phpブラウザで表示確認。
http://Raspberry PiのIPアドレス/test.phpphpinfo表示されたらOK。「あ」と表示されなくても大丈夫。
Mariaインストール・設定
インストール # apt-get install php7.3-mysql # apt-get install mariadb-server 確認 # mysqld -V # mysql -V 設定 # mysql_secure_installation ※rootパスワード設定、他は基本 Y+Enter 管理者権限でログインできるよう設定 # mysql -u root > use mysql; > update user set plugin='' where user='root'; > flush privileges; > quit; 先ほど設定したパスワードでログイン確認 # mysql -uroot -p 自動起動しておく systemctl enable mariadbLaravel環境セットアップ
Composerでやります # apt-get install composer 確認 # composer -V ディレクトリ作成 # mkdir /var/www/laravel ↓自分だけの開発環境のため安易に済ませている。 # chmod 777 /var/www/laravel project作成に必要 # apt-get install php-xml piユーザに戻る(もしくはLaravel実行ユーザ) # exit project作成(ちょっと時間かかる) $ composer create-project laravel/laravel /var/www/laravel Laravelバージョン確認 $ cd /var/www/laravel/ $ php artisan --version rootに戻る $ sudo su - DocumentRoot設定を書き換え # vi /etc/nginx/sites-available/default ※41行目以下に変種 # root /var/www/html; root /var/www/laravel/public; nginx再起動 # systemctl restart nginx failed to open stream対策 ↓自分だけの開発環境のため安易に済ませている。 # chown -R www-data:www-data /var/www/laravel/storage # chmod -R 757 /var/www/laravel/storageブラウザ確認
ブラウザで表示確認。
http://Raspberry PiのIPアドレス
- 投稿日:2019-07-14T16:00:40+09:00
macOS Mojaveで最新のPHP(7.3)にVersion upする
背景
なんてことはないけど、エラーが多発したので備忘録として
操作
Homebrewはインストールしている前提
$ brew search php@7 $ brew install php@7.3Pythonインストール時にerrorがでる
An unexpected error occurred during the `brew link` step The formula built, but is not symlinked into /usr/local Permission denied @ dir_s_mkdir - /usr/local/Frameworks以下のコマンド実行
$ sudo mkdir /usr/local/Frameworks $ sudo chown $(whoami):admin /usr/local/Frameworks $ brew link pythonもう一度
$ brew search php@7 $ brew install php@7.3今度は
Error: The `brew link` step did not complete successfully The formula built, but is not symlinked into /usr/local Could not symlink sbin/php-fpm /usr/local/sbin is not writable. You can try again using: brew link phpPythonインストール時のエラー同様に以下を実行
$ sudo mkdir /usr/local/sbin $ sudo chown $(whoami):admin /usr/local/sbin $ brew link php以下のメッセージがでる
If you need to have php@7.3 first in your PATH run: echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile指示通り
$ echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile $ echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile $ brew services start phpターミナルを再起動してPHPのVersion確認
$ php -v以下のメッセージが出れば成功
PHP 7.3.7 (cli) (built: Jul 5 2019 12:44:05) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.3.7, Copyright (c) 1999-2018, by Zend Technologies念の為 phpinfoを確認
$ touch index.php $ echo "<?php phpinfo(); ?>" >> index.php $ php -S localhost:8000がphpinfoでも出ればOK.
参考
- 投稿日:2019-07-14T13:06:38+09:00
少数のあれこれ【備忘】
小数の桁数を取得する
$num1 = 12.345; strlen(substr(strrchr($num1, '.'), 1));解説
- strrchr関数を使用して、ドット[.]の開始位置を取得
- substr関数を使用して、ドット[.]の次の値以降を取得
- strlen関数を使用して、取得文字の長さを取得
参考
小数点以下の数字を指定桁数だけ丸める
- 丸める
- 1.23 という値を小数点第一位で返したい場合、1.2で返す
- 1.28 という値でも同様に小数点第一位で返したい場合は、1.2で返す
- 上記数字を小数点第二位で返したい場合、1.23 は、1.23を返し、1.28 は、1.28を返す
$digit = 3; $fraction = 1.2345; round($fraction + 0.5 * pow(0.1, $digit), $digit, PHP_ROUND_HALF_DOWN)解説
- pow関数を使用して、指数を作る
- 末尾に0.5を足す事で、繰り上げ・下げをせず 元々の値から指定した桁数だけ切り捨てて返すようにするため
- round関数を使用して、浮動小数点を$precisionの値だけ丸める
- その時、第3引数に PHP_ROUND_HALF_DOWN を指定して、0に近く方向に値を丸める
- 例えば、1.5 → 1 にして、-1.5 → -1 にする
参考
小数の整数部と小数部をそれぞれ取得する
$num1 = 12.345; $integer = floor($num1); $fraction = $num1 - $integer; $digit = strlen($integer);解説
- floor関数を使用して、整数部分を取得
- 元の値から、整数部分を引いて、少数部分を取得
- strlen関数を使用して、整数部分の桁数を取得
参考
- 投稿日:2019-07-14T12:58:00+09:00
最長AB列を求める
最長AB列を求める
文字'A'と文字'B'からなる文字列Sがあります。
Sに含まれる連続した区間で'A'と'B'の数が等しいものの最長の長さを答えよ。ソースコード
<?php //入力値 $nyu = "ABBBAAAAA"; //評価する値(それぞれの区切った値を配列に格納) $hyo1 = "A"; $hyo2 = "B"; $arrray1=explode($hyo1, $nyu); $arrray2=explode($hyo2, $nyu); //A、B配列の数分だけ、レングスを格納する for($i = 0; $i < count($arrray1); $i++){ $arr1_len[$i] = strlen($arrray1[$i]); } for($i = 0; $i < count($arrray2); $i++){ $arr2_len[$i] = strlen($arrray2[$i]); } //取得した配列のmax値を取得 $arr1_max = max($arr1_len); $arr2_max = max($arr2_len); //A,B双方で取得したmax値の低いほうを取得 $arr_min = min($arr1_max,$arr2_max); //結果値 $kekka = $arr_min * 2; print($kekka); ?>
- 投稿日:2019-07-14T12:29:07+09:00
JSで公開鍵を使って暗号化したデータをPHPで秘密鍵を使って復号する
公開鍵暗号を用いて、JSでデータを暗号化したものをPHPで復号してみます。
記載内容に問題があっても責任は取れないので、参考にする場合は自己責任でお願いします。
また、参考にした公式のドキュメントを載せるので、情報が変わっていないかそちらを確認していただければと思います。ちなみに、パスワードは暗号化せずにハッシュ化しましょう。
公開鍵と暗号鍵を作成する
まずは暗号化に使う鍵を作成しておきます。
$ openssl genrsa -out rsa_2048_priv.pem 2048 $ openssl rsa -pubout -in rsa_2048_priv.pem -out rsa_2048_pub.pem1024bitで作成している記事もありますが、2048bit以上のRSA鍵を使用するようにしましょう。
JSでの暗号化について
調べてみると、JSで暗号化を行う場合に様々なライブラリが存在しました。
英語ですが、下記のgistにJSで暗号化させる時のライブラリの一覧が載っています。
JavaScript Crypto Librariesただ、node.jsだとデフォルトでcryptoというモジュールが使えますし、多くのブラウザではSubtleCrypto オブジェクトが実装されています。
今回はLaravelのプロジェクトで使うことを想定して、node.jsのcryptoモジュールを使用します。
cryptoモジュールで暗号化する
公開鍵で暗号化するにはcrypto.publicEncryptというメソッドを使用します。
const crypto = require('crypto'); // 先ほど作成したpublickey const publicKey = `-----BEGIN PUBLIC KEY----- hogehogehogehgoe -----END PUBLIC KEY----- `; const plain = 'hoge fuga'; const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(plain)); console.log(encrypted); console.log(encrypted.toString('base64'));ドキュメントを見るとpublicEncryptの第二引数が
buffer
となっていますが、new Buffer()
は廃止予定となっており、使用するとwarningが出たと思います。
いくつか記事を調べると、new Buffer(plain)
を使用している記事が多いですが、Buffer.fromを使用して、バイナリデータに変換します。参考
今年のうちに対応したい、Node.jsのBufferに潜む危険性暗号化した結果を確認してみる
base64エンコードした結果をサーバ側へ送り、DBなどに保存をする想定です。
Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式である
$ node publicEncrypt.js # console.log(encrypted); <Buffer b7 8c 41 4b 5e 3b 84 59 4a 31 f7 e5 53 a4 41 5d 55 c3 05 7d 27 18 9d 6d d6 eb 15 45 7d 53 01 99 79 eb ea d7 95 d6 2e 31 c1 b1 2c 76 ed cc 48 4a dd ea ... > # console.log(encrypted.toString('base64')); t4xBS147hFlKMfflU6RBXVXDBX0nGJ1t1usVRX1TAZl56+rXldYuMcGxLHbtzEhK3equw7qE8cCNulqJfst40B5OSThpkUoEiA9Q1Bo6b5RIhyZi8IQsTSZCkNE2LQaEILl5JZXfioYXmjTfMqDhn/jI6QLagWkRyd2jYIZVQ6ChhjzYG2eVWo5otli/N4Z9j93FKKQ1n8fiIvY62lZsOSv9I0F/ZZzCcYPFvI1DeOuYIw6StHC20lPo49d6quNjAAZwiLI9p43kue1PnD4M2HwwVFWYr4DRveDkR3gIUhOGk8UDI8BeCrwjVsz9jT5MjpAVp/6BT8/W1Q0NgJyctA==PHPでの復号について
openssl-private-decryptを使うことで復号可能です。
// 先ほど作成した秘密鍵 $privatekey = <<<EOD -----BEGIN RSA PRIVATE KEY----- hogehogehgoe -----END RSA PRIVATE KEY----- EOD; // 先ほど暗号化した文字列 $encrypted = 't4xBS147hFlKMfflU6RBXVXDBX0nGJ1t1usVRX1TAZl56+rXldYuMcGxLHbtzEhK3equw7qE8cCNulqJfst40B5OSThpkUoEiA9Q1Bo6b5RIhyZi8IQsTSZCkNE2LQaEILl5JZXfioYXmjTfMqDhn/jI6QLagWkRyd2jYIZVQ6ChhjzYG2eVWo5otli/N4Z9j93FKKQ1n8fiIvY62lZsOSv9I0F/ZZzCcYPFvI1DeOuYIw6StHC20lPo49d6quNjAAZwiLI9p43kue1PnD4M2HwwVFWYr4DRveDkR3gIUhOGk8UDI8BeCrwjVsz9jT5MjpAVp/6BT8/W1Q0NgJyctA=='; // base64エンコードしているのでデコードしてから復号する $decoded= base64_decode($encrypted); openssl_private_decrypt($decoded, $decrypted, $privatekey, OPENSSL_PKCS1_OAEP_PADDING); var_dump(decrypted);ポイントとしては、
openssl_private_decrypt
の第四引数にOPENSSL_PKCS1_OAEP_PADDING
を指定しているところかなと思います。crypto.publicEncryptのドキュメントに、
RSA_PKCS1_OAEP_PADDING
を使用していると記載がありますので、php側でも同じパディングを指定しています。Otherwise, this function uses RSA_PKCS1_OAEP_PADDING.
下記のように第四引数に指定しない場合には、$decryptedがnullとなってしまいます。
openssl_private_decrypt($decoded, $decrypted, $privatekey);復号した結果を確認してみる
これでできた
$ php privateDecrypt.php string(9) "hoge fuga"連携部分について
公開鍵も秘密鍵もサーバ側で持っておいて、公開鍵のみを
csrf-token
と同じようにhtmlのmetaに埋め込むか、公開鍵を取得するためのAPIなどを用意してJSで取得をできるようにすれば良いと思います。注意点
公開鍵暗号では容量の大きいデータをまとめて暗号化できない
当たり前かもしれませんが、公開鍵暗号では大きなサイズのデータを暗号化できません。
そのため、そこそこ長い文章などを暗号化しようとすると、下記のようなエラーが表示されてしまいます。Error: error:0409A06E:rsa routines:RSA_padding_add_PKCS1_OAEP_mgf1:data too large for key size容量の大きいデータを暗号化してサーバ側に送りたい場合には、公開鍵と共通鍵を使ったハイブリッド暗号で対応する必要があると思います。
うまく復号できない場合に確認すること
最初復号できなかったのですが、teratailで同じような質問があり、参考にさせてもらいました。
使うライブラリやメソッドなどによって、設定に差異がないかを確認する必要ありそうです。・暗号アルゴリズム(AES等) ・鍵長(256ビット等) ・モード(CBC等) ・パディング(pcks7等)その他参考情報
- 投稿日:2019-07-14T11:18:21+09:00
EclipseでPHPのデバッグを可能にする(xdebugを使用)
Eclipse上でPHPのデバッグを実行したいと考えたのですが、設定に結構苦戦しました。
同じ悩みを抱える人も多いようなので、備忘録として公開してみます。ほぼ素人の考え方なので、見当違いな部分もあると思いますが、そこは勘弁してください。OS: Windows7 64bit
PHP: 7.3.7
Apache: 2.4.39※PHPをローカル環境で使う場合は、xamppを利用することが多いと思いますが、今回の例ではPHPとApacheを単独でインストールします。
PHPとApacheのインストール・設定
PHPのインストールはこちらを参照、
Apacheのインストールはこちらを参照しました。PHP: 7.3.7
Apache: 2.4.39phpinfo()を使って、設定内容を確認する画面を出します。こちらを参照。下図のようにブラウザに表示されるはず。このページはこのまま表示させておきます。
xdebugの入手とphp.iniの設定
こちらのページで、xdebugのdllをダウンロードします。さっき表示しておいたPHP設定内容を確認する画面で、内容を全部コピー(ctrl + a → ctrl + c で大丈夫)し、ダウンロードページのテキストエリアに貼り付けます。これで必要なxdebugのバージョンを調べてくれるので、「Analyse my phpinfo() output」ボタンを押してダウンロードへ。
自分の環境では、"php_xdebug-2.7.2-7.3-vc15-x86_64.dll"というファイルがダウンロードされました。このdllファイルを、php.iniと同階層にある"ext"フォルダに格納します。
次にphp.iniを開き、末尾に以下のように追加。
[XDebug] zend_extension=C:\php-7.3.7\ext\php_xdebug-2.7.2-7.3-vc15-x86_64.dll xdebug.remote_connect_back=On xdebug.remote_enable = 1 xdebug.remote_host = "localhost" xdebug.remote_port = 9000zend_extension= には、xdebugのdllを格納したディレクトリを指定。
xdebug.remote_port は、9000にしておくのが一般的みたいです。Apacheを再起動し、再びphpinfo()でPHPの設定を確認。下図のようにxdebug関連の情報が表示されていればOK。
eclipseのインストールと設定
※eclipseをインストールする前に、Apache、PHP、xdebugのダウンロードと設定、php.iniの設定をしておいたほうが無難なようです。
先にeclipseをインストールしたら、起動時にサーバー関連のエラーが出るようになってしまったので。自分の知識不足とは思いますが。
エラーの発生を止められなくなった時に、eclipseのworkspaceのフォルダを丸ごと削除したら発生しなくなりました。プロジェクト等を作成してからではできないことなので、先にデバッグができる環境を整えることを優先すべきかと思います。こちらから、Eclipse IDE for PHP Developersをダウンロードし、インストール。
PHP開発用のプラグインもありますが、PHP専用のeclipseを別にインストールするほうが無難な気がします。動作がおかしくなっても、インストールし直せば済むことになるので。Pleiadesで日本語化もしておきましょう。
eclipseをインストールしたら、「ウィンドウ」→「設定」→「PHP」→「インストール済みのPHP」で、新規のPHP実行可能ファイルを登録します。
「次へ」ボタンで、デバッガー設定へ。「デバッガー」はXdebug、ポートは9000を指定。この設定は不要かもしれませんが、やっておいたほうがいいとは思います。
プロジェクト用のディレクトリとファイル作成
通常はeclipseのworkspaceにプロジェクトのディレクトリを作成しますが、今回はApacheのドキュメントルートの下に作成します。
Apacheをインストールしたディレクトリの、"htdocs"フォルダの下にプロジェクト用のディレクトリを作成。
eclipseから、このディレクトリをインポートします。「実行」→「デバッグ構成」から、PHP Webアプリケーションで新規構成を選択。
最初に、PHPサーバーを新規登録します。
サーバー名は適当に。ベースURLはlocalhost指定で。ドキュメントルートは、Apacheのドキュメントルートを指定。
「次へ」でデバッグの設定へ。
デバッガーはXdebug。ポートは9000を指定。「完了」ボタンで終了。
次にデバッグ構成を登録します。PHPサーバーは、先程新規登録したサーバーを指定。ファイルは、プロジェクトのindex.phpでいいでしょう。他のファイルを指定もできます。これでデバッグモードで実行できるようになりました。下図のように、ブレークポイントで止まります。変数の値も取得できます。
注意点として、デバッグで実行ではなく通常の実行でスタートしても、強制的にデバッグモードになってしまうようです。通常の実行をするなら、「実行の構成」でデバッグを"None"にしたPHPサーバーを指定しておくといいようです。
全般的に、こちらのページが非常に参考になりました。このページを見たほうが分かりやすい人も多いと思います。
今回参考にしたリンク。
PHP入門
Apache入門
phpinfo関数による設定内容の確認
Xdebug Tailored Installation Instructions
Eclipse Packages Download
Pleiades Plugin ダウンロード
【PHPへ xdebug導入】は簡単。実はEclipseで動かす設定が環境依存で若干ややっこい
Eclipse PHP(Pleiades All in One)でハマった件 起動でエラー
- 投稿日:2019-07-14T10:21:56+09:00
入力値は全体の何パーセント
- 投稿日:2019-07-14T04:40:15+09:00
PHPでRARファイルの解凍をする
はじめに
RARファイルの解凍をやりたかったけど、公式ではZipArchiveしかないみたい。
PECLの方にRarArchiveというのがあるみたいなので、これを使う。環境
- Windows 7
- PHP 7.1
RarArchiveのダウンロードと設定
ここからダウンロード。
僕はWinなのでVer.4.0.0 の「DLL」 -> 「7.1 Non Thread Safe (NTS) x86」をダウンロードしました。
ダウンロードしたやつの中身に「php_rar.dll」があるので、それを php の ext フォルダに配置。
php.ini
に以下追記。php.ini[PHP] extension=php_rar.dll追記後、サーバー再起動。
解凍
$archive = RarArchive::open("dir/"); $entries = $archive->getEntries(); foreach ($entries as $entry) { $entry->extract($to_dir); } $archive->close();ZipArchive との違いは、一度
getEntries
しないと中身がとれない。ついでに、ファイル名が日本語だと Failed to open になるっぽいです。
さいごに
公式で扱える形式増やして(懇願
- 投稿日:2019-07-14T04:15:31+09:00
PHPでObserverパターンで実装してみた
はじめに
Rx****をやってみたくなり、基本となる(?)ObserverパターンをPHPにて実装して見た。
前提条件として、
- PHP5.xでも動く
- ある程度実用的
とします。
Observerパターンとは
あちこちのページで書かれているので細かくは省略します。
状態変化に応じた処理を記述するときに有効らしいです。今回のサンプル
タイトルと内容を入力とするフォームからPOSTされた時に、
- メール送信
- ログ出力
を行う処理を記述するのにObserverパターンで記述してみます。
(この程度でObserverパターンを使うのもって話はあるが。。。(汗)
クラス図はこんな感じ
ソース構成はこんな感じ
┣━ classes
┃ ┣━ ifSubject.php
┃ ┣━ clsFormdat.php
┃ ┣━ ifObserver.php
┃ ┣━ clsLogObserver.php
┃ ┣━ clsSndMailObserver.php
┗━ smp1.php実装
インターフェイス
まずSubjectのインターフェイスは
ifSubject.php<?php /** * Subjectインターフェイス */ interface ifSubject { public function addObserver($obj); // Observerインスタンス追加 public function removeObserver($obj); // Observerインスタンス削除 public function notify(); // Observerへの通知 }次にObserverインターフェイスは
ifObserver.php<?php /** * Observerインターフェイス */ interface ifObserver { public function execute($obj); // Subjectからの通知受信 }Subjectクラス
clsFormdat.php<?php require_once(dirname(__FILE__)."/ifSubject.php"); /** * フォームデータクラス */ class clsFormdat implements ifSubject { private $title = ""; /// タイトル private $memo = ""; /// 内容 private $arrObservers = NULL; /// Observerインスタンス配列 public function __construct() { $this->arrObservers = array(); } /** * タイトルと内容のセッター */ public function __set($itm,$val) { if ( $itm == "title" ) $this->title = $val; if ( $itm == "memo" ) $this->memo = $val; } /** * タイトルと内容のゲッター */ public function __get($itm) { if ( $itm == "title" ) return $this->title; if ( $itm == "memo" ) return $this->memo; } /** * Observerインスタンス追加 * @param $obj Observerインスタンス */ public function addObserver($obj) { $this->arrObservers[get_class($obj)] = $obj; } /** * Observerインスタンス削除 * @param $obj Observerインスタンス */ public function removeObserver($obj) { unset($this->arrObservers[get_class($obj)]); } /** * Observerへの通知 */ public function notify() { foreach($this->arrObservers as $obj) { $obj->execute($this); } } }Observerクラス
まず、ログ出力クラスは
clsLogObserver.php<?php require_once(dirname(__FILE__)."/ifObserver.php"); /** * ログ出力クラス */ class clsLogObserver implements ifObserver { public function __construct() { } /** * 通知受信 * @param $obj clsFormdatのインスタンス */ public function execute($obj) { $buf = "title:".$obj->title; $buf .= "\n".$obj->memo; $fp = fopen("/var/www/Log/app.log","a"); fwrite($fp,$buf); fclose($fp); } }次にメール送信クラス
clsSndMailObserver.php<?php require_once(dirname(__FILE__)."/ifObserver.php"); /** * メール送信クラス */ class clsSndMailObserver implements ifObserver { public function __construct() { } /** * 通知受信 * @param $obj clsFormdatのインスタンス */ public function execute($obj) { mail("tst@cde.jp",$obj->title,$obj->memo,"From: adm@cde.jp"); } }動かしてみる
次のコードで実際に動かしてみる。
smp1.php<?php require_once(dirname(__FILE__)."/classes/clsLogObserver.php"); require_once(dirname(__FILE__)."/classes/clsSndMailObserver.php"); require_once(dirname(__FILE__)."/classes/clsFormdat.php"); $obj = new clsFormdat(); $objLog = new clsLogObserver(); $obj->addObserver($objLog); $objMail = new clsSndMailObserver(); $obj->addObserver($objMail); $obj->title = "サンプルタイトル"; $obj->memo = "サンプルサンプル\nサンプル"; $obj->notify();確かに実装はシンプルになったようだ。
- 投稿日:2019-07-14T03:07:40+09:00
Laravel vs Symfony(DDDの場合)
PHP で DDD(ドメイン駆動設計)をする案件でウェブフレームワークの選定を行いました。
フレームワーク選定にあたり、以下の方針を立てました。
- 実績のあるフレームワークから選定(Laravel か Symfony の2択としました)
- DDD が提唱している不変条件をモデルに実装出来ること
- フレームワークと戦わない(目的達成の為に Hack 等の小細工をしない)
- 人がレビュー等で注意するといった回避策で妥協しない
- なるべくシンプルにフレームワークを使う
本来、フレームワークはドメイン層に関心がなく DDD に制約を与えないはずです。
一方で DDD はドメイン層以外には具体的な実装方法を提示していません。
DDD をやるのにどのフレームワークを使ってもいいのでは?と思うのですが、実際にはそうではありませんでした。フレームワークが採用している ORM によって DDD しやすいものと困難なものがあります。
FW ORM パターン 調査結果 Laravel Eloquant Active Record 設定が無く簡単
モデルで constructor や public, private といったアクセス修飾子が自由に使えない
モデルに不変条件の実装ができずDDDに不向きSymfony Doctrine Data Mapper DBのテーブルカラムとモデル属性のマッピング設定が必要
モデルで constructor や public, private といったアクセス修飾子が自由に使える
モデルに不変条件の実装ができてDDDに向いている上記表の結果から PHP での DDD 案件では Symfony を採用することに決定しました。
我々は Laravel をとても気に入っていたので、なかなか Laravel をあきらめる気にはなれませんでした。しかし、色々と調べたのですが良い方法は見つかりませんでした。Active Record でもうまくDDDやっているという方がいましたら、ぜひ、知見をお聞かせください。
参考情報
モデルでドメイン知識を表現するとは何か・・・不変条件について、とても分かりやすい記事です
- 投稿日:2019-07-14T02:42:09+09:00
Laravelでのマルチ認証でログイン後のリダイレクト先をroleで変更する方法
概要
セッション衝突問題とかは置いておいてシンプルにroleを使ってログイン先を変更する話です。
Laravelデフォルトの認証を使います。UsersテーブルにRoleを追加
migrationファイルでroleを追加しておきまましょう。
roleは数値でもenumでも良いです。
今回は admin,teacher,parentを用意したと仮定して進めます。redirectTo()
Auth\LoginControllerにredirectToメソッドを定義してあげます。
そうすると既に定義してあるprotected $redirectToではなくredirectTo()の戻り地でredirect先が決定するようになります。
この辺りのことは\Illuminate\Foundation\Auth\RedirectsUsers.phpに書いてあります。
trait RedirectsUsers { /** * Get the post register / login redirect path. * * @return string */ public function redirectPath() { if (method_exists($this, 'redirectTo')) { return $this->redirectTo(); } return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home'; } }traitがtrait先のコントローラーでメソッドかプロパティの定義を期待しているのはちょっと変わった実装ですね。
LoginControllerにredirectTo()を実装
public function redirectTo(){ $role = $this->guard()->user()->role; if($role === 'admin'){ return '/admin'; } if($role === 'teacher'){ return '/teacher'; } if($role === 'parent'){ return '/parent'; } return '/'; }roleに当てはまらなかったら例外投げても良いのですが今回は'/'にします。
まとめ
これでログイン後のリダイレクト先を変更することが出来ました。
role別に認証や認可でアクセス先を制限するのは別な実装が必要です。参考
Laravelで複数テーブルを使ったログイン認証を実装する
https://qiita.com/sakuraya/items/248d1bed5857c69e44c4
【Laravel】Laravel5.5でユーザーと管理者の認証(MultiAuth)を実装する(マルチログイン実装時のセッション分割対応)
https://qiita.com/sola-msr/items/65634826bcedf3ea4ca4
やはりお前らのMulti-Auth は間違っている
https://qiita.com/h1na/items/bbe4d17af21860de1930
- 投稿日:2019-07-14T00:47:07+09:00
ssh(sftp)サーバーをLaravelのストレージとして利用する
はじめに
Laravelのファイルストレージで外部のサーバーのファイルを取り扱いたい場面に遭遇して解決方法が見つかったのでメモとして残します。
ファイルストレージは標準ではローカル ディスクとAmazon S3、Rackspace、ftp用のアダプタが組み込まれています。調べてみるとFlysystemというライブラリの機能で実現されていて、アダプタを追加すれば様々なデバイスをストレージとして利用できる仕組みになっています。
Laravelには入っていませんがFlysystemには標準でsftpのアダプタが用意されています。これを利用すると任意のsshサーバーをsftp経由でLaravelのストレージとして利用可能です。
手順
composer で sftp アダプタのモジュールをインストール
composer require league/flysystem-sftp
サービスプロバイダでアダプタを追加する。
<?php namespace App\Providers; use Storage; use League\Flysystem\Filesystem; use League\Flysystem\Sftp\SftpAdapter; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { ... public function boot() { /** * flysystem に sftp 用のアダプタを追加する * @see https://flysystem.thephpleague.com/docs/adapter/sftp/ * @see https://readouble.com/laravel/5.5/ja/filesystem.html#custom-filesystems */ Storage::extend('sftp', function ($app, $config) { return new Filesystem(new SftpAdapter($config)); }); } }
config/filesystems.php
にディスクを追加する。<?php return [ ... /** * sftp アダプタで ssh サーバーを disk として登録する * * @see https://flysystem.thephpleague.com/docs/adapter/sftp/ */ 'rpx' => [ 'driver' => 'sftp', 'host' => '192.168.10.11', 'port' => 22, 'username' => 'vagrant', // 'password' => 'vagrant', 'privateKey' => '/home/vagrant/.ssh/id_rsa', 'root' => 'rpx', 'timeout' => 10, ], ];接続先サーバーには対応する公開鍵を登録する。
ストレージで利用する
Storage::disk('rpx')->put('./a/test.txt', "hello rpx\n");
- 投稿日:2019-07-14T00:09:17+09:00
[PHP][GraphQL]13月32日を受け入れないようにする、とある1つのScalar
ちょっと試してみたところから、正しいってどこかな?と予想外に探したという小話です
環境
- PHP 7.3
- Laravel 5.8
- Composer 1.8.6
- nuwave/lighthouse 3.6.1
- mll-lab/laravel-graphql-playground 1.0.2
こんなことが
年月日時分秒の時刻を示す文字列から、その「月末」を出す関数を実行した結果です
わざとあり得ない日時を渡したのですが、思わぬ方向に処理された、という感じです
正しくしようとして
ここでの「正しい」は、「間違ったものとして、処理させない」とします
カスタムScalarをつくる
公式1でも「実装次第」とかいているので、実装していきます
# php artisan lighthouse:scalar DateTime Scalar created successfully. # php artisan lighthouse:scalar Date Scalar created successfully.実装していったのがこちらになります
- https://github.com/sogaoh/LaravelPractice/blob/master/server/app/GraphQL/Scalars/DateTime.php
- https://github.com/sogaoh/LaravelPractice/blob/master/server/app/GraphQL/Scalars/Date.php(そして、元から用意されてたのは使わないようにコメントアウト)
実装のポイント
何をもってこの年月日時分秒の時刻を示す文字列を「正しい」とするかを判定するメソッドを、自分はこのようにしました
private function validate($target): bool { if (!\is_string($target)) { return false; } return $target === \date('Y-m-d H:i:s', \strtotime($target)); }
- 文字列じゃなかったらダメ
- PHP標準の date 関数・strtotime 関数 で時刻オブジェクト化して文字列フォーマットにした結果が、
元の年月日時分秒の時刻を示す文字列と完全一致してなかったらダメここがミソ(と思っているところ)
- 標準関数のみで実装
- 便利な Carbon クラスを敢えて使っていない
- 例外処理を利用することを避けている
- 必要以上のことを積んで重くするレイヤーじゃないと思って
結果
間違ってるよ、とはじくようになりました
一方で、正しいものを意図通りに結果を出すのもOKまとめ(というか自分の結論)
- ありがたく用意されているものでも、期待されている結果が得られるかを確かめたうえで使うのが良さそう
- 何が「正しい」のかを考えるのは、とても良い頭の体操になる
- 便利な高水準のオブジェクトを利用するシーン、プリミティブな比較的低水準の標準関数などを利用するシーンを適切に使い分けることができると楽しい
関連情報
- https://github.com/sogaoh/LaravelPractice (検証に使ったコード・設定一式)
- https://github.com/sogaoh/LaravelPractice/tree/master/server/graphql [schema.graphql ほか]
- https://github.com/sogaoh/LaravelPractice/tree/master/server/app/GraphQL [カスタムScalarクラス含]
- https://github.com/nuwave/lighthouse (Laravel GraphQL Server ソース)
- https://github.com/nuwave/lighthouse/blob/master/src/Schema/Types/Scalars/DateTime.php
- DateTime Scalar は日時文字列として読み取れれば通ってくることをこれ見て確認した
- https://github.com/nuwave/lighthouse/blob/master/tests/Utils/Scalars/Email.php
- 思いがけず、カスタムScalarのサンプルを見つけた...
そして
- 日時・メールアドレスに続き、正しい
電話番号
の判別について、考えている