در حال بارگذاری ...

Creating Upload Form0:00

Now, whether you're uploading to your local file system or something like S3, it's always a little more complicated than you would want. So you just want the user to upload their avatar, but then it just gets kind of clunky figuring out what the file name is, what the extension is, where to store it, where the temporary path. You always have to research it, right? Take a look at this. Here our home route loads a welcome view. In this welcome view, I'm going to set up a form here that will post to anywhere. How about just avatars?

In this welcome view, I'm going to set up a form here that will post to anywhere. How about just avatars? We're going to give the User the option to upload an avatar to their account. And let's say save avatar. So the basic path is we will upload a file. So this will be a file type with the name of avatar. And of course, as you likely know, anytime you accept file uploads, you need to set the enctype on the form to multipart/form-data. And that should do it. Okay, so if we visit laravel53.dev, sure enough, we get this file input at the top.

And that should do it. Okay, so if we visit laravel53.dev, sure enough, we get this file input at the top. But actually real quick, why don't we style this? Let's say body, really quick, set the height to 100%. And then the body will be display is flex. That way I can justify the content to the center and align the items to the center. And this should bring it to the top of the page. Yeah. Okay, but anyways, it's going to post to /avatars. So I'm going to set up a route for that.

Storing Uploaded File1:15

Okay, but anyways, it's going to post to /avatars. So I'm going to set up a route for that. When we post to avatars, now in the past, yeah, it was kind of clunky. You had to get the file upload, and then you had to inspect it. And we did have Symfony's UploadedFile instance to make it a little cleaner, but it was still just more of mental weight than you would want. Instead, we can do this. Give me the avatar file, and I'm going to store that to the avatars directory. I mean, this is pretty crazy. So we'll say return.

I mean, this is pretty crazy. So we'll say return. Let's just return back when we're done and take a look. So give it a refresh. I'm going to choose a file, and I've saved a few LaraCast avatars. So we'll start with pmul, save. Now that actually redirected back really quickly, but I assure you, it works. So by default, these will be stored not in the public directory. And if you think about it for version control and pulling down changes, it's kind of weird to put it there.

Default Storage Location2:09

And if you think about it for version control and pulling down changes, it's kind of weird to put it there. So instead, the recommended location is the storage directory, and then you can set up a symlink, which Laravel can help you with. But anyways, so the default path is storage/app. And real quick, let me show you this. In your config filesystems directory, you'll see where this is referenced. So the root directory for the local file system is the storage directory and then an app folder. So what you see here is when I said store avatars, I was specifying a folder name. And then Laravel is going to dynamically figure out a unique name, including the extension.

So what you see here is when I said store avatars, I was specifying a folder name. And then LaraFell is going to dynamically figure out a unique name, including the extension. And in this case, there you go. Let's do another one. Let's do Bobby. Okay, back to Sublime. And now he is stored here. Pretty cool. I mean, that's light years easier than it was in the past. Now though, if we take a look at this, the store method, well, that's going to be located

Using storeAs and Disks2:58

I mean, that's light years easier than it was in the past. Now though, if we take a look at this, the store method, well, that's going to be located on the UploadedFile instance that Laravel offers. And you'll notice that it defers to this storeAs method. So this is just a helper that will dynamically figure out the name for you. Now if you want though, if you want to override the name and be explicit about it, then you can call the storeAs method, you specify the path, what the fileName should be, and then you can also specify the disk that you want to use. So as you know, Laravel 5 offers support for multiple file systems, so to speak. So for example, you could use the local file system, you could FTP somewhere, you could

So as you know, Laravel 5 offers support for multiple file systems, so to speak. So for example, you could use the local file system, you could FTP somewhere, you could use Rackspace, or you could use S3. So that means, according to this, if we call the store method, or the same with store by the way, and you specify a disk and you set it up, well, that means we can do something like this. And as a result, in one line of code, we can take an uploaded file, we can generate a unique name and extension, and we can upload it to S3 all in one line of code. Pretty cool. Now a quick note on this though.

