はじめに

この記事は、Laravelを使った開発を行っている方、PHPのバージョン管理に課題を感じている方、または複数のPHPバージョンを使い分けたい方を対象にしています。特に、環境によってPHPのバージョンが異なり、予期せぬエラーに遭遇した経験がある方にはぜひ読んでいただきたい内容です。

この記事を読むことで、LaravelプロジェクトにおけるPHPのバージョン指定がなぜ重要なのか、そしてその具体的な指定方法(Composer、php-fpm、Webサーバー設定など)を深く理解できます。さらに、それらの設定がどのように連携して動作するのかを把握し、安定した開発・運用環境を構築できるようになるでしょう。複数PHPバージョン環境での効率的な管理方法も学ぶことができます。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • PHPの基本的な構文と概念
  • Laravelの基本的なプロジェクト構造とArtisanコマンドの操作
  • Linux/macOSにおけるコマンドラインの基本的な操作
  • Composerの基本的な使い方(パッケージのインストール、更新など)

LaravelとPHPバージョンの密接な関係

Laravelアプリケーションを開発・運用する上で、PHPのバージョン指定は非常に重要な要素です。なぜPHPバージョンを適切に指定し、管理する必要があるのでしょうか。

まず、互換性と安定性が挙げられます。Laravelフレームワーク自体は特定のPHPバージョン範囲をサポートしており、例えばLaravel 9はPHP 8.0以降、Laravel 10はPHP 8.1以降を要求します。これに満たないPHPバージョンで実行しようとすると、構文エラーや未定義の関数呼び出しなど、様々な問題が発生します。また、使用しているComposerパッケージもそれぞれPHPのバージョン要件を持っています。これらの要件をすべて満たすPHPバージョンを選択することが、安定稼働の第一歩となります。

次に、新機能とパフォーマンスです。PHPはバージョンアップごとに新しい言語機能が追加され、大幅なパフォーマンス改善も行われています。新しいPHPバージョンを利用することで、より効率的で高速なアプリケーションを開発できる可能性があります。Laravelもこれに合わせて、新しいPHPの機能を取り入れ、内部最適化を図っています。

最後に、セキュリティとメンテナンスです。古いPHPバージョンは、セキュリティパッチの提供が終了していることが多く、既知の脆弱性が未解決のまま残ってしまうリスクがあります。常にサポートされているPHPバージョンを使用することは、セキュリティを確保し、長期的なアプリケーションのメンテナンスを容易にする上で不可欠です。

このように、開発環境、ステージング環境、本番環境のすべてで一貫したPHPバージョンを使用することは、予期せぬバグの発生を防ぎ、スムーズな開発ワークフローを維持するために極めて重要です。

LaravelにおけるPHPバージョン指定の具体的な方法と管理

ここでは、LaravelプロジェクトにおけるPHPバージョン指定の具体的な方法を、プロジェクトレベルから実行環境レベルまで詳細に解説します。

ComposerによるPHPバージョン指定 (プロジェクトレベル)

LaravelプロジェクトのPHPバージョン指定は、まずcomposer.jsonファイルから始まります。ComposerはPHPの依存関係管理ツールであり、プロジェクトに必要なPHPの最小バージョンや許容範囲を定義できます。

composer.jsonrequire.phpキー

composer.jsonファイルを開くと、requireセクションにphpキーが含まれていることがわかります。

