PHP Velho Oeste 2024

新機能

定数式

数値や文字列リテラルと定数を、これまでのバージョンでは静的な値が想定されていた場面 (定数やプロパティの宣言、関数のデフォルト引数など) で、スカラー式として扱えるようになりました。

<?php
const ONE = 1;
const
TWO = ONE * 2;

class
C {
const
THREE = TWO + 1;
const
ONE_THIRD = ONE / self::THREE;
const
SENTENCE = 'THREE の値は '.self::THREE;

public function
f($a = ONE + self::THREE) {
return
$a;
}
}

echo (new
C)->f()."\n";
echo
C::SENTENCE;
?>

上の例の出力は以下となります。

4
THREE の値は 3

配列も、 const キーワードで定数として定義できるようになりました。

<?php
const ARR = ['a', 'b'];

echo
ARR[0];
?>

上の例の出力は以下となります。

a

... による可変個引数関数

可変個引数の関数 の実装に ... 演算子が使えるようになり、 func_get_args() を使わずに済むようになりました。

<?php
function f($req, $opt = null, ...$params) {
// $params は配列で、残りのすべての引数が含まれます
printf('$req: %d; $opt: %d; パラメータ数: %d'."\n",
$req, $opt, count($params));
}

f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>

上の例の出力は以下となります。

$req: 1; $opt: 0; パラメータ数: 0
$req: 1; $opt: 2; パラメータ数: 0
$req: 1; $opt: 2; パラメータ数: 1
$req: 1; $opt: 2; パラメータ数: 2
$req: 1; $opt: 2; パラメータ数: 3

... による引数のアンパック

配列Traversable オブジェクトを引数リストにアンパックするために、 関数の呼び出し時に ... 演算子が使えるようになりました。 これは、Ruby などの他の言語では splat 演算子と呼ばれることもあります。

<?php
function add($a, $b, $c) {
return
$a + $b + $c;
}

$operators = [2, 3];
echo
add(1, ...$operators);
?>

上の例の出力は以下となります。

6

累乗演算子 **

右から評価する ** 演算子が追加されました。 これは累乗をサポートするものです。さらに、短縮代入演算子 **= も追加されました。

<?php
printf
("2 ** 3 == %d\n", 2 ** 3);
printf("2 ** 3 ** 2 == %d\n", 2 ** 3 ** 2);

$a = 2;
$a **= 3;
printf("a == %d\n", $a);
?>

上の例の出力は以下となります。

2 ** 3 ==      8
2 ** 3 ** 2 == 512
a ==           8

use function および use const

The use 演算子を拡張し、クラスだけではなく関数や定数もインポートできるようになりました。 それぞれ、言語構造 use function および use const を用います。

<?php
namespace Name\Space {
const
FOO = 42;
function
f() { echo __FUNCTION__."\n"; }
}

namespace {
use const
Name\Space\FOO;
use function
Name\Space\f;

echo
FOO."\n";
f();
}
?>

上の例の出力は以下となります。

42
Name\Space\f

phpdbg

PHP は、今や SAPI モジュールとして実装された phpdbg という対話型デバッガーを含みます。 詳細な情報は » phpdbg のドキュメント を参照ください。

デフォルトの文字エンコーディング

エンコーディングに依存する関数 htmlentities()html_entity_decode() そして htmlspecialchars() におけるデフォルトの文字セットとして、 default_charset を利用するようになりました。 iconv (非推奨) や mbstring でのエンコードが設定されている場合は、 default_charset よりもそちらのほうが優先されます。

この設定のデフォルト値は UTF-8 です。

php://input が再利用可能に

php://input が再オープンできるようになり、必要に応じて何度でも読めるようになりました。 その結果として、POST されたデータを読むときに必要となるメモリの量が大幅に削減されました。

巨大なファイルのアップロード

2 ギガバイトより大きいサイズのファイルもアップロードできるようになりました。

GMP での演算子オーバーロードのサポート

GMP オブジェクトが、 演算子のオーバーロードやスカラー型へのキャストに対応するようになりました。 GMP を使って、よりわかりやすいコードが書けるようになります。

<?php
$a
= gmp_init(42);
$b = gmp_init(17);

if (
version_compare(PHP_VERSION, '5.6', '<')) {
echo
gmp_intval(gmp_add($a, $b)), PHP_EOL;
echo
gmp_intval(gmp_add($a, 17)), PHP_EOL;
echo
gmp_intval(gmp_add(42, $b)), PHP_EOL;
} else {
echo
$a + $b, PHP_EOL;
echo
$a + 17, PHP_EOL;
echo
42 + $b, PHP_EOL;
}
?>

