PHP 8.1以降で発生する「Passing null to parameter of type string」の修正方法

beginner🐘 PHP2026-06-24| PHP 8.1, 8.2, 8.3 (Linux (Ubuntu/Debian), Nginx/Apache, または Docker コンテナ)

Error Message

Deprecated: str_replace(): Passing null to parameter #1 ($search) of type array|string is deprecated in /var/www/html/app.php on line 42
#php81#非推奨#nullハンドリング#php移行#バックエンド

クイックフィックス

PHP 8.1以降のバージョンでは、string型を期待する内部関数にnullを渡すことができなくなりました。これを即座に解決するには、Null合体演算子(?? '')を使用して、常にデフォルトの空の文字列が提供されるようにします。

// ❌ 以前のコード(Deprecated警告が発生します)
$output = str_replace($search, $replace, $subject);

// ✅ 推奨:Null合体演算子
$output = str_replace($search ?? '', $replace ?? '', $subject ?? '');

// ✅ 代替案:明示的なキャスティング
$output = str_replace((string)$search, (string)$replace, (string)$subject);

ログが突然肥大化する理由

PHP 8.1へのアップグレードには、厄介な驚きが伴うことがよくあります。それは、エラーログが1日で数百メガバイトも膨れ上がることです。以前のPHPはかなり寛容でした。strlentrimのような関数にnullを渡しても、PHPはそれを暗黙的に空の文字列に変換していました。これは便利でしたが、データロジックにおける潜在的なバグを隠していました。

PHPのインターナルチームは現在、型安全性に対する制限を強化しています。これらのパラメータにnullを渡すことは公式に非推奨(deprecated)となりました。現在はまだコードは動作しますが、PHP 9.0ではこれらがTypeError例外になる可能性が高いです。そうなると、単にログファイルが埋まるだけでなく、アプリケーション全体がクラッシュする原因になります。

おそらく、次のような特定のエラーパターンが表示されているはずです。

Deprecated: str_replace(): Passing null to parameter #1 ($search) of type array|string is deprecated in /var/www/html/app.php on line 42

よくあるシナリオ

1. Nullを許容するデータベースカラム

これが主な原因です。例えば、middle_nameカラムがNullを許容するユーザープロファイルを取得する場合を考えてみましょう。ユーザーにミドルネームがない場合、データベースドライバーはnullを返します。それを直接文字列関数に渡すと、警告がトリガーされるようになります。

$user = $db->fetch("SELECT middle_name FROM users WHERE id = 123");
// カラムがNULLの場合、この行で警告が発生します:
echo strlen($user['middle_name']); 

2. 予測不可能なAPIペイロード

外部APIはデータの一貫性がないことで有名です。JSONフィールドがあるレスポンスでは文字列であっても、次のレスポンスではnullになることがあります。コードがそのフィールドを常に文字列であると想定している場合、高トラフィック時に本番環境のログがすぐに非推奨の通知で埋め尽くされてしまいます。

3. 任意のフォーム入力

フレームワークによっては、空のフォーム入力をnullに正規化することがあります。検索フィルターや任意の略歴(bio)フィールドを型のチェックなしで処理すると、すぐにこの非推奨化の壁に突き当たることになります。

実践的な修正方法

方法1:Null合体演算子

?? ''を使用するのが、最もクリーンで読みやすい解決策です。これは他の開発者に対して、「文字列を期待していますが、データがない場合は空として扱います」と明示的に伝えます。

// 安全で簡潔
$slug = strtolower($title ?? '');

方法2:明示的な文字列キャスティング

キャスティングは、大規模なリファクタリングに適した「力技」のアプローチです。数千行に及ぶレガシーコードに対してグローバルな検索・置換を行う場合に特に便利です。PHPでは、(string)nullは常に""として評価されます。

$description = trim((string)$data->description);

方法3:モデルレベルでの修正

LaravelのEloquentのようなORMを使用している場合は、データソース側で変換を処理します。これにより、ビジネスロジックにnullが到達するのを防ぐことができます。Attributeを使用して、アクセス時に値が常に文字列であることを保証します。

// Laravelの例:文字列の返却を保証する
protected function biography(): Attribute
{
    return Attribute::make(
        get: fn (?string $value) => $value ?? '',
    );
}

コードベース内の問題箇所の特定

ユーザーがあらゆるコードパスを実行するのを待つ必要はありません。grepを使用してソースディレクトリ内の一般的な文字列関数を検索することで、これらの問題をプロアクティブに見つけることができます。

grep -rnE "(str_replace|strlen|trim|explode|strpos)" ./src

より堅牢なソリューションとしては、PHPStanを使用してください。静的解析ツールは、Nullを許容する変数がNullを許容しない関数パラメータに渡されているすべての箇所を特定できます。これは手動で検索するよりもはるかに安全です。

# PHPStanのインストール
composer require --dev phpstan/phpstan

# レベル5以上で解析を実行
vendor/bin/phpstan analyse src --level 5

修正の検証方法

変更を適用したら、警告が消えたことを確認してください。設定でエラーを非表示にするだけなのは一時しのぎの応急処置であり、解決策ではありません。

  • 開発環境で完全なエラーレポートを有効にする:error_reporting(E_ALL);
  • 自動テストスイートを実行するか、影響を受けるページを手動でトリガーする。
  • PHP-FPMまたはApacheのエラーログを監視する(例:tail -f /var/log/php-fpm.log)。
  • コードの実行時に新しい「Deprecated」エントリが表示されないことを確認する。

Related Error Notes