I'm also p*ssed with this "error". VSCode and Intelephense keep saying Undefined method 'url'
for any Storage::disk('s3')->url('path.ext');
, even knowing that this is the method suggested on the Laravel docs File Storage. For docs specific to 5.8, look here.
Apparently, there's more than one way to handle this and I'm not sure about which one would the proper way to choose without changing the Laravel itself. I'll tell you what I think it's the best, at least to me, since I'm trying to solve the same thing.
Some of the ways suggested outhere, are:
Use the default cloud filesystem, like this:
Storage::cloud()->url('filename.ext');
But I admit I don't like it, since I prefer to specify the disk name. Remember that to use this, you'll have define the cloud
config at config/filesystems.php
, like this: 'cloud' => env('FILESYSTEM_CLOUD', 's3')
. But if there's something that we can learn with the cloud
method, is that it is returning the right type to IDE's when it's reading the code (and we'll use this).
According to the cloud
method above, it returns \Illuminate\Filesystem\FilesystemManager
. So, we can use this to specify it in a variable comment, like this:
/** @var \Illuminate\Filesystem\FilesystemManager $disk */
$disk = Storage::disk('s3');
$url = $disk->url('filename.ext');
Greg mentioned that here. I really like this implementation and I'll probably use this. Remember that you can also always create a method to return that anywhere to avoid repeated code:
/**
* Return the s3 storage disk.
*
* @return \Illuminate\Filesystem\FilesystemAdapter
*/
private function getDisk()
{
return Storage::disk('s3');
}
- Another robust way is to generate the url directly with some more hidden methods Laravel uses under the table:
$s3 = Storage::disk('s3')->getAdapter()->getClient();
$url = $s3->getObjectUrl(env('AWS_BUCKET'), 'filename.ext');
This will probably generate the url even without having to set the filesystem url
at the configs but, as people commented, it may not work to non public s3 directories. And as far as I've tested, if you have url
set at the configs it'll just disconsider it. Personally, after all this reasons, I don't like this.
- There's also another way like extending the facade, but I also don't like and I'll prefer to not publish it here, first because it's too many code for something trivial, second to not recommend it. But of course, if you'd like to deal with this on a centralized way, that maybe the path.
So as you can see, the quicker and clean way nowadays is to use the @var
notation.
Hope someone fixes this in a near future or another better way appears. If anyone knows something better, please let me know in the comments, I'll be more than happy to update it here.
Info related:
If this was helpful, remember to consider accepting the answer or thumbing it up.