$GLOBALS 配列へのアクセスに対し、
多くの制限が適用されるようになりました。
$GLOBALS['var']
のような、
個別の配列要素に対する読み取りや書き込みは、
これまで通り動作します。
$GLOBALS 配列全体への読み取り専用のアクセスも、
引き続きサポートされます。
しかし、$GLOBALS 配列全体への書き込みは、
もはやサポートされなくなりました。
たとえば、array_pop($GLOBALS)
のようなコードは、エラーが発生します。
static 変数を使っているメソッドが継承された (但し、オーバーライドはされていない) 場合、継承されたメソッドは static 変数を親クラスのメソッドと共有するようになりました。
<?php
class A {
public static function counter() {
static $counter = 0;
$counter++;
return $counter;
}
}
class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), 以前のバージョンでは int(1)
var_dump(B::counter()); // int(4), 以前のバージョンでは int(2)
?>
必須の引数の前に、 デフォルト値を持つ引数 を指定した場合、 デフォルト値を持つ引数は常に必須の引数として扱われるようになりました。 これは、 名前付き引数 を使って関数を呼び出した場合でも同様です。 PHP 8.0.0 以降、かつ 8.1.0 より前のバージョンでは、 以下のコードは推奨されない警告を発生させていましたが、 呼び出しは成功していました。 PHP 8.1.0 以降では、 ArgumentCountError がスローされるようになっています。 位置を指定して呼び出した場合でも、同じエラーがスローされます。
<?php
function makeyogurt($container = "bowl", $flavour)
{
return "Making a $container of $flavour yogurt.\n";
}
try
{
echo makeyogurt(flavour: "raspberry");
}
catch (Error $e)
{
echo get_class($e), ' - ', $e->getMessage(), "\n";
}
?>
上の例の PHP 8.0 での出力は、このようになります。:
Deprecated: Required parameter container in example.php on line 3 Making a bowl of raspberry yogurt.
上の例の PHP 8.1 での出力は、このようになります。:
Deprecated: Optional parameter $container declared before required parameter $flavour is implicitly treated as a required parameter in example.php on line 3 ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed
但し、必須の引数の前であっても、
Null を許容する型 を指定するために、
引数にデフォルト値 null
を指定できることに注意して下さい。
その場合でも、その引数は必須であることには変わりありません。
ほとんどの final でない内部メソッドは、
それをオーバライドする際、
互換性がある戻り値の型を宣言することが必須になりました。
そうしない場合、継承が有効かを検証する際に、
推奨されない警告が発生するようになります。
PHP のバージョン間の互換性を保ちたいがために、
戻り値の型を宣言できない場合、
アトリビュート #[ReturnTypeWillChange]
を追加することで警告を抑止できます。
readonly
は予約されたキーワードになりました。しかし、まだ関数名としては使えます。
never
が予約語になりました。
よって、クラスやインターフェイス、
トレイトの名前として使えなくなっています。
名前空間の中であっても同様です。
いくつかの リソース が、object に移行しました。
is_resource()
関数を使って戻り値をチェックしているコードは、
false
を返すことをチェックするコードに置き換えるべきです。
FileInfo 関数は、
fileinfo
リソース ではなく、
finfo オブジェクトを受け取り、
返すようになりました。
FTP 関数は、
ftp
リソース ではなく、
FTP\Connection オブジェクトを受け取り、
返すようになりました。
IMAP 関数は、
imap
リソース ではなく、
IMAP\Connection オブジェクトを受け取り、
返すようになりました。
LDAP 関数は、
ldap link
リソース ではなく、
LDAP\Connection オブジェクトを受け取り、
返すようになりました。
LDAP 関数は、
ldap result
リソース ではなく、
LDAP\Result オブジェクトを受け取り、
返すようになりました。
LDAP 関数は、
ldap result entry
リソース ではなく、
LDAP\ResultEntry オブジェクトを受け取り、
返すようになりました。
PgSQL 関数は、
pgsql link
リソース ではなく、
PgSql\Connection オブジェクトを受け取り、
返すようになりました。
PgSQL 関数は、
pgsql result
リソース ではなく、
PgSql\Result オブジェクトを受け取り、
返すようになりました。
PgSQL 関数は、
pgsql large object
リソース ではなく、
PgSql\Lob オブジェクトを受け取り、
返すようになりました。
PSpell 関数は、
pspell
リソース ではなく、
PSpell\Dictionary オブジェクトを受け取り、
返すようになりました。
PSpell 関数は、
pspell config
リソース ではなく、
PSpell\Config オブジェクトを受け取り、
返すようになりました。
mysqli_fetch_fields()
と
mysqli_fetch_field_direct() は、
max_length を指定すると
常に 0
を返すようになりました。
この情報は、結果セットを繰り返し処理する際に計算できますし、
長さの最大値をとります。
PHP でも以前のバージョンから、
内部的にこれと同じ処理が行われてきました。
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
オプションは、もはや意味をなさなくなりました。
MYSQLI_STORE_RESULT_COPY_DATA
オプションは、もはや意味をなさなくなりました。
mysqli::store_result()
の mode
引数にどんな値を渡しても、
同様に意味がなくなっています。
mysqli::connect() は、
成功時に null
ではなく、true
を返すようになりました。
デフォルトのエラー処理モードが、
"silent" から
"exceptions" に変更されました。
この変更の意味の詳細と、
どのようにこの属性を明示的に設定するかについては、
MySQLi のエラー報告モード
のページを参照して下さい。
以前のバージョンの振る舞いは、
mysqli_report(MYSQLI_REPORT_OFF);
を使うことで再現できます。
mysqli_stmt::execute() を継承したクラスは、 追加でオプションの引数を指定しなければいけません。
INI ディレクティブ mysqlnd.fetch_data_copy が削除されました。 このディレクティブによって、 ユーザーの目に見える形で、振る舞いが変更されるべきではないからです。
EC キーの秘密鍵は、他のキーと同じように PKCS#8 フォーマットでエクスポートされるようになりました。
openssl_pkcs7_encrypt() と openssl_cms_encrypt() は、 デフォルト値が RC2-40 から AES-128-CBC に変更されました。 RC2-40 暗号はセキュアではないと見なされており、 OpenSSL 3 からはデフォルトで有効ではなくなっています。
PDO::ATTR_STRINGIFY_FETCHES
は、bool 型の値を
"0"
や "1"
に変換するようになりました。
以前のバージョンでは、bool は文字列に変換されていませんでした。
PDOStatement::bindColumn()
に
PDO::PARAM_LOB
を指定してコールした場合、
かつ、PDO::ATTR_STRINGIFY_FETCHES
が有効になっていない場合は、
常にストリームに結果をバインドするようになりました。
以前のバージョンでは、
使っているデータベースドライバやバインドが行われるタイミングによって、
文字列にバインドされることもあれば、
ストリームにバインドされることもありました。
結果セットの整数と浮動小数点の値は、
エミュレートされたプリペアドステートメントを使った場合、
文字列ではなく、
ネイティブの PHP の型を使って返されるようになりました。
これは、ネイティブのプリペアドステートメントの振る舞いと一致します。
以前のバージョンの振る舞いは、
PDO::ATTR_STRINGIFY_FETCHES
オプションを有効にすることで再現できます。
結果セットの整数と浮動小数点の値は、
ネイティブの PHP の型を使って返されるようになりました。
以前のバージョンの振る舞いは、
PDO::ATTR_STRINGIFY_FETCHES
オプションを有効にすることで再現できます。
ArrayAccess インターフェイスに準拠するため、 Phar::offsetUnset() と、 PharData::offsetUnset() は bool を返さなくなりました。
version_compare() は、 ドキュメントに書かれていない演算子の省略形を受け入れなくなりました。
htmlspecialchars(),
htmlentities(),
htmlspecialchars_decode(),
html_entity_decode(),
get_html_translation_table() のデフォルト値が、
ENT_COMPAT
から
ENT_QUOTES | ENT_SUBSTITUTE
に変更されました。
これは、'
が
'
にエスケープされるようになるということです。
以前のバージョンでは、'
に対してはエスケープは行われていませんでした。
さらに、不正な UTF-8 文字列は、空文字列を返すのではなく、
Unicode 置換文字に置きかえられるようになっています。
debug_zval_dump() は、
値の前に &
を付加する代わりに、
自身のリファレンスカウントだけでなく、
リファレンスラッパーのリファレンスカウントも表示するようになりました。
これは、PHP 7.0 以降のリファレンスの表現をより正確にモデル化したものです。
debug_zval_dump() は、
インターン化された文字列や、
変更できない配列については、
ダミーのリファレンスカウントではなく、
interned
と表示するようになりました。
SplFixedArray は、 array のように JSON にエンコードできるようになりました。