Pretty cool. Now a quick note on this though. Of course, you need to set up S3 with Laravel. So once again, you'll do that in your filesystems directory. And if we scroll down, well, of course, if you want S3 for everything, you can update your default. You can also update your default cloud disk. But also down here at the bottom, you'll see that I've just hardcoded some values that I will delete in just a minute. So don't try to use these.

Uploading and Serving from S35:20

Once again, choose a file. We'll do Bashy this time. Save it. But now it's going to be stored on S3. So if I come back and give this a refresh, there it is. There's the avatars folder, and there's Bashy. So if we open this up, that will download, of course, or if I go to properties, here is the full link to the file. Now here's what you can do. Of course, you can reference that directly in your view, like if you happen to know it,

Now here's what you can do. Of course, you can reference that directly in your view, like if you happen to know it, you can just reference that directly. Give it a refresh. You'll see that there, of course. But you can also do this. You can replace this with the URL. So you could say storage, the disk is S3 because we're not using the default. And then you could say give me the full URL for this. Okay, so now if I come back and I give that a refresh, I'm still going to get the exact

Explicit Filenames and Paths6:06

And then you could say give me the full URL for this. Okay, so now if I come back and I give that a refresh, I'm still going to get the exact same thing. But yeah, now we're getting it dynamically based upon the region and your bucket name. Now last thing, like I said, if you need to be explicit, you don't want to use a unique generated file, what you can do is you can say request file avatar, and that's going to basically give you an uploaded file instance. So if we take a look at that, that's going to give you Illuminate\Http\UploadedFile, which extends Symfony's\UploadedFile. So here's where you can get all this stuff, like the extension, or you can guess it.

which extends Symfony's uploaded file. So here's where you can get all this stuff, like the extension, or you can guess it. You can get the original size, anything you would really want there. So yeah, you could say file, store as, and I want it in the avatars directory. However, if you are going to use a name like avatar.jpg, well, you want to make sure that you don't overwrite that every single time. So what you might want to do is something like give me the authenticated User's ID, or their username, or some kind of hash for that. So like if I were to manually log in a User, yeah, well, now it would be stored within avatars/1/ whatever the file name is, and that way they can all be generic.

So like if I were to manually log in a User, yeah, well, now it would be stored within avatars/1/whatever the file name is, and that way they can all be generic if you need to. Next, though, you can't depend upon the extension. So what you could do is say $ext equals, and then file_get_contents() client extension. It's always kind of tricky, the proper method you're supposed to use for that, because Symfony gives you a couple of different ways to figure out what the extension should be. You can just base it upon the extension of the file given to you, or you can actually read the MIME type and try to figure out what the extension is. Either way, we could do avatar.extension.

read the MIME type and try to figure out what the extension is. Either way, we could do avatar.ext. Yeah, so this is just an option if you need to be explicit. I think in many cases, you can just let Laravel do it for you, because often a unique random hash is exactly what you want. But yeah, once again, if you need to be explicit, you can dig in and do what you want. All right, so get the uploaded file instance, figure out what the extension should be, and then we're going to store it to the avatar/1 directory, and the file name will be called avatar.ext. And let's do it locally, and then do it through S3.

Go back to Chrome, choose a file, go back to Bobby, save the avatar. And of course, by the way, if these are large images, you can queue that all up. But let's give it another refresh, and there we go. Here's the User with an ID of one, and there is their avatar that we can reference. Oh, and by the way, I know I said we were done, but one last thing I want to show you. When you call these methods, it's going to return to you the path that you can use. So if we come down, we're returning the path if it was uploaded. So we could say path, and in fact, let's just do this number right here. Okay, so let's try it one last time. Save the avatar, and yeah, that's going to return to you the local path.

Okay, so let's try it one last time. Save the avatar, and yeah, that's going to return to you the local path. And notice that it's not including the full S3 region and the bucket name. So that's where you would want to use Storage::disk('s3'), and then you call the url method to get the full path. But anyways, no matter how you tackle this, this is really very, very cool. You now call request()->file(), you pass the name of the file input, and then you store that to a directory. It couldn't be simpler. I love it.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