phpcodeigniter-4

Returning extra data to my request in Filter after upgrading to PHP 8.1


In PHP 7.X I was able to send extra data from my filter to the Controller:

My app uses bearer token authentication via this Filter. If the token is valid I return the original request and include the user's id:

<?php

namespace App\Filters;

use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;


class AuthFilter implements FilterInterface {

    use ResponseTrait;

    public function before(RequestInterface $request, $arguments = null) {
        if ($request->hasHeader('Authorization')) {

            helper('my_cors_helper');
            $frontendBaseUrl = checkFrontendBaseUrl();

            $token = "";
            $token = str_replace(['Bearer ', 'bearer '], "", $request->header('Authorization')->getValue());
            $userModel = new \App\Models\UserModel();
            $user = $userModel->where('token', $token)->first();
            if (!$user) {
                return Services::response()
                    ->setHeader("Access-Control-Allow-Origin", $frontendBaseUrl)
                    ->setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, PATCH, OPTIONS")
                    ->setJSON([ 'message' => "Access denied", "type"=> "ACCESS_DENIDED"])
                    ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
            }

            $userModel->update($user['id'], ['last_activity' => date('Y-m-d H:i:s')]);
            $request->user_id = $user['id'];
            return $request;
        } else {
            return Services::response()
                ->setHeader("Access-Control-Allow-Origin", $frontendBaseUrl)
                ->setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, PATCH, OPTIONS")
                ->setJSON([ 'message' => "Access denied", "type"=> "ACCESS_DENIDED"])
                ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
        }
    }

    public function after(RequestInterface  $request, ResponseInterface $response, $arguments = null) {

    }

}

After switching to PHP 8.1, I'm unable to set the user's id:

$request->user_id = $user['id'];

Because "Creation of dynamic property is deprecated in PHP 8.1"

As a quick fix I modified the Codeigniter\HTTP\Request class - I've introduced a public $user_id property.

I don't like modifying a file inside the Vendor folder, because it is not how you should do it.

What is the correct way please?


Solution

  • One way to don't get deprecation warnings is to extend the the IncomingRequest class:

    <?php
    
    namespace App\HTTP;
    
    use CodeIgniter\HTTP\IncomingRequest;
    
    class MyRequest extends IncomingRequest {
    
        public $user_id;
    
    }
    

    And then set up the custom request in Config\Services.php:

    <?php
    
    namespace Config;
    
    use App\HTTP\MyRequest;
    use CodeIgniter\Config\BaseService;
    use CodeIgniter\HTTP\UserAgent;
    
    class Services extends BaseService {
    
        public static function request(App $config = null, bool $getShared = true) {
            if ($getShared) {
                return static::getSharedInstance('request', $config);
            }
    
            $uri = static::uri();
            $userAgent = new UserAgent();
            $config = $config ?? config('App');
    
            return new MyRequest($config, $uri, 'php://input', $userAgent);
        }
    
    }