Skip to main content

Laravel File Handling

The thing I like best about Laravel is its elegance.  As far as I'm concerned, it is the cleanest framework out there, even with its limitations.  So I just had to write this post about how I handle files in Laravel.  Note that the storage path can be configured to local storage or to an S3 bucket.

First, we need a route for opening the file in our routes.php file:

// Open a file
Route::get('file/{id}', 'HomeController@getFile');

Then, in our home controller, the related function:

/** * Open file
*/
public function getFile($filename)
{
// Full path
$path = storage_path('app/' . $filename);

// Determine the mime type
$mimetype = mime_content_type($path);

// Return the file
return response()->file($path, ['Content-Type: ' . $mimetype . '; charset=utf-8']);
}



That's it!  When you hit that URL route, the file will automatically open.

If you aren't sure whether your environment supports the mime_content_type() function, you can add a little bit of extra code (this part comes from php.net):


/**
* Open a file
*/
public function getFile($filename)
{
// Full path
$path = storage_path('app/' . $filename);

// Determine the mime type
if (function_exists('mime_content_type')) {
$mimetype = mime_content_type($path);
} else {
$mime_types = [
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',
// audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
// ms office
'doc' => 'application/msword',
'docx' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.ms-powerpoint',
'rtf' => 'application/rtf',
// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
];

// Get extension
$ext = strtolower(array_pop(explode('.', $filename)));

// Match to mime type
if (array_key_exists($ext, $mime_types)) {
$mimetype = $mime_types[$ext];
} else {
$mimetype = 'application/octet-stream';
}
}

// Return the file
return response()->file($path, ['Content-Type: ' . $mimetype . '; charset=utf-8']);
}

Comments

Popular posts from this blog

jQuery noUIslider Pip Label Customization

Recently, I was tasked with creating a slider element for a user to select their credit rating, of which the user can select from among: 'Poor', 'Fair', 'Good', 'Excellent' and 'Not Sure'.  Several problems presented themselves here: A drop-down box would be better, but that's not what the requirements specified. I already have several numeric sliders on my page and I want them all to match. I selected the jQuery noUi Slider library to create the numeric sliders. noUi Slider does not support string values - only numeric values. The "pips" (slider scale/labels) also does not support string values. Since the solution involved shifting my mindset, I wanted to document it here for future reference and maybe to help someone facing the same requirements. Here's my solution: Since there is really no numeric correlation to credit score (especially considering one of the options is "Not Sure"), I will just u...

How to Create a new Case Record Type in Salesforce

Here are the specific steps for adding a case record type. Some steps may vary by organization but the process should be pretty similar to what is shown here. 1) Create a new page layout 2) Add any new case statuses to picklist 3) Edit case statuses that should indicate case is "closed" 4) Add any new case types to picklist 5) Add any new case reasons to picklist 6) Add any new case origins to picklist 7) Add any new fields to case object 8) Under Record Types, ensure the picklists have the correct values (i.e. - Reason/Type/Origin) 9) Within the Type field, edit "Reason" field dependencies matrix and add new reason(s) to types 10) Create a new support process (if not reusing an existing one) 11) Create the new record type (enable for all profiles) 12) Finalize the page layout (if needed) and check "Default" in Case Assignment checkbox under Layout Properties 13) Create approval queues (if needed) 14) Set up approv...

Regarding Technology (a departure from WebDev)

I'm departing from WebDev for a minute to blog about technology. I'm as guilty of over-indulging in technology as anyone, especially given that my career demands a technology overload. Today at noon is the solar eclipse and that prompted me to think about the past and the future. I started to think about where the world stands and a song came up on my playlist that seemed perfect for my mood. 27 years ago, Bad Religion wrote a song about the current generation of kids. It would be prophetic if it weren't for the fact that the trend had already begun back then. In any event, it seems now is a good time to look back at the lyrics: 'Cause I'm a twenty-first century digital boy I don't know how to live but I got a lot of toys My daddy's a lazy middle-class intellectual My mommy's on Valium, so ineffectual What child these days does not have multiple devices to play with? Gaming systems, television, computers and tablets are in nearly every home. Kid...