本記事では、PHP7からPHP8への移行を行う際によく遭遇する警告やエラーを10項目ピックアップし、PHP7とPHP8での差異を踏まえて詳しく解説します。
それぞれのケースについて、実際に発生する可能性のあるエラーコードやサンプルコードを示し、なぜ問題が起きるのか、そしてどのように対応すればよいかを丁寧に説明していきます。
移行時には、これまでエラーにならなかった記述が突然警告を出したり、非推奨な関数が致命的なエラーを引き起こすこともあります。
こうした問題への事前知識は、スムーズなPHP8対応にとって重要です。
よく発生する警告・エラー10選
1. 非対応な型エラー (TypeError) の増加
問題概要
PHP8では型システムが強化され、PHP7まで許容されていた暗黙的な型変換がエラーを投げるようになったケースがあります。
特にstring
を期待する関数へint
を渡したりすると、PHP7では警告止まりだったものがPHP8ではTypeError
として扱われることがあります。
エラー例
Fatal error: Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, int given
サンプルコード (PHP7で警告、PHP8でTypeError)
<?php
// PHP7ではWarning、PHP8ではFatal errorになるケース
$value = 100;
echo strlen($value); // PHP8ではTypeError: strlen() expects a string, int given
対応策
引数を明示的にキャストする、あるいはコード内で型を厳密に管理して正しい型を渡すようにします。
詳細記事
2. Non-nullable型へのnull代入
問題概要
PHP8では、関数やメソッドの引数に対して、non-nullableな型宣言(string
, int
など)をしている場合にnull
を渡すと即エラーが発生します。
PHP7では「nullが来ているがとりあえず通す」という緩さがあったケースも、PHP8では明確なTypeError
になります。
エラー例
TypeError: Argument #1 ($name) must be of type string, null given
サンプルコード
<?php
function greet(string $name) {
echo "Hello, $name!";
}
greet(null); // PHP8でTypeError
対応策
引数がnullになりうる場合は?string
などnullable型を明示的に指定したり、nullが渡らないような事前チェックを行います。
詳細記事
3. 数値演算での非数値文字列操作
問題概要
PHP7では、"10abc"
のような文字列を整数コンテキストで使用すると、先頭の数字を読み取って計算する「緩い」挙動がありました。
PHP8ではこの緩い挙動がDeprecated扱いとなり、将来のバージョンでは完全なエラーに移行するため、Warningが発生します。
エラー例
Deprecated: Automatic conversion of false to array is deprecated
※ こちらは別のケースですが、同様に「曖昧な変換」が非推奨になった旨を示すエラーが出ることがあります。
サンプルコード
<?php
$value = "10abc";
echo $value + 5; // PHP7では15になるが、PHP8では警告付きで非推奨
対応策
計算前に(int)$value
のような明示的キャストを行うか、妥当なバリデーションを行ってから計算処理を行います。
詳細記事
4. 関数呼び出し時の名前空間解釈の厳格化
問題概要
PHP8では名前空間利用時の関数呼び出し解釈がより厳格になっています。
PHP7で動いていたが実際には不明確なネームスペース指定がPHP8で致命的エラーになるケースがあります。
エラー例
Fatal error: Uncaught Error: Call to undefined function SomeNamespace\some_function()
サンプルコード
<?php
namespace SomeNamespace;
some_function(); // PHP7では警告レベル、PHP8では致命的エラー
対応策
ネームスペースを正しく指定し、use
文でのインポートやFQCN(Fully Qualified Class Name)の利用によって明確な関数参照を行います。
5. コンストラクタでの未定義プロパティへのアクセス禁止
問題概要
PHP8では未定義プロパティへアクセスした場合に厳しくエラーが発生します。
PHP7ではNotice程度で済んでいたものが、PHP8ではErrorException
相当の扱いになることがあります。
エラー例
Error: Cannot access uninitialized non-public property MyClass::$prop
サンプルコード
<?php
class MyClass {
private $prop;
public function __construct() {
$this->prop2 = 'test'; // 存在しないプロパティ
}
}
new MyClass(); // PHP8ではエラー
対応策
クラス定義時に正確なプロパティ定義を行い、存在しないプロパティへのアクセスを避けるよう修正します。
6. マジックメソッド内での不適切な戻り値型
問題概要
__toString()
などのマジックメソッドは明確な戻り値型を求めます。
PHP7では暗黙的にstring
へ変換できたケースも、PHP8ではTypeError
を発生させることがあります。
エラー例
Fatal error: Uncaught TypeError: Method MyClass::__toString() must return a string value
サンプルコード
<?php
class MyClass {
public function __toString() {
return 123; // PHP8ではTypeError: stringを返す必要あり
}
}
$obj = new MyClass();
echo $obj;
対応策
__toString()
は必ずstring
型の戻り値を返すように修正します。
7. 可変関数・可変メソッド呼び出しの厳格化
問題概要
可変変数・可変関数呼び出しにおいて、PHP7までは許容されていた曖昧な呼び出しがPHP8でエラーとなる場合があります。
特に($foo)()
のような呼び出しで、$foo
が本来関数名として有効でない場合エラーになります。
エラー例
Fatal error: Uncaught Error: Call to undefined function someVar()
サンプルコード
<?php
$funcName = "non_existent_function";
$funcName(); // PHP8ではFatal error
対応策
関数が存在するかチェックし、存在しない場合は条件分岐で適切な処理を行うか、function_exists()
を使用して安全な呼び出しを行います。
8. 変数のデフォルト値における問題
問題概要
関数引数のデフォルト値として不正な型や存在しない定数を使用すると、PHP7では警告レベルだったものがPHP8ではエラーを発生させるケースがあります。
エラー例
Fatal error: Uncaught Error: Undefined constant "SOME_UNDEF_CONST"
サンプルコード
<?php
function test($val = SOME_UNDEF_CONST) {
return $val;
}
test(); // PHP8でFatal error
対応策
デフォルト値として適切なリテラル値や定義済み定数を使用します。
9. 正規表現関数での戻り値厳格化
問題概要
preg_match()
やpreg_replace()
などの正規表現系関数でエラー発生時の戻り値はPHP7とPHP8で挙動が微妙に異なります。
PHP8では無効なパターンを使用した場合に、より明確なWarningやErrorが発生します。
エラー例
Warning: preg_match(): Compilation failed: unrecognized character after (?< at offset 3
サンプルコード
<?php
$pattern = '/(?<name>[a-z]+/';
$result = preg_match($pattern, "test");
// PHP8ではWarningが発生し、$result = false
対応策
正規表現のパターンが正しいか事前にテストし、エラー時はfalse
が返ることを前提にエラーハンドリングを行います。
10. 内部関数での無効なパラメータ
問題概要
PHPの組み込み関数に無効な引数を与えた場合、PHP7ではWarningで済んでいた箇所が、PHP8ではTypeError
など致命的エラーになることがあります。
エラー例
TypeError: htmlentities(): Argument #1 ($string) must be of type string, array given
サンプルコード
<?php
$data = ["test" => "hello"];
echo htmlentities($data); // PHP8でTypeError
対応策
引数に渡す値が想定された型であることを確認し、配列やオブジェクトを誤って文字列関数へ渡さないようにします。
まとめ
PHP7からPHP8への移行では、より厳格な型チェックや非推奨機能の明確化などが行われた結果、これまで曖昧なコードが動いていた場面でエラー・警告が多発する可能性があります。
しかし、これらは「コードの品質向上」につながる正しい変化とも言えます。
今回紹介した10のよくある警告・エラーは、実際のプロジェクトでも頻出する問題点です。
移行前にこれらのケースを洗い出し、TypeError
の回避、nullableな型の適切な取り扱い、デフォルト値の見直し、正規表現パターンの検証などを行うことで、より安全で堅牢なPHP8コードへと移行することができます。
結果的に、PHP8の新たな仕様に適応したコードはバグを減らし、保守性を高めることにつながるため、移行作業は決して「手間」だけではなく「投資」と考えるべきでしょう。