1 of 16

思い出すシリーズ:

非推奨になった PHP の構文

株式会社あつまる ミツイ

2 of 16

はじめまして、PHP 5.3 を書いているミツイです

  • 株式会社あつまる
    • 集客や採用のコンサルティングの会社
    • 集客に関連するツールの開発を内製してます
    • エンジニア募集中 (東京・福岡)
  • ミツイ
    • あつまるのテックリード
    • PHP 5.3 のサーバーが降ってくることが�稀によくある
    • さすがに PHP 4 は2年以上 触ってない

3 of 16

はじめに: 絶対に勘違いしてほしくないこと

  • PHP 5 のサポートは 2017 年だか 2018 年だかに終了しています
  • 本 LT は PHP 5 の使用を推奨するのもではありません
  • とはいえ、 PHP 5.3 の案件が降ってくることあるよねー
  • (あるあるネタ)
  • (なお納期は2週間)

4 of 16

PHP 8 リリースおめでとうございます!

200%成長

5 of 16

match 式 いいなー

$num = "0";

​

echo match($num, array(

array(0, "is zero\n"),

array("0", false, "is not zero\n"),

), "who?");

​

​

function match($x, $cond, $default)

{

foreach ($cond as $rules) {

$return = array_pop($rules);

​

foreach ($rules as $rule) {

if ($x === $rule) { return $return; }

}

}

​

return $default;

}

5分で書いたオレオレ match 式関数

6 of 16

名前付き引数 いいなー

public function __get($name)

{

return $this->__call($name);

}

​

public function __call($name, array $arguments = array())

{

try {

if (method_exists($this, "_{$name}")) {

$coimpleted_args = $this->__args_completion($name, $arguments);

​

return call_user_func_array(

array($this, "_{$name}"),

$coimpleted_args

);

} else if (

function_exists("get_field")

&& in_array($name, $this->advanced_custom_keys, /* $strict = */ true)

) {

// $name が Advanced Custom Fields プラグインで定義されたカスタムフィールドの場合

$advanced_custom_field = Acf::create($this->post_id, $name, $this->param);

​

return call_user_func_array(

array($advanced_custom_field, "get_value"),

$arguments

);

} else if (in_array($name, $this->custom_keys, /* $strict = */ true)) {

// $name が add_post_meta() で定義されたカスタムフィールドの場合

$post_meta = PostMeta::create($this->post_id, $name, $this->param);

​

return call_user_func_array(

array($post_meta, "get_value"),

$arguments

);

} else {

throw new NotSupportKeyException($name);

}

}

// NotSupportKeyException|UnknownCustomKeyException $e と書きたいところだけど

// PHP 7.0 以前には対応していないので下記のような冗長な書き方で我慢する

catch (NotSupportKeyException $e) {

if ($this->__faithful) {

throw $e;

} else {

// 取得を試みた値 $name がその投稿でサポートされていないものだったら

// $name に応じたデフォルト値を返す

// デフォルト値はほとんどの場合 空文字列 "" だが、

// 取得を試みた $name によっては $e->get_default() が

// array() や false だったりするだろう

return $e->get_default();

}

}

catch (UnknownCustomKeyException $e) {

if ($this->__faithful) {

throw $e;

} else {

// 取得を試みた値 $name がその投稿でサポートされていないものだったら

// $name に応じたデフォルト値を返す

// デフォルト値はほとんどの場合 空文字列 "" だが、

// 取得を試みた $name によっては $e->get_default() が

// array() や false だったりするだろう

return $e->get_default();

}

}

// Exception|Error $e と書きたいところだけど

// PHP 7.0 以前には対応していないので下記のような冗長な書き方で我慢する

catch (Exception $e) {

if ($this->__faithful) {

throw $e;

} else {

return "";

}

}

catch (Error $e) {

if ($this->__faithful) {

throw $e;

} else {

return "";

}

}

}

​

public function __isset($name)

{

return $this->offsetExists($name);

}

​

private function __args_completion($name, array $args)

