Laravel7 Middlewareを使ってJSONの日本語文字化けに対応する

Laravel7 Middlewareを使ってJSONの日本語文字化けに対応する

JSONデータをGETした際に日本語だと文字化けすることがあるので対処法を記述してます。日本語がユニコードでエスケープ されているため発生。

環境

  • OS CentOS Linux release 8.0.1905 (Core)
  • Composer 1.10.5
  • PHP 7.4.5
  • Percona Server Ver 8.0.19-10
  • Laravel Framework 7.6.2

※CentOs8に Laravel のインストールはこちら

文字化け

日本語がユニコードでエスケープ(\uxxx)されているため下記の画像のようになります。

Middleware作成

Unicode( ユニコード )エスケープをさせないため、Middlewareを利用して、エンコードのオプションに「 JSON_UNESCAPED_UNICODE 」を追加してresponseデータを処理します。

middlewareを作成します。

php artisan make:middleware JpJsonResponse

app/Http/Middleware/JpJsonResponse.phpを下記の通りに編集します。

<?php

namespace App\Http\Middleware;

use Closure;
use Symfony\Component\HttpFoundation\JsonResponse;
class JpJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        
        //JSONでない場合はそのまま
        if (!$response instanceof JsonResponse) {
            return $response;
        }

        // Unicodeエスケープさせないようにオプションを追加        
        $response->setEncodingOptions($response->getEncodingOptions() | JSON_UNESCAPED_UNICODE);

        return $response;
    }
}

Kernel追加

作成したmiddlewareをKernelに追加します。
app/Http配下にある「Kernel.php」に下記を追加します。

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,        
        //追加します
        'JpJsonResponse' => \App\Http\Middleware\JpJsonResponse::class,
    ];

あとはControllerの __constructに追加して利用します。

class TaskController extends Controller
{
  //追加
    public function __construct()
    {
        $this->middleware('JpJsonResponse');
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $tasks = Task::all();
        return $tasks;
    }

文字化けが解消されていることが確認できます。