システム開発 - FTPによるLaravel6からLaravel9へのアップデート

 

Laravel6のセキュリティフィックスも2022年9月3日に期限を迎え、アップデートを検討している方々も多いことでしょう。

2022年9月現在で、Laravelの差審バージョンは、Laravel9です。セキュリティフィックス期限は2024年2月8日とあと2年ちょっとしかありませんが、次のLTSが出ていない以上、これを選択するしかありません。

Laravel 9.x リリースノート

2022年の9月ごろ、数サイトのアップデートを行いました。そのメモですが要点を紹介させていただきます。

手順は下記のとおりです。

  • PHPのアップデート
  • Composer.jsonの変更
  • Handlerクラスの修正
  • TrustProxiesクラスの修正
  • session.phpの書き換え
  • 本番環境へのアップロード
  • 後片付け

PHPのアップデート

Laravel9のphpのバージョンは8.0 - 8.1推奨です。今までLaravel6ではphp7.2 - 8.0がサポート範囲でしたので、既にphp8.0環境にされている方もいらっしゃるかもしれません。

phpのバージョンアップの仕方については、商用サーバーの場合には、各サポートページを参照してください。

弊社のお客様では、CPIを利用している場合が多く、CPIでは.htaccessの書き換えだけで済むので非常に簡単です。php8.0版のphp.iniもコントロールパネルより取得できます。

また、専用サーバーやAWSなどを使用している方は、他のサイトなどを参考にアップデートの方法を参考にしてください。

FHWでは、関連情報として、awsのphpのインストールなど紹介しておりますので、参考になれば幸いです。

composer.jsonの変更

手順的には、Composer.jsonを書き換え、composer updateを行い必要なライブラリを取得します。

現在のcomposer.jsonのバックアップをとり、下記のようなcomposer.jsonファイルを作成します。

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "require": {
        "php": "^8.0",
        "almasaeed2010/adminlte": "~3.2",
        "fruitcake/laravel-cors": "^2.0.5",
        "guzzlehttp/guzzle": "^7.2",
        "jeroennoten/laravel-adminlte": "^3.8",
        "laravel/framework": "^9.0",
        "laravel/sanctum": "^2.14",
        "laravel/tinker": "^2.7",
        "laravel/ui": "^4.0",
        "laravelcollective/html": "^6.3",
        "spatie/laravel-permission": "^5.5"
    },
    "require-dev": {
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^1.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

まずは、artisanファイルのある階層まで移動します。

$ cd /path/to/

環境によりパスは異なると思いますが、cdコマンドを使用します。

全ライブラリのアップデート

下記のコマンドを実行してvendorディレクトリのライブラリをアップデートします。

$ composer update

実行すると次々にライブラリがアップデートされていきます。最後にdump-autoloadが自動的に実行され、composerのautoloadファイル関連が更新されます。

今までは手動で下記のコマンドを実行し、composerの各ファイルを更新する必要がありました。

$ composer dump-autoload

どのバージョンからかは確認していませんが、今後は、composer.jsonファイルにある下記の記述により自動的に行われます。

・・・
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
・・・

今まで手動で行っていたことが追記されており、非常に便利です。

追加のライブラリのインストールとテスト

階層まで移動したら、インストールしたいライブラリを設定し「--dry-run」オプションを付けて実行します。このオプションを使うことで、依存関係だけを確認して、ファイルはインストールされませんので、安心して実行してください。

$ composer require xxxxxx/yyyyy --dry-run

私自身、毎回必ずこれを実行してからインストールを行っています。実行すると下記のように表示されます。

$ composer require xxxxxx/yyyyy --dry-run
Info from https://repo.packagist.org: #StandWithUkraine
Using version ^8.0 for xxxxxx/yyyyy
./composer.json has been updated
Running composer update xxxxxx/yyyyy
Updating dependencies
Info from https://repo.packagist.org: #StandWithUkraine
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking xxxxxx/yyyyy (1.0.0)
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing xxxxxx/yyyyy (1.0.0)
88 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

毎回特に注意してみているのは下記の部分です。

Package operations: 1 install, 0 updates, 0 removals

ライブラリをインストールすると、たまにremove(削除)されるライブラリがあったりして、のちのち混乱することもあります。

また、インストールできなかった場合には、その内容についてエラーがでます。たいていはphpのバージョンが合わなかったり、インストールしている環境にphpモジュールが無かったりする場合です。

phpのバージョンが合わない場合には、既にそのライブラリの更新が行われていない場合もありますので、該当サイトを確認してみることも必要です。

どうしてもそのライブラリを使用したい場合には、お勧めしませんが、Laravel9へのアップデートをあきらめる必要があるかもしれません。できれば、代替ライブラリを探し利用するのが良いと思います。

問題なければ「--dry-run」オプションを消去してインストールを行います。

$ composer require xxxxxx/yyyyy

Handlerクラスの修正

影響が大きいとLaravelのサイトにはあります。こちらはLaravel6 → Laravel7とLaravel8 → Laraval9のアップデート内容です。

Laravel6の記述は下記のようになっています。

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that should not be reported.
     *
     * @var array
     */
    protected $dontReport = [
        \Illuminate\Auth\AuthenticationException::class,
        \Illuminate\Auth\Access\AuthorizationException::class,
        \Symfony\Component\HttpKernel\Exception\HttpException::class,
        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
        \Illuminate\Session\TokenMismatchException::class,
        \Illuminate\Validation\ValidationException::class,
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        return parent::render($request, $exception);
    }

    /**
     * Convert an authentication exception into an unauthenticated response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Auth\AuthenticationException  $exception
     * @return \Illuminate\Http\Response
     */
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        return redirect()->guest(route('login'));
    }
}

