Page 1
PHPは何を捨て、
どんな力を手に入れてきたのか
What did PHP give up and what power did it get?
PHP Conference Japan
2019-12-01 #phpcon
公開日:
by USAMI Kenta @tadsan
に東京都大田区蒲田の大田区産業プラザ PiOで開催された『PHPカンファレンス2019』でレギュラーセッション(25分)として発表しました。
PHPは何を捨て、
どんな力を手に入れてきたのか
What did PHP give up and what power did it get?
PHP Conference Japan
2019-12-01 #phpcon
お前誰よ
うさみけんた (@tadsan)
/ Zonu.EXE
これまでのあらすじ
昨日
そもそもPHP自体が レガシーと言われがち
PHPカンファレンス
本日のお題
そもそもPHPというプ ログラミング言語はどん な機能を持っているのか
“We have things like protected properties.
We have abstract methods. We have all
this stuff that your computer science
teacher told you you should be using.
I don't care about this crap at all.”
–Rasmus Lerdorf
https://en.wikiquote.org/wiki/Rasmus_Lerdorf
には プロパティも抽象メ
“PHP protected
ソッドもありますよ。計算機科学の教授が
「使え」と言ってるものは全部。
そんなことはクソ興味ないですけど
”
–Rasmus Lerdorf
僕が思いつくPHPの 機能をざっと挙げて
みると…
抽象クラス, トレイト, インター
フェイス, ジェネレータ, イテレー タ, クロージャ, 函数の動的呼び出 し, 無名クラス, eval, 型宣言, 連 想配列, リフレクションAPI, 自己
文書化, 標準入出力の読み書き,
REPL, クラスの遅延ロード
改めてPHPの言語 仕様が追加された時
系列を見てみよう
PHP 7.4
Arrow functions 2.0
JavaScriptなど
Typed Property
Javaなどの静的型付き言語
Numeric Literal Separator
Ada, Ruby, JavaScriptなど
PHP 7.3
Flexible Heredoc and Nowdoc
Rubyにも似た記法はある
list() Reference Assignment
これはPHP独自に近い
PHP 7.2
Trailing Commas In List Syntax
カンマ(,)を並べて書く記法のほぼ全
てで余分につけてもよくなった
Parameter Type Widening
継承したクラスで引数の型省略
PHP 7.1
Nullable Types
Void Return Type
Multi catch
Allow specifying keys in list()
PHP 7.0
Anonymous Class
Generator Delegation
(yield from)
Return Type Declaration Null Coalesce Operator
Scalar type hints
PHP 5.6
Exponential Operator(pow**)
Importing named function
Variadic function argument (...)
配列を引数として展開
Argument unpacking(...)
可変長引数を配列として取得
PHP 5.5
Generator
finally keyword (try-catch-...) Const array/string dereference Allow non-scalar keys in foreach
PHP 5.4
Traits
Short array syntax
callable type hint
PHP 5.3
Closures (function expression)
関数式、クロージャ、またはラムダ式
JavaScriptのfunctionに似てる が、レキシカルスコープ(変数の捕 捉)のためにuseキーワードが必要
ひとつひとつの機能 の話を語ったら20分
では全然足りない
なので本日はPHPがどう変 わっていったかというエピ ソードを交えてPHPの言語
機能を紹介していきます
さて
がリリー
PHP 7.4.0
スされましたね
本日
12月1日は
何の日でしょう?
27
この数は何でしょう
せいかい
PHP7.4に向けて
受理されたRFCの数
RFC?
RFC
(Request for Comment)
新バージョンへの変更提案 PHPの機能の改廃の提案は
RFCを通じて行われる
提案はメーリングリストで議論 されPHP.net VCSアカウント
の所持者が議決する
PHP RFC
の歴史
2008年頃から機能提案のため
に運用されはじめた
2011年 から正式な
(5.4alpha1)
リリースプロセスになった
“PHP releases have always been
done spontaneously, in a somehow chaotic way. Individual(s) decided
when a release will happen and
what could or could fit in. Release managers role are unclear and the
way to nominate them is not
clearly defined either.”
‒ Request for Comments: Release Process
https://wiki.php.net/rfc/releaseprocess
“PHPのリリースは常に無秩序な方法で自 発的に行われてきました。個々人がいつリ リースされるか、何が起こるか、そして何 が収まるかを決定しています。リリースマ ネージャの役割は不明瞭で、指名の手続き
も明確に定義されていません。”
‒ Request for Comments: Release Process
https://wiki.php.net/rfc/releaseprocess
この時期
(2008〜2010年)
のPHPには
何があったでしょう
この当時のPHP情勢
廣川さんの
「PHPの今とこれから」が 当時の事情の貴重な資料
‒ PHPの今とこれから2009
https://www.slideshare.net/hirokawa/php2009
‒ PHPの今とこれから2009
https://www.slideshare.net/hirokawa/php2009
‒ PHPの今とこれから2009
https://www.slideshare.net/hirokawa/php2009
Unicode化とは どういうことか?
言語処理系の文字列実装
CSI方式
(Code Set Independent)
特定のコードセットに依存しない
UCS正規化方式
(Universal Character Set)
内部的に文字コードを統一し
てから処理する
https://magazine.rubyist.net/articles/0025/0025-Ruby19_m17n.html
言語ごとの文字列実装
CSI方式
Ruby, Python 2, PHP
UCS正規化方式
Java, JavaScript, Perl,
Python 3, PHP6
ざっくりCSI方式
文字列変換をしないので、 オーバーヘッドは最小限
サポートする文字コードごと に文字列処理の実装が要る
ざっくりUCS正規化方式
文字列を変換するので入出力 で変換オーバーヘッドがある 文字列処理は内部文字コード 用のものだけ用意すればいい
PHP6はUTF-16を目指した
UCS正規化方式への移行
従来のPHP文字列はバイト列 PHP 5.2で キャスト
(binary)
と が追加された
b"string"
結局Unicode化しなかった
ので、ただのエイリアス
重要なこと
UCS正規化しないとUnicode サポートできないわけではない UTF-16にしても1コードポイ ント=1文字になるわけではな
い (サロゲートペア)
PHP6.0の顛末
実装は難航し、文字列以外の 6.0向け機能は5.3, 5.4系で
それぞれリリースされた
2010年3月にリポジトリの
trunk(master)が5.3に
ロールバックした
開発が頓挫したPHP6は 欠番としてスキップされ
PHP5.6の次は7.0になっ
たというのは有名な話
(私はこの時代にPHPに 触れておらず議論を詳し
くは追ってないので 想像の域は出ないが)
この時代にPHPはカウボーイ による開発スタイルを捨て、明 文化されたスケジュールとプロ セスによる開発体制に移行した
PHPのリリース計画や メンテナンス期間が定め られたのもこのRFCから
PHP5.3ではPHP6
を待たず重要な
機能がマージされた
‒ PHPの今とこれから2009
https://www.slideshare.net/hirokawa/php2009
遅延静的束縛
static::method();
親クラスの静的メソッドから継承さ れたクラスのメソッドを呼び出す ちなみに 関
forward_static_call()
数のマニュアルには「静的メソッド をコールする」と書いてるが、この 説明は間違い (翻訳の問題ではない)
Dynamic static call
の代りに
Hoge::fuga()
$class="Hoge"; $class::fuga();
で呼べるようになった 静的メソッド版可変関数
名前空間
クラスや関数を階層化できる
名前空間違いの同名のクラス
が作れるようになった
フルネームをFQSENと呼ぶ
useでファイルローカルな別名
を付けることもできる
useの誤解されがちなところ
include/requireのようにファ イルを読み込む機能ではない
ファイル内で呼べるよう
ローカルな名前を付けるだけ 存在しないクラスをuseして
もエラーにはならない
クロージャ (関数式・ラムダ式)
ローカルな関数が作れる
ただの関数を作れるだけでは なく、外側の変数を引き込め
るのが重要 (関数閉包)
普通の関数やメソッドにその
機能はない
クロージャ以前の無名関数
create_function()という関
数で関数式っぽいことはできた その実態はevalで lambda_1 のような関数を動的に定義する
この関数はリスキーなので PHP7.2からdeprecated
PHPのクロージャ
構文上はJavaScriptのものに 似ているが、useで列挙しない と外側の変数を捕捉できない
この仕様にはPHPの変数の 説明しにくい挙動が関わって
いる…
PHPの変数
PHPで変数の値を再代入した
り引数に渡したりすると、
(意味論として)値がコピーされる
クロージャでuseしたときも
PHPでは引数と同じ動きになる &を付けると変数の参照をとる
JavaScriptのクロージャ
make_counter = function() {
i = 0;
return function () {
return i++;
};
};
c1 = make_counter();
console.log(c1()); console.log(c1()); console.log(c1());
PHPのクロージャ
この記述だと$i=0のコピーさ
れるだけ。 &を付けると変数リファ
<?php
レンスで値を更新できる
$make_counter = function() {
$i = 0;
return function () use ($i) {
return $i++;
};
};
$c1 = $make_counter();
var_dump($c1()); //=> 0 var_dump($c1()); //=> 0 var_dump($c1()); //=> 0
最初のRFCクロージャ
実はJavaScript風クロージャ よりも前に短いクロージャが 提案されてた (2008年3月)
RFC: Short syntax for anonymous functions
ただしDraft止まり
‒ PHP: rfc:short-syntax-for-anonymous-functions
https://wiki.php.net/rfc/short-syntax-for-anonymous-functions
‒ PHP: rfc:short-syntax-for-anonymous-functions
https://wiki.php.net/rfc/short-syntax-for-anonymous-functions
時は流れて
2019年
PHP: rfc:arrow_functions_v2
https://wiki.php.net/rfc/arrow_functions_v2
PHP: rfc:arrow_functions_v2
https://wiki.php.net/rfc/arrow_functions_v2
姿形は違うが幾度もの 議論の末に短い記法の
関数式が導入された
ところで
PHP: rfc:arrow_functions_v2
https://wiki.php.net/rfc/arrow_functions_v2
私たちはこの
提案者の名前を
見たことがある!
‒ PHPの今とこれから2012
https://www.slideshare.net/hirokawa/php-now-and-then-
2012-at-php-conference-2012-tokyo-japan
ジェネレータ
(古典的な)コルーチン
「何度も繰り返す」構造を関 数(メソッド)を使って簡単に作
れる
Nikita Popov
近年のPHPの中核的な開発者
PHP5.5以降、非常に多数の言語機能 を実装してPHPに取り入れてきた
PHP-Parserなどの作者
去年の大学院を卒業し今年JetBrains に入社してPhpStormチームに参加
とてもざっくり言うとレガ シー仕様を消し、不条理な 挙動は是正し、他言語にあ るようなカッコイイ機能を
追加提案してきた
不条理な
挙動って?
例: 未定義定数はその文字列になる
echo PHP;
=> 文字列 "PHP" が出力
E_NOTICE/E_WARNING
error_reportingが低い環境 でさりげなく生き残ってた可
能性が高い
歴史的経緯で残ったレ ガシー仕様はさくっと 消しまくっていこうぜ
いいじゃん いいじゃん
📛
🔥
🔥
🔥
🔥
燃えた
Deprecate PHP's short open tags, again
一般的なPHPタグは<?php ... ?> または<?= ... ?> だが、<? ... ?>と
いう形式もある
php.iniで有効無効を切替られる 環境によってOnだったりOffだっ
たり
Deprecate PHP's short open tags, again
XML宣言との相性がとても悪い
そんな半端モンは引導を渡してやろう
ぜ! ということで提案された
構文がシンプルになるし、機械的に変 換もできるから良いだろ、という主旨
Zeevによる
反論
Zeev Suraski
PHP3・4の開発者
相方のAndi Gutmansとともに VM型処理系のZend Engine開発
PHPでよくあるZend…は
ZeevとAndiに由来
PHPコードに未だに影響を残す
さらなる提案
続きは Webで
まとめ
PHPは力を手に入れ ようとして失敗して きた経験が結構ある
現在のPHPは静的解析 できる環境が年々強まっ て往年のざっくりさは息
をひそめつつある
銀河の平和は
どっちだ