Page 1
諸君とPHPと一級市民
First-class citizen in PHP with you
2017-10-24 PHP勉強会@東京 #phpstudy
公開日:
by USAMI Kenta@tadsan
に東京都渋谷区のGMO Yoursで開催された『PHP勉強会@東京』でライトニングトーク(5分)として発表しました。
First-class citizen in PHP with you
2017-10-24 PHP勉強会@東京 #phpstudy
はじめに
プログラムは様々な要素の組み合せで構成される
様々な要素?
PHPにおいては(ざっくり)、構文(文法), 数字, 文字列, 真理値,配列, リソース, 型, クラス, 関数,オブジェクト, インターフェイス,トレイト, ファイル, 外部API,データベース, HTMLテンプレート…etc.
われわれはいろんなものを組み合せて作る
どうやって?
<?php require 'bootstrap.php';$db = mysqli_connect();$stmt = mysqli_prepare($db, 'SELECT * FROM books');mysqli_stmt_execute($stmt);print '<h1>本の一覧</h1>';print '<ul>';foreach ($stmt as $s){print '<li>'; print $s->name; print ‘</li>';}print '</ul>';
お気付きか
階級制度
いろんなものがある
“第一級オブジェクト(ファーストクラスオブジェクト、first-class object)は、あるプログラミング言語において、たとえば生成、代入、演算、(引数・戻り値としての)受け渡しといったその言語における基本的な操作を制限なしに使用できる対象のことである。ここで「オブジェクト」とは広く対象物・客体を意味し、必ずしもオブジェクト指向プログラミングにおけるオブジェクトを意味しない。”–第一級オブジェクト (最終更新 2017-04-23 19:00:11)
https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88
PHPはどうかな?
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
PHPはどうかな?
明らかに一級市民ではないもの
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
構文
ifをforに変換する…といったことはできない
🤔
神
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
string
int
$s = "string";
echoとかで簡単に画面に出力できる
$a['str'] みたいな感じでキーになれる
あらゆるバイナリ列を格納できる
例: 画像ファイルの中身
$i = 12345;
echoとかで簡単に画面に出力できる
$a[0] みたいな感じでキーになれる
PHP_INT_MINからPHP_INT_MAXの範囲のみ扱える (CPUのアーキテクチャ32bit, 64bitに依存)
上級市民
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
$f =1.1; $l = PHP_INT_MAX + 1;
echoとかで簡単に画面に出力できる
絶対に配列のキーにしてはいけない
エラーにもならずintに化ける
基本的に等値比較(==, ===)してはいけない
$t = true; $f = (1 == 2);
そのままechoなどで出力できない
trueは1に化ける
falseは何も出力されない
配列キーにすると
<?php
if ($i == 1) echo '$iは1です';
$is_success = do_something();if ($is_success) {echo "成功";} else {echo "しっぱい。。。";}
<?php
function is_valid_keyword($key){return in_array($key, ['public', 'private']);}
シリアライズできる
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
$a = array('a', 'b', 'c');$b = range(1, 10);$c = ['name' => $n , 'age' => $y];
ほかの言語の配列や辞書(ハッシュ, 連想配列)とか呼ばれるもの
内容にほかの型の値を含められる
$dt = new DateTime('2112-09-03');
$o = (object)['name' => $n , 'age' => $y];
クラスを実体化したものキャストするとstdClassになる
内容にほかの型の値を含められる
<?php$s = serialize('string');// "s:6:"string";"$a = serialize(['apple', 'orange']);//=> "a:2:{i:0;s:5:"apple";i:1;s:6:"orange";}"
$obj = new stdClass;$obj->name = 'ミク'; $obj->age = 16;
//=> "O:8:"stdClass":2:{s:4:"name";s:6:"ミク";s:3:"age";i:16;}"
変数に代入できる
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
$x2 = function ($n){return $n*2};
ローカル変数として関数を作ることができる
グローバル関数は一度定義すると(同名で)作り直すことはできないが、これは何回でも作って捨てられる!
リソース(何者である何か)
$c = curl_init(); $g = gmp_init();
リソースって一括りにされてるけど互換性はない
http://php.net/resource
resourceは型宣言に書けない
<?php
$f = function ($r) { var_dump($r); };$g = function (resource $r) { var_dump($r); };
$x = fopen('php://temp', 'r');
$f($x);$g($x);
関数や構文を経由して一級市民になれる
階層できること
神配列のキーになれる
貴族簡単に画面に出力できる
上級市民シリアライズできる
一級市民変数に代入できる・引数にできる
関数や構文を経由して一級市民になれる
謎の関数によってアクセスできる
相当がんばらないと操作できない
タイプヒントにcallableって書ける
単なる文字列・配列を紛れやすい
最近は引数で受け渡すときはcallableよりも\Closureがオススメ
PHP 7.1〜 \Closure::fromCallable()これでcallableをClosureに変換できる
<?php
$p = 'printf';$p('%s %s!', 'Hello', $p);
$c = \DateTimeImmutable::class;$dt = new $c;
$m = [$dt, 'format'];echo $m('Y-m-d H:i:s');
<?php
if (is_development()) {$fp = fopen('php://stderr');} else$fp = fopen('/path/to/log.txt');}
$logger = new MyLogger($fp);$logger->write($data);
ここから下は一級市民と呼び難い
😢
謎の関数によってアクセスできる
ローカル変数
compact(), extract()
プロパティ
ReflectionProperty
定数
constant()
もう時間がない
Symfony\VarDumper
PsySH
whoops!
いい感じに表示できる
市民権を拡張しよう
関連リンクがありません。