これを下記のように書き換えます。

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array<int, class-string<Throwable>>
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }
}

かなり変わっているので、コピペしても良いかもしれません。

TrustProxiesクラスの修正

こちらは、Laravel8 → Laraval9 のアップデートに記載されています。

Laravel6の記述は下記の通りです。

<?php

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array|string
     */
    protected $proxies;

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

下記のように書き換えます。

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array<int, string>|string|null
     */
    protected $proxies;

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers =
        Request::HEADER_X_FORWARDED_FOR |
        Request::HEADER_X_FORWARDED_HOST |
        Request::HEADER_X_FORWARDED_PORT |
        Request::HEADER_X_FORWARDED_PROTO |
        Request::HEADER_X_FORWARDED_AWS_ELB;
}

session.phpの書き換え

こちらは、Laravel6 → Laraval7 のアップデートに記載されています。

このファイルはconfigフォルダ内にあります。下記の部分を書き換えてください。

'secure' => env('SESSION_SECURE_COOKIE', false),
↓
'secure' => env('SESSION_SECURE_COOKIE'),

公式サイトでは、「false」を「null」に書き換えると書いてありますが、Laravel9のクリーンインストールでは、何も設定がありませんでしたので、上記で問題ないかと思います。

設定完了

Laravelの公式サイトでは様々書いてありますが、10サイトくらいのアップデートを行い、上記だけで今のところ問題なく動いています。

環境によっていは必要な設定があるかもしれませんが、今回はここまでの設定で行います。

本番環境へのアップロード

FHWでは、商用サーバーのお客様の運用も多いため、SSHの接続よりも、FTPなどによるファイルのアップロードで対応する場合がほとんどです。

ですので、今回はFTPによるアップロードでの更新方法を紹介したいと思います。

Vendorフォルダのアップロード

Vendorフォルダは、composer updateにより作成されるphpライブラリが入ったフォルダです。ファイルの数もかなり多いため、アップロードに時間がかかります。そこで、事前に本番環境にアップロードしておきます。手順は下記です。

  • 「vendor」と同じ階層に「vendor_new」フォルダを作成
  • 「vendor_new」フォルダにローカルのvendorフォルダの内容をアップロード

何度か上書きしてしまって、エラーを出してしまいました。必ず、新しいフォルダへアップロード行ってください。

必要ファイルのアップロード

いざという時に元の状態に戻したいのであれば、下記のファイルは事前にバックアップをとるか、本番環境上で、各ファイルの後ろに「.old」などを付して、アップロードされた際に上書きされないようにします。

また、ファイルをアップロードした時点で本番サイトでは、エラーが吐きだされることが予想されますので、必要であればメンテナンスモードに変更してください。

アップロードするファイルは下記です。

  • /app/Exceptions/Handler.php
  • /app/Http/Middleware/TrustProxies.php
  • /config/session.php
  • /composer.json(念のため)
  • /composer.lock(念のため)

キャッシュファイルの削除

新しいキャッシュが作成されるよう下記のフォルダ内のファイルを削除します。問題はないはずですが一応「.gitignore」ファイルは削除しないようにしておきます。

  • bootstrap/cacheフォルダ内のphpファイル

これを行わないと表示の際に、「Class 'Facade\Ignition\IgnitionServiceProvider' not found」などのエラーが表示されます。

また余談ですが、下記にもresourceなどキャッシュファイルがありますので、参考になればと思います。

  • /storage/framework/cache/data内の数字フォルダ
  • /storage/framework/views内のphpファイル

vendorフォルダのリネーム

先ほどvendor_newフォルダを作成しました。今度は、現在の「vendor」フォルダを「vendor_old」とし、その後、「vedor_new」を「vendor」フォルダとします。

これでアップデートは完了し、表示されるはずです。

エラーが表示されない場合には、「.env」ファイルの「APP_DEBUG」か「config.debug」の値をtrueにしてエラーを確認します。もしくは、「storage/logs」の「laravel.log」ファイルの内容を確認します。

エラー内容を検索サイトなどで検索すると各種見つけられるはずです。

エラーが出ているということはLaravelは動いているということが分かりますので、疑う場所は限られてきます。

また、何も表示されない場合やInternal Server Errorなどの場合には、htaccessの設定などを疑うか、DBとの接続設定などを見直すのが良いかもしれません。

後片付け

表示が確認できたら、下記を行います。

  • vendor_oldフォルダの削除
  • ファイルアップロードの際に作成した「~.php」ファイル

また、念のためですが、「.env」ファイルの「APP_DEBUG」か「config.debug」の値をfalseにしておくことをお勧めします。

まとめ

今回は、ざっくりとした内容ですが、FTPを使ったLaravel6からLaravel9への一足飛びのアップデートの方法を紹介いたしました。

SSHによる更新などはよく見ますが、FTPを使ったLaravelのアップデート方法として参考になればと思います。

文責:フライング・ハイ・ワークス代表 松田 治人(まつだ はるひと)
会社では、Laravelを中心としたエンジニアとして働いており、これまでに50本以上のLaravelによるWebアプリケーションの構築や東京でホームページ制作をしています。
エンジニアとして弊社で働きたい方、お仕事のご相談など、お待ちしております。

WEBサイト制作のお問い合わせ、お見積り依頼、ご質問は
こちらのお問い合わせフォームよりお願いいたします

メールお問い合わせはこちら

フライング・ハイ・ワークスの紹介

フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。

実績

デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。

また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。

500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください!

東京のホームページ制作・Web制作のお問い合わせ、お見積り依頼、相談、質問は
こちらのお問い合わせフォームよりお願いいたします

メールお問い合わせはこちら