- 投稿日:2019-08-20T23:58:16+09:00
php-master-changes 2019-08-19
今日は arginfo を PHP スタブへ移行する修正があった!
2019-08-19
iNem0o: Add md5 arginfo stubs
- https://github.com/php/php-src/commit/ff7900f551908e43348b10b5dc2ec20267a0ffbd
- md5()、md5_file() の arginfo を PHP スタブへ移行
iNem0o: Add metaphone arginfo stubs
- https://github.com/php/php-src/commit/b7c4d8e8467cdd75f0910618e3cdfcff08ab2a04
- metaphone() の arginfo を PHP スタブへ移行
iNem0o: Add pageinfo arginfo stubs
- https://github.com/php/php-src/commit/8150c65ae4f72545eac40d0374e1d34f215f27bc
- getmyuid() や getmyinode() など、pageinfo の関数の arginfo を PHP スタブへ移行
iNem0o: Add sha1 arginfo stubs
- https://github.com/php/php-src/commit/baeb10d736f45a1ab84df78e65483f732f4fbbca
- sha1()、sha1_file() の arginfo を PHP スタブへ移行
- 投稿日:2019-08-20T18:35:01+09:00
LaravelのEloquentで最初のn件とn件目以降のデータを取得する
- 投稿日:2019-08-20T17:59:51+09:00
VCCW3.x で、PHPのバージョンを5.6にする
結論
// in the client $ sudo add-apt-repository ppa:ondrej/php ### PPAのインストール $ sudo apt-get update $ sudo apt-get upgrade $ sudo apt install php5.6 ### php5.6のインストール $ sudo a2enmod php5.6 ### apacheにphp5.6モジュールを組み込む(有効化) $ sudo a2dismod php7.0 ### apacheからphp7.0モジュールを除去(無効化) これを書いてない記事が多い $ sudo apt-get install php5.6-mysql ### 'Your PHP installation appears to be missing the MySQL extension which is required by WordPress.' エラーへの対処 $ sudo apt-get install php5.6-mbstring ### WP Multibyte Patchあたりが必要としてるっぽい $ sudo service apache2 restart経緯
普段WordPressの開発に、Virtualbox + Vagrant + VCCW3 を使っているのだけど、未だWordPressの本番環境ではPHP5.x上で動かしてるものも少なくなくなくなくなくなくて、できるだけ本番環境に近い開発環境を用意したいものの、VCCW3はUbuntu16.04がベースにあるため、PHPの標準バージョンが7な上に、PHP5.6を標準でサポートしてないという状況のため、もどかしい気持ちになっていた。
手順
PPAを入れる
ペンパイナッポーアッポーではなく、パーソナル・パッケージ・アーカイブのことらしい。Ubuntu公式ではなく、そのユーザーが保守しているパッケージ集で、公式ではサポートしなくなったアプリケーションなどをaptでインストールできるようにしてくれる。
PHP5.6のインストールには、Ondřej Surý氏によるPPAを用いる。
PPAをインストールしたら、リストの更新のためにも、apt-get update
をしておこう。$ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update $ sudo apt-get upgrade # ついでPHP5.6 を入れる
Linux系の環境で、導入されている設定を切り替えるには、いろんな手続きが必要だったりするものだけど、今回はひとまずいきなりPHP5.6を入れても大丈夫のようだ。
PPAを入れることで、PHP5.6のインストールは可能になったのだから、早速入れてしまおう。$ sudo apt-get install php5.6PHP5.6 を apache で使えるようにする。
PHP5.6をインストールしただけではまだ使える状態にはなっていない。というか、apacheが「PHP5.6を使うべき」という認識をしてくれていないのだ。このままでは依然PHP7.0を使い続けてしまう(なぜPHP7.3じゃないんだろう…)
そこで、apacheのモジュールに、PHP5.6モジュールを組み込んで、使えるようにする。ただ、有効にしてapacheをrestartしてみると、実はセグフォるだけで、起動してくれない。理由は「PHP7.0モジュールも組み込まれているから」である。(
$ ls /etc/apache2/mods-enabled/
を見てみると、php5.6.load
とphp7.0.load
の2つが設置されいていることに気づくはずだ)。なので、これの除去もちゃんと行なっておく。$ sudo a2enmod php5.6 ### apacheにphp5.6モジュールを組み込む(有効化) $ sudo a2dismod php7.0 ### apacheからphp7.0モジュールを除去(無効化) これを書いてない記事が多い余談1
調べた限りでは、この
$ sudo a2dismod php7.0
について書かれているサイトがほぼ無くて、結構迷った。実際、a2dismod php7.0
をキーワードに検索して初めて見つけたくらいだ。余談2
本来ならここで、CUIのPHPバージョンも5.6にしておくべきなんだろうが、wp-cliの何かプラグインがPHP5.xでは動かなかった気がするので、一旦保留。ただ、wp-cli経由でWordPress動かしたときに、PHP7.x上でWordPressを処理するのであれば、CUIの方もPHP5.6に変えないといけない気がするなぁ…
PHPからmysqlが
ここでapacheをrestartしてみると、起動はするもののページがちゃんと表示されてくれない、という問題が起こる。画面にはそっけなく
Your PHP installation appears to be missing the MySQL extension which is required by WordPress.
というテキストが表示されるのみだ。
これは、今のPHPモジュールからMySQL拡張が利用できないが故に表示されるようで、実際調べてみると、$ php -m | grep mysql
の結果にmysqlという行がないことに気づく。
一般に、こういうときは$ sudo apt-get install php-mysql
と打って、PHPのmysqlモジュールを入れるべきなのだが、言ってみればこのデフォルトのライブラリは、Ubuntu16.04標準のPHP7.x用のmysqlモジュールを指しているので、これでは解決しない。ちゃんと php5.6用のモジュールを入れてあげよう。$ sudo apt-get install php5.6-mysqlmbstringも大事
普段はあまり有効性を感じないんだけど、まぁ大体の日本語環境では有効化されているプラグインWP Multibyte Patch。別になくても普通に使えるものの、もし自身の環境でこれが有効化されているなら、その内部で mbstring を使っているようなので、これも使えるようにしておく。
上記同様、普通ならphp-mbstring
を入れるので良いのだけど、今回はPHP5.6向けのものが必要なので、php5.6-mbstring
で対応する。$ sudo apt-get install php5.6-mbstringapache2をリロード!
最後に、今まで入れたり変更したりした設定を有効にするため、apache2をリロードする。
リロード方法はいくつかあるが、$ sudo a2enmod php5.6
を実行したときに表示された方法でリロードすることにする。$ sudo service apache2 restartおわりに
いままでずっと「本番はPHP5.xだけど、まぁPHP7.xで動けばだいたい動くでしょ、WordPressは」みたいな雑な考えで逃げ続けていたのだが、WordPressも5.2になって、推奨環境がPHP7.3以上になり、さらに
年末に PHP 7 以降を最低必須バージョンにすることも視野に入れつつ
日本語 « PHP 最低必須バージョンの変更 — WordPressとか公式にかかれていたりするので、そのうちPHP5.6で動くものが減ってくる可能性も考えると、今の構成(WordPressはもちろん、各種プラグインも)がちゃんとPHP5.6で動くかどうか検証しないといけないなーって状況になってきて、ここ数年ちゃんとLinux触ってないながらにいろいろ調べることになったわけなんですが、案外VCCW3でWordPressを開発してる人が少ないのか、これ系の情報があまり見つからないんですよね。いや、WordPressを使う人が、Linuxの環境いじれることの方が珍しいだけなんでしょうけど。
参考サイト/記事
- 投稿日:2019-08-20T15:56:20+09:00
すぐに忘れる phpcs を設定する際に使うコマンド
※phpcsにpathが通っている前提です。
現在使用可能な規約
$ phpcs -i The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1 and PSR12自作ルールの格納ディレクトリを確認
$ phpcs --config-show Using config file: /Users/hoge/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer.conf installed_paths: /Users/hoge/.phpcs # installed_paths: 〜 が自作ルールを入れるフォルダ。自作ルールの格納ディレクトリを指定
# installed_pathsは上書きされるので注意。(この場合 /Users/hoge/.phpcs の指定が消える。) $ phpcs --config-set intalled_paths path/to/standarts/dir
- 投稿日:2019-08-20T08:40:59+09:00
Laravel 5.8 -> 6.0 LTS Upgrade Guide が更新されました!
For those that aren't aware: Laravel 6.0 will be an LTS release. ? #DatEnterprise
— Taylor Otwell ? (@taylorotwell) August 19, 2019こちらのツイートの通り、 Laravel 6.0 は LTS サポートになる予定とのことです。
そして、 Laravel 5.8 から 6.0 へのアップグレードガイドも更新されました(リリースまでもう少し更新が入るかもしれません)。
I've finished my first pass at the Laravel 5.8 -> 6.0 upgrade guide. Pegging upgrade time estimate at about 1 hour. Probably faster for majority of applications. https://t.co/ZqYGWEXp5S ?
— Taylor Otwell ? (@taylorotwell) August 19, 2019以下、要約。
Upgrade dependencies
composer.json の
laravel/framework
の依存を^6.0
にしてcomposer update
をかけます。6.0 から SemVer を採用するので、 7.0 になるまで破壊的変更は含まれない予定となっています。そのため、バージョン指定は
6.0.0~6.x.x
となる^6.0
を指定する形になります。もちろん、このアップグレードがほかの dependencies で対応しているかしっかりと確認する必要があります。これは以前からのアップグレードと同様です。
特に今回は 5.8 から 6.0 へのアップグレードのため、多くのライブラリは
laravel/framework: ^5.6
といった形で依存していて、しっかりとした更新対応が入るまでアップグレード出来ないのではないでしょうか。認可処理
Authorized Resources
$this->authorizeResource(Post::class, 'post');
のような形でリソースコントローラに対してコンストラクタでポリシーを設定している場合、index
メソッドは元々認可をスルーしていましたが、viewAny
メソッドをポリシークラス側に定義しない限り認可で拒否されるように変更になりました。RegisterController
RegisterController の
register
registered
メソッドを上書きしている場合は、親メソッドを呼ぶ必要が出てきました。イベントの発行場所なども変わっているので注意が必要です。Authorization Responses
Illuminate\Auth\Access\Response
クラスが変更になりました。Database
プライマリキー型定義
パフォーマンス最適化のため、
protected $keyType = 'string';
のように、string
系の型をプライマリキーとして保持している場合は、このプロパティを指定する必要が出ました。Email 確認
email/resend
ルーティングがGET
からPOST
に変わりました。そのため、 view 側で CSRF を追加するなどの修正が必要です。ヘルパー
str_plug
やarray_get
などのヘルパー関数が今までsrc/Illuminate/Support/helpers.php
に実装されていましたが、Illuminate\Support\Str
またはIlluminate\Support\Arr
の静的メソッドを使うことが推奨されるようになりました。また、
composer require laravel/helpers
として別パッケージ化されたそれらのメソッドを要求することも可能です。Localization
Lang::trans
はLang::get
に、Lang::transChoice
はLang::choice
にメソッド名が変更になりました。
Lang::get
とLang::getFromJson
は同じ扱いになったので、Lang::getFromJson
ではなくLang::get
を呼ぶことが推奨されるようになりました。
__('foo')
や@lang('foo')
を使っている場合は特に変更は不要ですね。キュー
php artisan queue:work
を今まで呼んだ場合、失敗したジョブを無限に繰り返すようになっていました。今後は 1 度のみ再実行されます。無限に再実行したい場合は--tries=0
を指定します。Input Facade
Input
Facade は削除されました。Input::get
を使っていた場合はRequest::input
を使ってください。Input
はそのままRequest
Facade に置き換え可能です。
他にも規模の小さい破壊的変更がありますが、ごらんのとおり今までと同じレベルの変更度合いですね。安心しました。
今後は 6.0.0 も 6.9.10 も同じコードで利用出来るようになるはずです(セキュリティリリースなど致命的なものは除く)。
また、大体半年置きにメジャーアップデートが行われていましたが、それは継続するようなので、恐らく来年の2月くらいに Laravel 7.0 が出るのではないかと思います。
※上記のリリースノートはまだ途中のものなので、今後他にも破壊的変更が含まれる可能性があることに注意してください。
※上記は要約で省略している部分もあります。
- 投稿日:2019-08-20T03:08:41+09:00
PHP For Beginnersチュートリアル その14 基本的な検索フォームの実装
このシリーズの目的
体系的なwebコーディングの訓練ができるようになるためにPHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために
上記のチュートリアルを進めているのでその備忘録。
内容
今回のチュートリアル
PHP Multi Language Website Tutorial: Create Dynamic Website In 20 Minutes
このチュートリアルでやること
Webサイトの言語切り替えを行えるようになる
成果物
index.php<?php require_once "config.php"; ?> <!DOCTYPE html> <html> <head> <title><?php echo $lang['title'] ?></title> <link rel="stylesheet" type="text/css" href="css/index.css" media="all"> <link rel="stylesheet" type="text/css" href="css/reset.css" media="all"> <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> </head> <body> <nav class="nav navbar navbar-expand-sm bg-dark navbar-dark "> <ul class="navbar-nav"> <li class="nav-item"><a class="nav-link" href="#"><?php echo $lang['home'] ?></a></li> <li class="nav-item"><a class="nav-link" href="#"><?php echo $lang['pricing'] ?></a></li> <li class="nav-item"><a class="nav-link" href="#"><?php echo $lang['contact'] ?></a></li> </ul> </nav> <div class="container"> <div class="row justify-content-center"> <div class="main col-md-6"> <h1><?php echo $lang['title'] ?></h1> <p><?php echo $lang['description'] ?></p> </div> </div> </div> <div class="footer bg-dark"> <a class="footer-link" href="index.php?lang=en"><?php echo $lang['lang_en'] ?> </a>| <a class="footer-link" href="index.php?lang=ja"><?php echo $lang['lang_ja'] ?></a> </div> </body> </html>config.php<?php session_start(); if (!isset($_SESSION['lang'])) $_SESSION['lang'] = "en"; else if(isset($_GET['lang']) && $_SESSION['lang'] != $_GET['lang'] && !empty($_GET['lang'])) { if ($_GET['lang'] == "en") $_SESSION['lang'] = "en"; else if ($_GET['lang'] == "ja") $_SESSION['lang'] = "ja"; } require_once 'languages/'. $_SESSION['lang'] . ".php"; ?>ja.php<?php $lang = array( "title" => "ダイナミック・ウェブサイト", "home" => "トップ", "pricing" => "料金プラン", "contact" => "ご連絡先", "description" => "ようこそ、ダイナミック社のウェブサイトへ", "lang_en" => "英語", "lang_ja" => "日本語" ); ?>en.php<?php $lang = array( "title" => "Dynamic Website", "home" => "Home", "pricing" => "Pricing", "contact" => "Contact", "description" => "This is explanation about my amazing website!", "lang_en" => "English", "lang_ja" => "Japanese" ); ?>手順
1.サーバーにlanguageフォルダを作りそこに言語設定が記載されたPHPファイルを作る。
(ja.php、en.php)
コード見ればわかるように連想配列にキー値の形で記載していく。
今回はen.phpを基準として、それの互換としてja.phpを作るという流れで見てもらえればわかりやすい。2.Session変数を用いて条件分岐させる。
今回はページが読み込まれた時にはWebサイトを英語表記し、あとはGETで切り替えられるようにする。3.HTML要素の切り替えさせたい部分をPHPタグで用いて変数とキーをechoで出力する形に置き換える、詳しくは後述。
今回のコードの注釈
・言語ファイルの作り方
ja.php<?php $lang = array( "title" => "ダイナミック・ウェブサイト", "home" => "トップ", "pricing" => "料金プラン", "contact" => "ご連絡先", "description" => "ようこそ、ダイナミック社のウェブサイトへ", "lang_en" => "英語", "lang_ja" => "日本語" );en.php<?php $lang = array( "title" => "Dynamic Website", "home" => "Home", "pricing" => "Pricing", "contact" => "Contact", "description" => "This is explanation about my amazing website!", "lang_en" => "English", "lang_ja" => "Japanese" ); ?> ?>言語切替させる箇所にそれぞれキーを設定して、そのキーを各言語共通にし、値をそれぞれの言語に合わせる形で書いていく。
そして、HTML要素の該当する部分をecho $lang['キー']の形でPHPタグを用いて置き換えていく。
こうすることで、キーさえ設定してまえばあとは実装したい言語に応じて基準となる言語と対照させてしまえば簡単に多言語に対応させることができるし、例えばページタイトルとメインタイトルには共通してtitleキーを設定することで一括して切り替えを行ったりすることもできる。require_oncerequire_once 'languages/'. $_SESSION['lang'] . ".php";require関数は指定されたパスのファイルを読み込む関数であるが、その派生のrequire_onceはファイルが既に読み込まれていた場合、そのファイルは読み込まないという処理が付随する。
今回はSessionにおいて最初に読み込まれるのはen.phpだということはコード見ればわかるが、ここで例えば英語orEngilishリンクをクリックしたとしても英語表示はそのままだがen.phpは読み込み直されることはない。
つまり、不必要な読み込みが行われないのでそれだけ処理は軽くなるということになる。
パスの指定方法は様々であるが同じ階層にあれば、そのままファイル名を、階層が違う場合は今回のようにパスを指定してファイル名を書く。
翻訳するとlanguageフォルダにある$_SESSION['lang']に代入された文字列.phpファイルを読み込むということになる。
ちなみに、PHPMaillerを使う際にも用いている関数なので、ここまでのチュートリアルを見直してみてほしい。このチュートリアルを終えたら
Sessionについては過去のチュートリアルでも出てきたがここで一旦基本に立ち返って最低でも以下の2つの記事はしっかり理解しておきたい。
PHP $_SESSION(セッション変数)のすべて!【初心者向け基本】
私もそうだがそろそろコードを見れば何が行われているかが、新しい関数などが出てこない時などを除けばおおよそ苦もなく理解できるようになった頃なので、そろそろアルゴリズムを考える上で、コードを書くだけではなく概念の勉強もしていかないといけないと感じる。
- 投稿日:2019-08-20T02:04:23+09:00
PHP For Beginnersチュートリアル その13 コンタクトフォームの練習
このシリーズの目的
体系的なwebコーディングの訓練ができるようになるためにPHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために
上記のチュートリアルを進めているのでその備忘録。
内容
今回のチュートリアル
PHP Tutorial: Create Contact Form & Send an Email With Attachment Using PHPMailer v6
このチュートリアルでやること
・その7 の復習
成果物
sendemail.php<?php $msg = ""; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Except; use PHPMailer\PHPMailer\SMPT; if (isset($_POST['submit'])) { $subject = $_POST['subject']; $email = $_POST['email']; $message = $_POST['message']; if (isset($_FILES['attachment']['name']) && $_FILES['attachment']['name'] != "") { $file = "attachment/". basename($_FILES['attachment']['name']); move_uploaded_file($_FILES['attachment']['tmp_name'],$file); } else $file = ""; mb_language("japanese"); mb_internal_encoding("UTF-8"); require 'vendor/autoload.php'; require 'Mailtrap-config.php'; $mail = new PHPMailer(); // Server $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($email); // $toname = mb_encode_mimeheader("$name", 'ISO-2022-JP', 'B', "\n"); $mail->addAddress(TO); // $mail->addAttachment($attachment); // Content $mail->Subject = mb_encode_mimeheader("$subject", "ISO-2022-JP", "UTF-8"); $mail->Body = mb_convert_encoding("$message","ISO-2022-JP", "UTF-8"); $mail->CharSet = 'ISO-2022-JP'; $mail->Encoding = "7bit"; $mail->addAttachment($file); // Select HTML or NOT $mail->isHTML(true); if ($mail->send()) { $msg = "Your Email has been sent, thank you!"; } else { $msg = "Something wrong happend! Please try again!"; unlink($file);//サーバーに毎回添付したファイルが保存されないようにする。送信先には問題なく添付される。 } } ?> <!DOCTYPE html> <html> <head> <title>PHP Mail Contact Form </title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <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" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <link rel="stylesheet" type="text/css" href="css/index.css"> </head> <body> <div class="container"> <div class="row justify-content-center"> <div class="col-md-6 mail"> <?php if ($msg != "") { echo "$msg <br> <br>"; } ?> <form action="sendmail.php" method="post" enctype="multipart/form-data"> <input class="form-control" type="text" name="subject" placeholder="Subject......"><br> <input class="form-control" type="text" name="email" placeholder="Email......"><br> <textarea class="form-control" name="message" placeholder="What`up?"></textarea><br> <input class="form-control" type="file" name="attachment"><br> <input class="btn btn-primary" type="submit" name="submit" value="Send Email"> </form> </div> </div> </div> </body> </html>変更点
unlink関数を使い、サーバーにユーザー側がアップロードした添付ファイルが残らないようにする。
メールには問題なくて添付されて送られるので問題ない。
また。Bootstrapを用いたフォームなのでテキスト要素にはform-controlクラスを付随。今回のコードの注釈
unlinkunlink($file);指定した引数を削除する。
この場合は$fileには添付ファイルのパスが代入されているので、それを削除するということはそのファイルを削除することになる。