Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rhand's avatar
Level 6

PHP Tinker Display Controller Methods show's data

I wanted to invoke show in the DownloadsController to load the only added downloadable file. So I added a new controller instance and then tried calling the method and id 1. I however seem to not be able to show the downloadable pdf this way


>>> $controller = app()->make('App\Http\Controllers\Admin\DownloadsController');
=> App\Http\Controllers\Admin\DownloadsController {#5043}
>>> app()->call([$controller, 'show'], ['id' => 1]);
Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException with message 'The file "/Users/jasper/code/domain.com/valet/storage/app/" does not exist'

The actual method is this

public function show(Download $download)
{
    $extension = pathinfo(storage_path("app/{$download->path}"), PATHINFO_EXTENSION);

    return response()->download(storage_path("app/{$download->path}"), "$download->name.{$extension}", [
        'Content-Type' => $download->mime,
    ]);
}

What am I missing here?

0 likes
7 replies
bugsysha's avatar

Have you tried app()->call([$controller, 'show'], ['download' => 1])?

2 likes
rhand's avatar
Level 6

@bugsysha I did not, but just did now and

>>> app()->call([$controller, 'show'], ['download' => 1])
TypeError: Argument 1 passed to App\Http\Controllers\Admin\DownloadsController::show() must be an instance of App\Models\Download, int given, called in /Users/jasper/code/domain.com/valet/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php on line 36

When I check for content in the table I do see that Downloads locally currently has one downloadable pdf and that that one has id 1:

>>> use App\Models\Download;
>>> Download::limit(10)->get();
=> Illuminate\Database\Eloquent\Collection {#5096
     all: [
       App\Models\Download {#5095
         id: 1,
         path: "downloads/HmBTtPJgeV0f2LNCjXW8ZeBkP3xvgI6DCIt8i5tp.pdf",
         name: "Grids",
         mime: "application/pdf",
         size: 37480.0,
         active: 1,
         total_downloads: 0,
         created_at: "2020-07-13 04:51:22",
         updated_at: "2020-07-13 04:51:22",
       },
     ],
   }

Simply started out tinkering as I basically wanted to see what data is produced by controller methods and what type of variables are in use so I can Docblock properly and deal with things like At /app/Http/Controllers/Admin/DownloadsController.php, line 77: Cannot call method store() on mixed. referring to to $path at

...
public function store(CreateRequest $request)
{
    /**
      * 
      */
    $path = $request->file->store('downloads');
...

But that got me into learning a whole new set of skills I do not have yet clearly.

devingray_'s avatar

You should mark the comment by @bugsysha as the “best” solution so that this question will have the solved badge which will help others in the community if they run into the same problems

rhand's avatar
Level 6

I cannot get controller > method data yet. @bugsysha 's solution just returns an error currently Devin. I need to understand how I can make that work first. The error

>>> app()->call([$controller, 'show'], ['download' => 1])
TypeError: Argument 1 passed to App\Http\Controllers\Admin\DownloadsController::show() must be an instance of App\Models\Download, int given, called in /Users/jasper/code/domain.com/valet/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php on line 36

does return some clues, but I am not sure yet how to work around it.

devingray_'s avatar
Level 8

That is not to say it won’t work.

The reason for that error is that you have told your show method that it should expect a Download model instance and instead you gave it an integer of 1. So change to this

 app()->call([$controller, 'show'], ['download' => Download::first()])

Where you give the Download::first() instead of 1

Let's look at this as a whole to try get a deeper understanding of this

We have a controller with a method called show()

public function show()
{}

That method accepts a parameter that we have used dependancy injection to link to a Download model instance

public function show(Download $download)
{}

Now we want to get the download data

public function show(Download $download)
{
    echo $download;
}

If we called this function like this

show(1)

We will get an error as 1 is not an instance of Download

But if we did this

$download = Download::first();

show($download);

We will get no error as we have provided a Download model instance

So, now we can call the controller from the container

app()->call([__CONTROLLER__, __METHOD__], __PARAMS__)

And in this case


use App\Http\Controllers\Admin\DownloadsController;
use App\Models\Download;

$download = Download::first();

app()->call([DownloadController::class, 'show'], ['download' => $download])
1 like
rhand's avatar
Level 6

Thanks for the amazing feedback @devingray_ .

>>> use App\Http\Controllers\Admin\DownloadsController;
>>> use App\Models\Download;
>>> $download = Download::first();
=> App\Models\Download {#5093
     id: 1,
     path: "downloads/HmBTtPJgeV0f2LNCjXW8ZeBkP3xvgI6DCIt8i5tp.pdf",
     name: "Grids",
     mime: "application/pdf",
     size: 37480.0,
     active: 1,
     total_downloads: 0,
     created_at: "2020-07-13 04:51:22",
     updated_at: "2020-07-13 04:51:22",
   }
>>> $controller = app()->make('App\Http\Controllers\Admin\DownloadsController');
=> App\Http\Controllers\Admin\DownloadsController {#5105}
>>> app()->call([$controller, 'show'], ['download' => $download])
=> Symfony\Component\HttpFoundation\BinaryFileResponse {#5136
     +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#487},
   }

did work.

Your code worked too except for a warning

>>> app()->call([DownloadsController::class, 'show'], ['download' => $download])
PHP Deprecated:  Non-static method App\Http\Controllers\Admin\DownloadsController::show() should not be called statically in /Users/jasper/code/domain.com/valet/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php on line 36
=> Symfony\Component\HttpFoundation\BinaryFileResponse {#487
     +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#5123},
   }

But responses are the same besides the warning. Both have a Binary File Response and a response headerbag . Both of which I will look into some more as well as all the things I missed... but will keep this thread as it is. Thanks again.

devingray_'s avatar

No problem and yeah that warning is good. You shouldn't call that method statically, but in tinkerwell you have no choice really.

If you did it in code, I would use it something like this

class ExampleController
{

     protected $downloadController; 

     public function __construct(DownloadsController $downloadController) {
          $this->downloadController = $downloadController;
     }

    public function doSomething()
    {
          $download = Download::first();
          $this->downloadController->show($download);
     }

}

1 like

Please or to participate in this conversation.