PHPの今とこれから2023
PHP Conference Japan 2023
October 8, 2023
廣川 類 (日本PHPユーザ会)
1
自己紹介:ひろかわ るい
◼ PHPのホビーユーザ(1996~)
◼ PHPマニュアルの日本語化
◼ マルチバイト化:mbstringエクステンション
◼ PHPカンファレンス皆勤中!
◼ PHP関連書籍:
➢ PHP徹底攻略
➢ 初めてのPHP(監訳)
2
PHP
76.9%
ASP.NET
6.8%
Ruby
5.5%
Java
4.7%
JavaScript
3.0%
other
3.1%
PHPとは?
◼ PHPは主にWebアプリケーションに使用されるスクリプト言語
◼ 1995年の誕生以来、Webと共に成長、進化
◼ 現場の課題を簡単に解決してくれる便利なツールです
引用: W3Techs.com, 2023/9/21 3
サーバサイド言語のシェア
WordPress
63.0%
Shopify
5.9%
Wix
3.7%
Squarespace
3.0%
Joomla
2.6%
other
21.8%
CMSのシェア
PHPの開発体制
Rasmus Lerdorf
Andi Gutmans
Zeev Suraski
Marcus Boerger
開発アカウント:約2,000名(15名)
コア:約150名(5名)
PHP Group:10名
Nikita Popov
Derick Rethans
https://www.php.net/credits.php
Dmitry Stogov
Pierrick Charron
Jakub Zelenka
Eric Mann
PHP 8.3 RM
PHP財団(PHP Foundation)について
https://thephp.foundation/
https://opencollective.com/phpfoundation
Nikita Popov氏がPHP開発からの離脱を宣言(2021年)
PHP開発者を支援する団体 PHP Foundation 設立(2021年11月)
重要なインフラであるPHPは個人のモチベーションに依存して
開発・維持されており,生活面の保証(支援)がない
◼ OpenCollectiveにより運営され,個人・企業の寄付に基づき,PHP開発者を支援.
◼ 184の団体・企業がサポート,個人のサポートも1,600名以上.
◼ 主要な開発者であるDmitry Stogov 氏ら6名をサポート(2022年)
◼ 追加の開発者を募集(~2023年9月),2024年から活動開始.
PHP開発者のサポートを開始
PHPの歩み
8
2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
8.0
`20/11/26
8.1
`21/11/25
2023
5.5
5.6
5.4
Traits
マルチバイト
ジェネレータ
キャッシュ
デバッガ
7.0
7.1
7.2
7.3
7.4
高速化
スカラー型宣言
戻り値型宣言
プロパティ型宣言
FFI
JIT
union
Fiber
Enum
交差型
PHP 5.3-5.4
現代的な機能導入
PHP7
大幅高速化
PHP8
JIT導入
8.2
`22/11/24
DNF
readonlyクラス
8.3
`23/11/23
クラス定数型
PHPアンケート 2023
9
主に使っているPHPのバージョンを教えてください。
A. PHP 7 (または以前のバージョン)
B. PHP 8.0
C. PHP 8.1
D. PHP 8.2
PHPバージョン分布
W3Techs.com, 2023/9/21
8.2
2.1%
8.1
6.6%
8.0
8.5%
7.4
41.2%
7.3
9.6%
7.2
6.9%
7.1
2.7%
7.0
3.0%
5.x
19.4%
◼ PHP7ユーザ: 63.2% (昨年: 71.6%),PHP 8ユーザ:17.2% (昨年: 4.4%)
◼ PHP 5(EOL)のユーザ: 19.4% (昨年: 23.8%),
PHP 7まで(EOL)のユーザ:82.8% (昨年: 57.2%)
◼ WordPressの推奨環境:PHP >=7.4, MySQL >=5.7/MariaDB >=10.4, HTTPS
10
* https://wordpress.org/about/requirements/
https://wordpress.org/about/stats/
8.2
5% 8.1
11%
8.0
15%
7.4
49%
7.3
7%
7.2
5%
7.1
1%
7.0
2%
5.x
5%
◼ PHPのライフサイクル:3年(バグ修正:2年、セキュリティ修正のみ:1年)
◼ EOL以降はセキュリティ関連の修正も提供されず、非常に危険です
◼ PHP5、PHP 7.0~7.4 は EOLとなっています
◼ 独自パックポート:
PHPリリースサイクル
11
2019 2020 2021 2022 2023 2024 2025
7.1
7.2
7.3
7.4
8.0
8.1
8.2
アクティブサポート セキュリティ修正のみ
2023/10/8
http://php.net/supported-versions.php
EOL 2019/12/1
EOL 2020/11/30
EOL 2021/12/6
EOL 2022/11/28
EOL 2023/11/26
EOL 2024/11/25
EOL 2025/12/8
https://github.com/remicollet/php-src-security
◼ CVE-* ⇒ 速やかな更新が必要
PHPリリース情報
Release 8.0 8.1 8.2 変更
2022/9/29 8.0.24 8.1.11 CVE-2022-31628/31629
2022/10/27 8.0.25 8.1.12 CVE-2022-31630
2022/11/24 8.0.26 8.1.13 8.2.0 PHP 8.2.0 Release, PHP 7.4 EOL (2022/11/25)
2023/1/5 8.0.27 8.1.14 8.2.1 CVE-2022-31631
2023/2/2 8.1.15 8.2.2
2023/2/14 8.0.28 8.1.16 8.2.3 CVE-2023-0662 (DOS when parsing multipart request body)
2023/3/16 8.1.17 8.2.4
2023/4/13 8.1.18 8.2.5
2023/5/11 8.1.19 8.2.6
2023/6/8 8.0.29 8.1.20 8.2.7 CVE-2023-3247
2023/7/6 8.1.21 8.2.8
2023/8/3 8.0.30 8.1.22 8.2.9 CVE-2023-3823/3824
2023/8/31 8.1.23 8.2.10
12
PHP8 JIT: より速く、快適に
AMD Ryzen 7 5700X, Ubuntu 22.04 13
0
0.05
0.1
0.15
0.2
0.25
0.3
0.35
Zend/bench.php strcat(200000)
sieve(30)
nestedloop(12)
matrix(20)
heapsort(20000)
hash2(500)
hash1(50000)
fibo(30)
ary3(2000)
ary2(50000)
ary(50000)
ackermann(7)
mandel2
mandel
simpleudcall
simpleucall
simplecall
simple
PHP 8バージョン間の
実行速度の差は小さい.
PHP8 JIT: より速く、快適に
AMD Ryzen 7 5700X, Ubuntu 20.04 14
0
0.2
0.4
0.6
0.8
1
1.2
1.4
Zend/micro_bench.php $x = $f ? $f : tmp
$x = $f ? $f : $a
$x = $f ?: tmp
$x = $a ?: null
$x = $str[0]
$x = $hash['v']
$x = $GLOBALS['v']
$x = $_GET
$x = TEST
new Foo()
$x = Foo::TEST
$this->f()
empty($this->x)
isset($this->x)
$this->x--
$this->x++
--$this->x
++$this->x
$this->x += 2
$this->x = 0
$x = $this->x
Foo::f()
self::f()
empty(Foo::$x)
isset(Foo::$x)
Foo::$x = 0
$x = Foo::$x
PHP 8バージョン間の
実行速度の差は小さい.
PHP 8.3 改善/変更のポイント
◼ クラス定数の型指定
◼ クラス定数の動的参照
◼ アトリビュートによるオーバーライド指定
◼ PDOでドライバ固有のサブクラスを導入
◼ INIファイルで環境変数参照時のデフォルト値
◼ json_validate()追加
◼ Randomizer関数追加
◼ mb_str_pad()追加
◼ スタティック変数の動的初期化
◼ readonlyでcloneを使用可能に
◼ SQLite3 で例外をデフォルトで使用
◼ 匿名クラスにreadonly属性を指定可能に
◼ class_alias()で内部クラスのエイリアス指定
機能廃止
機能追加
◼ ASSERT_* の一部、assert_options()の廃止
◼ 複数の関数シグニチャの廃止
◼ MT_RAND_PHPの廃止
◼ range()関数の一貫性改善
◼ Date/Time例外の改善
◼ unserialize()処理の改善
◼ array_sum(), array_product() 改善
◼ インクリメント・デクリメント演算子の改善
◼ 負の配列添字の動作改善
◼ スタックオーバーフロー検出の強化
◼ インターフェイス実装時の定数の可視性検証
◼ gc_status() の取得情報増加
機能改善
クラス定数の型指定
16
https://wiki.php.net/rfc/typed_class_constants
◼ クラス定数に型指定ができるようになった
◼ 指定した型以外の値を代入するとエラーになる
class Foo {
const string NAME = “Taro”;
const string NAME2 = 1;
}
Fatal error: Cannot use int as value for class
constant Foo::NAME2 of type string
class Foo {
const NAME = “Taro”;
const NAME2 = 1;
}
PHP 8.2 PHP 8.3
クラス定数の動的参照
17
https://wiki.php.net/rfc/dynamic_class_constant_fetch
◼ クラス定数を変数により動的に参照する
◼ 従来は、constant()関数を使用
◼ 定数以外の変数と同様に参照できるようになった
class Foo {
const NAME = "Taro";
}
PHP 8.2 PHP 8.3
$name = 'NAME';
echo Foo::{$name};
$name = 'NAME';
echo constant("Foo::$name");
アトリビュートによるオーバーライド指定
18
https://wiki.php.net/rfc/marking_overriden_methods
サブクラスで親クラスのメソッド
をオーバーライトして実装
class Foo {
protected function showitem(): void {}
}
class Moo extends Foo {
#[¥Override]
public function show(): void {}
}
Fatal error: Moo::show() has #[¥Override] attribute, but no
matching parent method exists
親クラスのメソッド名・シグニチャ
が変更された
Overrideアトリビュートを指定す
れば、エラーを発生してくれる
PDO: ドライバ固有のサブクラスを導入
19
◼ データベース固有の機能がPDO:sqliteCreateFunction()のようなメソッドとして実装され
ており,見通しが悪い.
✓ ドライバ固有の機能をサポートするPDOのサブクラスを定義
✓ 静的ファクトリメソッドPDO::connect()を追加
✓ 将来的に PDO:sqliteCreateFunction()は廃止される可能性があり、
$db->create_function() で代替される
✓ 注意:$db = new PDO($dsn, …) は従来と同じ動作(DB固有のドライバではない)
https://wiki.php.net/rfc/pdo_driver_specific_subclasses
$db = PDO::connect($dsn, $username, $password, $options);
$db = new PdoSqlite($dsn, $username, $password, $options);
INIファイルで環境変数を参照する際、
デフォルト値を指定可能に
20
◼ PHPでは、INIファイル内で環境変数を参照できる
◼ 指定した環境変数が存在しない場合、INIパーサは空文字列を使用する(!)
◼ PHP 8.3では、環境変数が存在しない場合のデフォルト値を指定できるようになった
session.name = ${SESSION_NAME}
sendmail_from = "${MAIL_FROM_USER}@${MAIL_FROM_DOMAIN}"
session.name = ${SESSION_NAME:-Foo}
sendmail_from = "${MAIL_FROM_USER:-info}@${MAIL_FROM_DOMAIN:-example.com}"
PHP 8.3
var_dump(ini_get('sendmail_from')); string(16) "info@example.com"
Readonly属性のclone対応
21
https://wiki.php.net/rfc/readonly_amendments
◼ Readonlyプロパティ、クラスをディープコピー(clone)すると、エラー発生
◼ __clone()メソッドの中であれば、変更可能に
class Foo {
public function __construct(
public readonly DateTime $bar) {}
public function __clone() {
$this->bar = clone $this->bar;
}
}
$foo = new Foo(new DateTime());
$moo = clone $foo;
Fatal error: Uncaught Error:
Cannot modify readonly property Foo::$bar
class Foo {
public function __construct(
public readonly DateTime $bar) {}
}
PHP 8.2
PHP 8.3
json_validate()関数追加
22
https://wiki.php.net/rfc/json_validate
◼ Json文字列のバリデータ関数を追加
◼ 従来は json_decode() を用いて実装
◼ json_decode() に比べて、変数の生成等を行わないため、メモリ・速度を改善できる
◼ json_decode()とパーサが共通のため、文法上デコード可能であることが保証される
var_dump(json_validate('[1, 2, 3]')); // bool(true)
var_dump(json_validate('{1, 2, 3]')); // bool(false)
ランダマイザ関数追加
23
https://wiki.php.net/rfc/randomizer_additions
$rng = new ¥Random¥Randomizer();
$s = 'AABC’; // A,B,C => 50%, 25%, 25%
print($rng->getBytesFromString($s, 6));
getBytesFromStringメソッドを追加
print($rng->getFloat(1, 2, ¥Random¥IntervalBoundary::OpenOpen));
print($rng->nextFloat()); // [0, 1)
getFloat, nextFloatメソッドを追加
例:AACBBA
print($rng->getFloat(0, 1, ¥Random¥IntervalBoundary::ClosedOpen));
print($rng->getFloat(0, 1)
nextFloat()は以下と等価
mb_str_pad()関数追加
24
https://wiki.php.net/rfc/mb_str_pad
◼ str_pad() はシングルバイト文字のみに対応
◼ マルチバイト文字対応版としてmb_str_pad()関数を追加
var_dump(str_pad('日本語', 10, '_', STR_PAD_RIGHT)); // BAD: string(10) "日本語_"
var_dump(mb_str_pad('日本語', 10, '_', STR_PAD_RIGHT)); // GOOD: string(16) "日本語_______"
例1:埋める文字がシングルバイト
var_dump(str_pad('日本', 10, '_', STR_PAD_RIGHT)); // BAD: string(10) "日本_�"
var_dump(mb_str_pad('日本', 10, '_', STR_PAD_RIGHT)); // GOOD: string(30) "日本________"
例2:埋める文字がマルチバイト
スタティック変数の初期化に変数や
関数の戻り値を使用可能に
25
◼ static変数の初期化は従来固定値のみ。
◼ 変数や関数の戻り値が指定できるようになった。
https://wiki.php.net/rfc/arbitrary_static_variable_initializers
function hello() {
echo "hello() called.";
return 1;
}
function foo() {
static $i = hello();
echo $i++;
}
foo(); // "hello() called." 1
foo(); // 2
Fatal error: Constant expression contains invalid operations
PHP 8.2
SQLite3エクステンションにおける例外
26
◼ SQLite3Exception例外を導入
◼ SQLite3::enableExceptions(true) とすると SQLite3Exception がスローされる
◼ SQLite3::enableExceptions(false) とすると E_DREPRECATEDを発生
◼ PHP 9.0: SQLite3::enableExceptions(true) を標準に
◼ PHP 10.0: SQLite3::enableExceptions() を廃止
https://wiki.php.net/rfc/sqlite3_exceptions
$sqlite = new SQLite3(':memory:');
try {
$sqlite->enableExceptions(true);
$sqlite->exec('create table bar');
} catch (SQLite3Exception $e) {
echo $e::class . ': ' . $e->getMessage();
}
$sqlite = new SQLite3(':memory:');
try {
$sqlite->enableExceptions(true);
$sqlite->exec('create table bar');
} catch (Exception $e) {
echo $e::class.': '.$e->getMessage();
}
Deprecated: SQLite3::enableExceptions():
Use of warnings for SQLite3 is deprecated
range()関数の一貫性改善
27
https://wiki.php.net/rfc/proper-range-semantics
◼ ステップが floatでもintと同じ値の場合は、intとみなす
◼ int|float|string チェックを行う (オブジェクト、リソース、配列を指定した場合はエラー)
var_dump(range(1, 3, 1.0));
var_dump(range("9", "A"));
[1, 2, 3]
[float(1), float(2), float(3)]
PHP 8.2
PHP 8.3
var_dump(range(0, 3, -1)); [float(1), float(2), float(3)]
PHP 8.2
Fatal error: Uncaught ValueError: range()
["9", ":", ";", "<", "=", ">", "?", "@", "A"]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
PHP 8.2
PHP 8.3
PHP 8.3
Date/Time例外の改善
28
https://wiki.php.net/rfc/datetime-exceptions
◼ PHP 8.2:無効な入力に対して、(通常の)例外、エラー、警告を発生
◼ DateException 、DataError を導入、バリデーションチェックの自由度を向上
$date = new DateTimeImmutable();
$i = DateInterval::createFromDateString(‘last Monday of’);
date->sub($i);
try {
$d = new DateInterval("");
} catch (¥DateMalformedIntervalStringException $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
DateMalformedIntervalStringException: Unknown or bad format ()
Fatal error: Uncaught DateInvalidOperationException
PHP Warning: DateTimeImmutable::sub()
PHP 8.2
PHP 8.3
Notice: unserialize()
Unserialize()の改善
29
https://wiki.php.net/rfc/unserialize_warn_on_trailing_data
https://wiki.php.net/rfc/improve_unserialize_error_handling
◼ 有効なシリアル化データの末尾にバイトがついていても受け入れてしまう。
◼ エラー処理整合性を改善
var_dump(unserialize('i:5;i:6;')); // 'i:6;' は不要
Warning: unserialize()
int(5)
PHP 8.2
int(5)
unserialize('foo');
unserialize('O:19:"SplDoublyLinkedList":3:{i:0;i:0;i:1;N;i:2;a:0:{}}');
PHP 8.2
Warning: unserialize()
PHP 8.3
UnexpectedValueException UnserializationFailedException
PHP 9.0
PHP 8.2/8.3
PHP 8.3
インクリメント・デクリメント演算の改善
30
https://wiki.php.net/rfc/saner-inc-dec-operators
◼ 文字列のインクリメントはできるが、デクリメントはできない
$s = "5d9"; var_dump(++$s); // string(3) "5e0"
$s = "5d9"; var_dump(--$s); // string(3) "5d9"
◼ 論理値・null値は整数にキャスト
◼ str_increment()、str_decrement() 関数を導入
◼ 文字列のインクリメント・デクリメントにE_DEPRECATEDを発生
◼ PHP 9.0で非数値文字列は TypeErrorを発生
var_dump(str_increment("5d9")); // string(3) "5e0"
var_dump(str_decrement("5d9")); // string(3) "5d8"
関数マルチシグニチャの廃止
31
https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures
◼ PHPには、引数パターン(シグニチャ)が複数ある関数が存在する。
◼ デバッグ、文書自動作成等に課題があるため、シグニチャを一つに統一する方向。
◼ 必要な場合は、代替関数を用意する。
◼ PHP 8.3:代替関数を作成 ⇒ PHP 8.4:廃止対象に ⇒ PHP 9.0/10.0:廃止
session_set_save_handler(object $sessionhandler, bool $register_shutdown = true): bool
session_set_save_handler(callable $open, callable $close, callable $read, callable $write,
callable $destroy, callable $gc, callable $create_sid = ?, callable $validate_sid = ?,
callable $update_timestamp = ?): bool
function pg_fetch_result(PgSql¥Result $result, mixed $field): string|false|null {}
function pg_fetch_result(PgSql¥Result $result, int $row, mixed $field): string|false|null {}
function pg_fetch_result(PgSql¥Result $result, ?int $row, mixed $field): string|false|null {}
session_set_save_handler(object $sessionhandler, bool $register_shutdown = true): bool
PHP 8.3における廃止項目
32
https://wiki.php.net/rfc/deprecations_php_8_3
◼ PHP 8.3:廃止対象に ⇒ PHP 9.0:廃止
mb_strimwidth('abcde', 0, -1);
mt_srand(0, MT_RAND_PHP);
✓ mb_strimwidth() 負の width を指定
✓ 壊れたメルセンヌツイスター実装を下位互換性のため、残している
負の配列添字の整合性改善
33
◼ 負の配列添え字の動作が正の添え字と異なっていた。
$array = [];
$array[-5] = 'a';
$array[] = 'b';
var_export($array);
PHP 8.2 PHP 8.3
array(-5 => 'a', 0 => 'b') array(-5 => 'a', -4 => 'b')
PHPの将来:新JIT
https://github.com/dstogov/php-src/tree/php-ir
https://github.com/dstogov/ir
◼ IRフレームワークを用いた新しいJIT実装
◼ 利点:
✓ (将来的に)より効率的なコード生成が可能に
✓ 低レベル処理をPHPから分離
✓ 新規CPUのサポートが容易に
◼ 欠点
✓ JITコンパイル速度が落ちる(関数JITの場合)
従来JIT
PHPバイトコード
ネーティブコード
新JIT
PHPバイトコード
中間コード
ネーティブコード
IRフレームワーク
JITコンパイラ
JITコンパイラ
PHP 9.0で採用?
PHPの将来:生成系AI
<?php
require __DIR__.'/vendor/autoload.php';
use Orhanerday¥OpenAi¥OpenAi;
$open_ai_key = '---Please-enter-openai-key';
$open_ai = new OpenAi($open_ai_key);
$prompt = $_POST['prompt'];
$complete = $open_ai->image([
"prompt" => $prompt ." for Facebook Marketing",
"n" => 1, "size" => "256x256",
"response_format" => "url",]);
$response = json_decode($complete, true);
?>
<img src="<?= $response["data"][0]["url"]?>" />
prompt:
https://github.com/devtamin/Simple-AI-Marketing-Tool-with-PHP
“burger”
◼ PHP + 生成系AI ⇒ 対話型アプリケーションの新しい可能性
◼ PHPのコードを書く必要がなくなる可能性も。。。
PHPユーザ相互の情報交換
およびコミュニティの健全な発展
設立趣旨 活動内容
ドキュメント整備
セミナー/イベント
メンバー/スタッフ
国際化
Web/SNS
• PHPユーザ会員と思ったらメンバー
• 運営してみるのも楽しいかも
日本PHPユーザ会
(2000年4月発足)
PHPカンファレンス
36
PHP勉強会
PHP is dead?
PHPは歯ブラシみたいなもの
by Rasmus Lerdorf
日常のニーズに応えるため,
進化し続けている
38
◼ 2023年のPHPカンファレンスは、昨年に続き、対面での開催となります.
◼ 今年も、思う存分お楽しみください!

PHPの今とこれから2023