avto-dev/roadrunner-laravel

Method Injection send empty Request object

Closed this issue · 16 comments

When I try to use method injection https://laravel.com/docs/7.x/controllers#dependency-injection-and-controllers with Request object, object creates as empty.
For example that code generate exception:
public function getCurrent(Request $request) { $user = $request->user(); $user->id;
Trying to get property 'id' of non-object

But that:
public function getCurrent() { $request = \request(); $user = $request->user(); $user->id;
working well

  • PHP version(s): [e.g. 7.4.3]
  • Package version(s): [e.g. 3.1.0]
  • Laravel version 7.0.8
  • RoadRunner version 1.6.3

I tried to use php-fpm, problem was not repeated, so it's not, a Laravel 7 issue.

also $request->all(); returns emply array

Hello @Alexfilus !

  • Application starts in docker?
  • Which one of Request objects did you use in DI of your controller?
  • Can you show application logs?

I've installed all from your stack and this is my version of controller:

<?php

declare(strict_types = 1);

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;

class TestController extends Controller
{
    /**
     * @param Request $request
     *
     * @return JsonResponse
     */
    public function getCurrent(Request $request): JsonResponse
    {
        return new JsonResponse([
            '$request->id'          => $request->route('id'),
            '$request->user'        => $request->user(),
            '$request->user()->id'  => $request->user()->id,
            'Auth::user()'          => Auth::user(),
            'Auth::user()->id'      => Auth::user()->id,
            'request()->user()'     => request()->user(),
            'request()->user()->id' => request()->user()->id,
            '$request->all'         => $request->all(),
        ]);
    }
}

My route in routes/web.php:

Route::post('/user/{id}', 'TestController@getCurrent')->middleware('auth');

After make request: curl --request POST --url 'https://my_host/user/1 with GET & POST parameters, I receive json response:

{
  "$request->id": "1",
  "$request->user": {
    "id": 1,
    "name": "user name",
    "email": "user email",
    "email_verified_at": "2020-03-12T07:14:45.000000Z",
    "created_at": "2020-03-12T07:14:45.000000Z",
    "updated_at": "2020-03-12T07:14:45.000000Z"
  },
  "$request->user()->id": 1,
  "Auth::user()": {
    "id": 1,
    "name": "user name",
    "email": "user email",
    "email_verified_at": "2020-03-12T07:14:45.000000Z",
    "created_at": "2020-03-12T07:14:45.000000Z",
    "updated_at": "2020-03-12T07:14:45.000000Z"
  },
  "Auth::user()->id": 1,
  "request()->user()": {
    "id": 1,
    "name": "user name",
    "email": "user email",
    "email_verified_at": "2020-03-12T07:14:45.000000Z",
    "created_at": "2020-03-12T07:14:45.000000Z",
    "updated_at": "2020-03-12T07:14:45.000000Z"
  },
  "request()->user()->id": 1,
  "$request->all": {
    "post_key": "post_value",
    "get_key": "get_value"
  }
}

@eldario I have the same problem. In the request helper \request()->all() everything comes. Through DI no $request->all() empty.

Thanx for your example, but no result.

docker + RR v1.6.3 + laravel 7.1.0 + php 7.4.3

@assurrussa Show source of your:

  • controller
  • config/roadrunner.php

I can not reproduce this situation

@eldario

config/roadrunner.php - all your configuration
psr-worker.php - all your configuration

rr.yaml - local dev

http:
  address: 0.0.0.0:8000
  uploads:
    forbid: [".php", ".exe", ".bat"]
  workers:
    command: "php /var/www/app/psr-worker.php"
    pool:
      numWorkers: 1
      destroyTimeout: 3
      maxJobs:  1
rpc:
  enable: true
  listen: tcp://:6000

psr-worker.php -

<?php

declare(strict_types = 1);
\define('RR_WORKER_START', \microtime(true));
\ini_set('display_errors', 'stderr');
require __DIR__.'/vendor/autoload.php';
$worker = new \AvtoDev\RoadRunnerLaravel\Worker(__DIR__);
$worker->start((bool) \getenv('APP_REFRESH')); // If you specify `TRUE`, then the data in `$request->all()` comes as it should.

Controller

<?php

declare(strict_types=1);

namespace App\Http\Controllers\Frontend;

use Illuminate\Http\Request;

/**
 * Class EntityController
 *
 * @package App\Http\Controllers\Frontend
 */
class EntityController extends FrontendController
{

    public function get(Request $request)
    {
        return response([
            \request()->all(),
            $request->all(),
        ]);
    }
|

Response:
image

@eldario I forgot to say that this bug appears when caching routes - php artisan route:cache

@assurrussa try this:

  • publish config/roadrunner.php from package
  • comment RebindHttpKernelListener from BeforeLoopIterationEvent

@eldario Yes, thanks, that helped.

@eldario comment RebindHttpKernelListener helped, thanks.
Docker uses only for database, php installed natively from homebrew. Maybe it's MacOS problem?
MacOS version is 10.14.6.
Something can be broken because of RebindHttpKernelListener?

@assurrussa I checked different options of caching configs/routes, there was no difference.

@Alexfilus My application is up and running. But now I have another problem, during the transition to the 7th Laravel, the speed dropped significantly in this particular package.

I did not use your stack, I can not say anything about this. I have everything in docker now.

@Alexfilus If you threw off the current settings of the application, then you need to increase the values and take measurements

At least:

numWorkers: 4
maxJobs:  16

@Alexfilus @assurrussa issue can be closed?

@tarampampam Everything works for me now. Thanks.

I suggest so far for version 7 comment out by default RebindHttpKernelListener.

Please update to v7.7 and check this issue. https://github.com/laravel/framework/pull/32416/files this PR fix

Please update to v7.7 and check this issue. https://github.com/laravel/framework/pull/32416/files this PR fix

After the current update, it no longer makes sense to comment on RebindHttpKernelListener - everything works fine.