{

$method_name = "_{$name}";

​

if (!method_exists($this, $method_name)) { return array(); }

​

$method_ref = new ReflectionMethod($this, $method_name);

$param_refs = $method_ref->getParameters();

​

​

$param_names = array();

$default_args = array();

foreach ($param_refs as $param_ref) {

$param_name = $param_ref->getName();

$param_name = str_replace("NAME", $name, $param_name); // 仮引数名に 'NAME' が含まれる場合、それを $name で置換したものを真の仮引数名とみなす

​

$param_names[] = $param_name;

$default_args[$param_name] = $param_ref->getDefaultValue();

}

​

$packed_args = $this->__pack_arguments($param_names, $args);

​

​

$merged_param = array_merge($default_args, $this->param, $packed_args);

​

$completed_args = array();

foreach ($param_names as $param_name) {

if (array_key_exists($param_name, $merged_param)) {

$completed_args[] = $merged_param[$param_name];

} else {

throw new RuntimeException("不明な param_name です: name: {$name}, param_name: {$param_name}");

}

}

​

return $completed_args;

}

​

private function __pack_arguments(array $param_names, array $arguments)

{

if (count($arguments) == 0) { return array(); }

​

if (count($arguments) == 1 && is_array($arguments[0])) {

return $arguments[0];

}

​

$param_name_and_argument_pairs = array_map(null, $param_names, $arguments);

​

$packed_args = array();

for ($i = 0, $len = count($arguments); $i < $len; $i++) {

list($param_name, $value) = $param_name_and_argument_pairs[$i];

​

if (!is_null($param_name)) { $packed_args[$param_name] = $value; }

}

​

return $packed_args;

}

5時間くらいかけて書いた

オレオレ名前付き引数マジックメソッド

7 of 16

名前付き引数 いいなー

​

class Foo extends Base

{

function _some_method(

$hoge = "Hoge",

$fuga = "Fuga"

)

{ /* ... */ }

}

// みたいに定義すると

​

$foo = new Foo;

$foo->some_method(array( "fuga" => "fff" ));

// みたいに呼び出せる

8 of 16

途中に: 絶対に勘違いしてほしくないこと

  • 本 LT は PHP 5 の使用を推奨するのもではありません
  • 急に PHP 5.3 案件が降ってくるのを予期して、�PHP 5 のコードベースを保守している人もいるんですよ!
  • (なお納期は2週間)

9 of 16

アジェンダ

  • PHP 8 で “できなくなった” こと
    1. クラス名と同名のコンストラクタ
    2. create_function()
    3. while (list($v, $k) = each($arr)) { ... }
    4. <script language="php">

10 of 16

1. クラス名と同名のコンストラクタ

  • Foo クラスに Foo メソッドを定義しておくと�コンストラクタとして呼ばれる
  • 気の利いたレガシープロジェクトだと下位互換のための�コードが書いてある

class Foo

{

function __construct()

{

if (method_exists($this, "Foo")) { $this->Foo(); }

}

​

function Foo()

{

echo "foo";

}

}

11 of 16

2. create_function()

  • 文字列まみれで無名関数を作ってくれる cool なやつ
  • PHP 5.2 以前は Closure が無かったのでこいつがいる
  • てか、PHP 5.2 以前は Closure が無かったってマジ?!���
  • eval() 使えば逆 polyfill 作れるらしいよ!(やらない)

$sum = create_function('$x,$y', 'return $x + $y;');

​

echo $sum(2, 3); // => 5

12 of 16

3. while (list($v, $k) = each($arr)) { ... }

  • each() は死んだんだ
    • 残しといてもよかったのでは?と思ってしまう
    • いやマジでたまに見るので
  • 素直に foreach () { … } 使おう

while (list($v, $k) = each($arr)) { ... }

// ↓↓↓

foreach ($arr as $k => $v) { ... }

13 of 16

4. <script language="php">

  • <?php … ?> の代わり
  • 7.0.0 の時点で削除済み
  • <script language=”JavaScript”> みたいで可愛い

<h1>

<script language="php">

echo "Hello,world!\n";

</script>

</h1>

14 of 16

むしろ PHP 4 の世界を体験したいと思った人へ

  • PHP 4 の実行環境を求めて、我々は Docker Hub へと向かった
    • が、Docker Hub で配布されているのは PHP 5.4 以降
    • PHP 5.3 すらないとか、何のための Docker か
  • さくらサーバーでさえ2021年2月末で PHP 4.4 提供終了...
  • でも大丈夫!
  • XAMPP があるじゃない!!!!
    • XAMPP = PHPer にとっての実家

15 of 16

むしろ PHP 4 の世界を体験したいと思った人へ

XAMPP v0.9 !!!

2003-07-27 リリース!!!!!

​

これをインストールすると、

PHP 4.3.3 が入るよ!

16 of 16

おわりに: 絶対に勘違いしてほしくないこと

  • 本 LT は PHP 5 の使用を推奨するのもではありません
  • ハッピーな PHP 4 ライフを 👍