Json
{ "name": "laravel/laravel", "description": "A Laravel application.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "require": { "php": "^8.1", // ここでPHPのバージョンを指定 "guzzlehttp/guzzle": "^7.2", "laravel/framework": "^10.0", "laravel/sanctum": "^3.3", "laravel/tinker": "^2.8" }, "require-dev": { "fakerphp/faker": "^1.9.1", "laravel/pint": "^1.0", "laravel/sail": "^1.18", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^7.8", "phpunit/phpunit": "^10.1" }, "autoload": { "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" } }, "extra": { "laravel": { "dont-discover": [] } }, "config": { "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true, "php-http/discovery": true } }, "minimum-stability": "stable", "prefer-stable": true }

上記の例では、"php": "^8.1" と指定されています。これは、「PHPのバージョン8.1以上、かつ9.0未満」の範囲を要求するという意味です。^ (キャレット) はセマンティックバージョニングに基づいて互換性のある最新バージョンを許可します。

この設定は、composer installcomposer update を実行する際に、現在CLIで実行されているPHPのバージョンがこの要件を満たしているかをComposerがチェックするために使用されます。要件を満たさない場合、Composerはエラーを出力し、依存関係の解決を中止します。

config.platform.phpによるPHPバージョンエミュレーション

特定のPHPバージョンでの動作をシミュレートしたい場合(例えば、開発環境はPHP 8.2だが、本番環境はPHP 8.1で、Composerの依存関係を8.1に合わせて解決したい場合など)、composer.jsonconfigセクションにplatformオプションを追加できます。

Json
{ "config": { "platform": { "php": "8.1.0" // ComposerにPHP 8.1.0として振る舞うよう指示 }, "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true, "php-http/discovery": true } } }

この設定は、Composerが依存関係を解決する際に、あたかも指定されたPHPバージョンで実行されているかのように振る舞うため、特定のPHPバージョンに合わせたcomposer.lockファイルを生成するのに役立ちます。ただし、実際にアプリケーションが動作するPHPバージョンとは異なる可能性があるため、注意が必要です。

実行環境でのPHPバージョン指定 (サーバーレベル)

Composerによる指定はプロジェクトの依存関係を管理しますが、実際にアプリケーションコードを実行するPHPのバージョンは、OSやWebサーバーの設定によって決まります。

CLI (コマンドラインインターフェース) での指定

ターミナルでphp artisan ...のようなコマンドを実行する際に使用されるPHPのバージョンは、環境変数PATHの設定や、PHPバージョン管理ツールによって決まります。

  1. phpコマンドのパス指定: 複数のPHPバージョンがシステムにインストールされている場合、通常は /usr/bin/php/usr/local/bin/php のようにシンボリックリンクが張られています。特定のPHPバージョンを使用したい場合は、フルパスで指定できます。 bash /usr/bin/php8.1 artisan migrate あるいは、環境変数PATHで優先するPHPバージョンへのシンボリックリンクが含まれるディレクトリを指定します。

  2. PHPバージョン管理ツール: 開発環境では、複数のプロジェクトが異なるPHPバージョンを必要とすることがよくあります。このような場合、phpbrewphpenvasdfといったバージョン管理ツールが非常に便利です。

    • phpbrew: 異なるPHPバージョンをコンパイルしてインストールし、簡単に切り替えることができます。 bash phpbrew install 8.1 +default +fpm phpbrew switch 8.1 phpbrew use 8.1
    • asdf: 様々な言語(PHP, Node.js, Rubyなど)のバージョン管理を統一的に行えるツールです。asdf-phpプラグインを使ってPHPを管理します。 bash asdf plugin add php asdf install php 8.1.12 asdf global php 8.1.12 # グローバルで設定 asdf local php 8.1.12 # プロジェクトディレクトリで設定 (優先される) これらのツールを使用すると、プロジェクトディレクトリに.php-versionのようなファイルを作成し、そのディレクトリに入ったときに自動的に指定されたPHPバージョンに切り替えることができます。

Webサーバー (Nginx/Apache) とphp-fpmでの指定

Laravelアプリケーションは通常、Webサーバー(NginxまたはApache)とPHP-FPM(FastCGI Process Manager)を組み合わせて動作します。PHP-FPMは、PHPコードを実行するPHPプロセスのプールを管理し、Webサーバーからのリクエストを処理します。

  1. php-fpmサービスのインストールと起動: 各PHPバージョンごとにphp-fpmサービスをインストールし、起動します。例えば、Ubuntu/Debian系では以下のようになります。 bash sudo apt install php8.1-fpm sudo systemctl enable php8.1-fpm sudo systemctl start php8.1-fpm これにより、php8.1-fpm.serviceが起動し、通常は/var/run/php/php8.1-fpm.sockのようなUnixソケットファイルが生成されます。

  2. Nginxでの設定: Nginxの設定ファイル(通常は/etc/nginx/sites-available/your-laravel-app)内で、fastcgi_passディレクティブを使用して、どのphp-fpmソケットにリクエストを転送するかを指定します。 ```nginx server { listen 80; server_name your-domain.com; root /var/www/your-laravel-app/public; # Laravelのpublicディレクトリ

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    
    index index.php;
    
    charset utf-8;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # ここでPHP 8.1を指定
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    
    location ~ /\.ht {
        deny all;
    }
    

    } ``` この設定では、PHP 8.1のphp-fpmソケットにリクエストが送られます。異なるPHPバージョンを使用したい場合は、対応するソケットのパスに変更します。

  3. Apacheでの設定: Apacheを使用する場合、mod_phpを使うか、mod_fcgidmod_proxy_fcgiとphp-fpmを組み合わせて使います。php-fpmと組み合わせるのが一般的です。 mod_proxy_fcgiを使う場合の設定例: ```apache ServerName your-domain.com DocumentRoot /var/www/your-laravel-app/public

    <Directory /var/www/your-laravel-app/public>
        Options +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # ここでPHP 8.1のphp-fpmを指定
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost/"
    </FilesMatch>
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    

    ``SetHandler`ディレクティブでphp-fpmのソケットパスを指定することで、Apacheがそのphp-fpmサービスを介してPHPスクリプトを実行するようになります。

ハマった点やエラー解決

PHPバージョン指定でよく遭遇する問題とその解決策について説明します。

  1. Composerのエラー「Your requirements could not be resolved... php ^8.1 but your PHP version (7.4.x) does not satisfy that requirement.」

    • 原因: プロジェクトのcomposer.jsonで要求されているPHPバージョン(例: ^8.1)と、現在CLIでcomposerコマンドを実行しているPHPバージョン(例: 7.4.x)が一致していません。
    • 解決策:
      • CLIのPHPバージョンを、プロジェクトの要件に合うように切り替えます(例: asdf local php 8.1.12 または phpbrew use 8.1)。
      • composer.jsonrequire.phpのバージョン指定が誤っていないか確認します。
      • 一時的にComposerのバージョンチェックを無視したい場合は、composer install --ignore-platform-reqsのようなオプションも使えますが、これは非推奨であり、互換性問題を引き起こす可能性が高いです。
  2. Webページが「502 Bad Gateway」または真っ白な画面になる

    • 原因: Webサーバー(Nginx/Apache)がPHP-FPMと適切に通信できていない場合に発生します。
      • 指定したPHPバージョンのphp-fpmサービスが起動していない。
      • Webサーバーの設定ファイルで指定されているphp-fpmのソケットパス(例: /var/run/php/php8.1-fpm.sock)が間違っている、または存在しない。
      • Webサーバーのユーザーがphp-fpmソケットにアクセスする権限がない。
      • PHP-FPMのログにエラーが出力されている。
    • 解決策:
      • sudo systemctl status php8.1-fpm のように、目的のPHPバージョンのphp-fpmサービスがactive (running)であることを確認します。起動していなければ sudo systemctl start php8.1-fpm で起動します。
      • Nginx/Apacheの設定ファイルでfastcgi_passSetHandlerのソケットパスが正しいか、ソケットファイルが実際に存在するかを確認します。
      • php-fpmのログファイル(/var/log/php8.1-fpm.logなど)を確認し、詳細なエラーメッセージを調べます。
  3. CLI (Artisanコマンド) とWebでのPHPバージョンが不一致

    • 原因: CLIでphp -vを実行すると目的のバージョンが表示されるが、ブラウザでLaravelアプリケーションにアクセスすると古いPHPバージョンで実行されている(またはその逆)。
    • 解決策:
      • CLIのPHPバージョンは、PATH環境変数やバージョン管理ツールによって制御されます。php -vで表示されるバージョンを確認してください。
      • Webサーバー(Nginx/Apache)経由のPHPバージョンは、Webサーバー設定で指定されているphp-fpmサービスによって制御されます。Webサーバーの設定ファイル(fastcgi_passなど)を確認し、Webサーバーをリロード/再起動してください。
      • Laravelプロジェクト内にphpinfo()を含むルートを一時的に追加し、ブラウザでアクセスして表示されるPHPバージョンを直接確認することも有効です。
Php
// routes/web.php (一時的なデバッグ用) Route::get('/phpinfo', function () { phpinfo(); });

解決策

上記のエラーを解決するためには、以下の点を確認し、対応することが重要です。

  1. composer.jsonrequire.phpとCLIのPHPバージョンの一致: composer installcomposer updateを実行する際は、常にCLIで実行されるPHPバージョンがcomposer.jsonの要件を満たしているか確認し、必要に応じてasdfphpbrewで切り替えてから実行します。

  2. php-fpmサービスの正常な稼働: Webサーバーから呼び出されるPHPバージョンは、対応するphp-fpmサービスによって提供されます。目的のPHPバージョンのphp-fpmサービスが正常に起動しているか、systemctl statusコマンドで確認し、必要に応じて起動・再起動します。

  3. Webサーバー設定の確認: Nginxのfastcgi_passまたはApacheのSetHandlerが、目的のPHPバージョンのphp-fpmソケットを指しているかを正確に確認します。変更を加えた場合は、Webサーバーを必ずリロード(sudo systemctl reload nginx / sudo systemctl reload apache2)してください。

  4. 権限とログの確認: php-fpmソケットへのWebサーバーのアクセス権限を確認します。また、php-fpmのログファイルとWebサーバーのエラーログを定期的にチェックし、問題の兆候を見逃さないようにしましょう。

これらの手順を踏むことで、LaravelプロジェクトにおけるPHPバージョン不一致による問題を効果的に解決し、安定した開発・運用環境を維持することができます。

まとめ

本記事では、LaravelプロジェクトにおけるPHPバージョン指定と管理の重要性、そして具体的な実践方法について解説しました。

  • composer.jsonでプロジェクトに必要なPHPバージョンを明示的に指定することが、依存関係の解決と互換性確保の第一歩です。
  • CLI実行環境とWeb実行環境(php-fpm)の両方で、プロジェクト要件に合ったPHPバージョンを設定する必要があります。これらが一致しないと、予期せぬエラーが発生します。
  • phpbrewasdfといったPHPバージョン管理ツールの活用により、複数のPHPバージョンを効率的に切り替え、プロジェクトごとに適切な環境を構築できます。

この記事を通して、LaravelプロジェクトのPHPバージョン管理に関する深い知識を得て、バージョン不一致によるトラブルを回避し、安定した開発・運用が可能になることを願っています。

今後は、Dockerを使ったPHP/Laravel開発環境の構築方法や、CI/CDパイプラインにPHPバージョンチェックを組み込む方法についても記事にする予定です。

参考資料