上の例の出力は以下となります。

59
59
59

hash_equals() による、タイミング攻撃に対応した文字列比較

hash_equals() 関数が追加されました。 この関数は、二つの文字列の比較を一定の時間で行います。 タイミング攻撃を防ぐために、文字列の比較にはこの関数を使うべきです。 たとえば crypt() のパスワードハッシュをチェックしたりするときに使えます (password_hash()password_verify() が使えない場合を想定。 これらの関数は、タイミング攻撃の影響を受けません)。

<?php
$expected
= crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct));
var_dump(hash_equals($expected, $incorrect));
?>

上の例の出力は以下となります。

bool(true)
bool(false)

__debugInfo()

マジックメソッド __debugInfo() が追加されました。 var_dump() でオブジェクトの情報を出力する際の、 プロパティやその値の表示方法を変更できます。

<?php
class C {
private
$prop;

public function
__construct($val) {
$this->prop = $val;
}

public function
__debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}

var_dump(new C(42));
?>

上の例の出力は以下となります。

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

gost-crypto ハッシュアルゴリズム

ハッシュアルゴリズム gost-crypto が追加されました。 これは GOST ハッシュ関数を実装したもので、 » RFC 4357, section 11.2 に記載されている CryptoPro S-box テーブルを使っています。

SSL/TLS の改良

PHP 5.6 では、SSL/TLS のサポートに幅広い改良が加わりました。 ピア検証にデフォルトで対応したり、 証明書のフィンガープリントのマッチングに対応したり、 TLS 再ネゴシエーションアタックの対策をしたり、多数の SSL コンテキストオプションを新たに導入したりしました。 これらによって、暗号化されたストリームに関するよりきめ細やかな制御ができるようになりました。

変更内容の詳細を、 PHP 5.6.x における OpenSSL 関連の変更 にまとめました。

pgsql の非同期サポート

pgsql 拡張モジュールが、 非同期の接続や問い合わせに対応しました。 PostgreSQL データベースとのやりとりで、ノンブロッキング処理ができるようになります。 非同期接続を確立するには、定数 PGSQL_CONNECT_ASYNC を利用します。そして、新しい関数 pg_connect_poll()pg_socket()pg_consume_input()pg_flush() を使って、非同期接続や問い合わせを処理します。

add a note add a note

User Contributed Notes 7 notes

up
164
tr0y
10 years ago
It is also possible ( in 5.6.0alpha ) to typehint the ...-operator

function foo (stdclass ... $inbound) {
   var_dump($inbound);
}

// ok:
foo( (object)['foo' => 'bar'], (object)['bar' => 'foo'] );

// fails:
foo( 1, 2, 3, 4 );
up
36
Anonymous
9 years ago
Remember, that

    ($a ** $b) ** $c === $a ** ($b * $c)

Thats why exponent operator** is RIGHT associative.
up
40
ashnazg at php dot net
9 years ago
Note the order of operations in that exponentiation operator, as it was opposite of what my first expectation was:

<?php
// what I had expected,
// evaluating left to right,
// since no parens were used to guide the order of operations
2 ** 3 ** 2 == 64; // (2 ** 3) ** 2 = 8 ** 2 = 64

// the given example,
// which appears to evaluate right to left
2 ** 3 ** 2 == 512; // 2 ** (3 ** 2) = 2 ** 9 = 512
?>
up
7
ciachn
9 years ago
Having 2 ** 3 ** 2 = 512 is actually that is the exact correct behavior for a right-associative operator just as specified in the "**" documentation.
up
12
gmblar+php at gmail dot com
10 years ago
<?php

function array_zip(...$arrays) {
    return
array_merge(...array_map(NULL, ...$arrays));
}

$a = array(1, 4, 7);
$b = array(2, 5, 8);
$c = array(3, 6, 9);

var_dump(implode(', ', array_zip($a, $b, $c)));

// Output
string(25) "1, 2, 3, 4, 5, 6, 7, 8, 9"
up
-1
stocki dot r at gmail dot com
3 years ago
You can create a self-documented, named argument workaround in PHP 5.6-7 with ... operator:

<?php
htmlspecialchars
($string, ...array_values([
   
'flags'         => ENT_COMPAT | ENT_HTML401,
   
'encoding'      => 'UTF-8',
   
'double_encode' => false,
]))
?>
up
-7
BernieV
4 years ago
The splat operator (...) is documented everywhere with no space after it.
But it seems to work just as well with whitespace between ... and what follows.
My IDE line-wrapped, introducing white-space, immediately after the ...
To Top