Some Random Tips and Tricks for Laravel

You never know.

Updated on July 19, 2018 Posted by lagbox on May 1, 2016 laravel tips tricks

Random Laravel tips and tricks

This will continue to be updated, this is just a small small selection of random tricks.

Database

Your own Schema Builder

How about always making sure 'created_at', 'updated_at' and 'deleted_at' are added to all tables for you via Schema Builder.

Gist - Use your own Schema Builder

Query Log

Been wondering how you can see what queries are being made to your database. Well there is a query log you can enable.

DB::enableQueryLog(); // enable the query log
DB::getQueryLog(); // get the query log


⚡ php artisan tinker
Psy Shell v0.7.0 (PHP 7.0.4-7+deb.sury.org~wily+2 — cli) by Justin Hileman
>>> DB::enableQueryLog();
=> null
>>> App\User::all();
=> Illuminate\Database\Eloquent\Collection {#771
     all: [
       App\User {#777
         ...
       },
       App\User {#778
         ...
       },
       ...
     ],
   }
>>> DB::getQueryLog();
=> [
     [
       "query" => "select * from "users"",
       "bindings" => [],
       "time" => 0.32,
     ],
   ]
>>>

Though this is not in the current docs you can still find it referenced in the 5.0 docs and it still works. Laravel 5.0 Docs - Basic Database Usage - Query Logging

Correct types on MySQL

If you are noticing that your 'number' fields are coming back as strings, you are missing a very nice driver. The mysqlnd module, MySQL Native Driver, will respect types.

If you are on Ubuntu or a derivative you can just do a search for it and install the package.

⚡ apt-cache search mysqlnd

After installing that and it being enabled, you should get back integers for your integer fields instead of strings.

Routing

Hardcoded Values

You can use the defaults method on a Route instance to add a default value for a parameter to pass to the action:

Route::get('about', 'PageController@show')->defaults('page', 'about');

public function show(Request $request, $page) { ... }

The action array for the route can be used to pass arbitrary data:

Route::get('about', [
    'uses' => 'SomeController@page',
    'page' => 'about'
]);

public function page(Request $request)
{
    $page = $request->route()->getAction()['page'];
    // Laravel >= 5.5
    $page = $request->route()->getAction('page');
    ...
}

Nested Resources

Though this isn't documented anymore, it is still in the 5.1 docs and is still available to use.

Route::resource('users.pictures', 'PictureController');

This will setup nested resource routes for you.

GET users/{users}/pictures
GET users/{users}/pictures/{pictures}/edit

Laravel 5.1 Docs - Controllers - Restful Resource Controllers - Nested Resources

Separate Route files for Web and API

In versions of Laravel > 5.2, you have routes broken up into more convenient files that are loaded into different groups, so this shouldn't be needed.

If you installed laravel/laravel (the project) after 5.2.26, you have the 'web' group of middleware applied to your routes in routes.php by your RouteServiceProvider. This will probably be a problem if you want to have routes that wont have the 'web' group of middleware applied to them.

  1. You can adjust your routes.php file and RouteServiceProvider to not apply the 'web' group to all the routes.
    1. Adjust the RouteServiceProvider@mapWebRoutes to not apply the 'web' middleware.
    2. Wrap any routes in routes.php that you want the 'web' group applied to in a route group with 'middleware' => 'web'.
    3. Wrap any routes in routes.php that you want the 'api' group applied to in a route group with 'middleware' => 'api'.
  2. Create another routes file to hold your API routes: api-routes.php.
    1. Put the routes you don't want to have the 'web' middleware group applied to in api-routes.php.
    2. Adjust your RouteServiceProvider@map to add a call to $this->mapApiRoutes($router);
    3. Add a mapApiRoutes method to your RouteServiceProvider that will load the api-routes.php file in a route group with the correct middleware.

Option 2 is recommended. Gist for Option 2 - changes to RouteServiceProvider

Files

Uploaded File Hash Name

In 5.2+ you can use the UploadedFile class, which is returned from $request->file('yourfile') to get a hash name for the uploaded file.

$file = $request->file('yourfile');
$hashname = $file->hashName();

Get a filename for the file that is the MD5 hash of the contents.

public function hashName($path = null)
	

In newer versions of Laravel the hash may not be based upon the file contents.

Helpers

Have a need to add some helper functions to your application. Well that is pretty easy. We can easily create a file to hold some functions and have composer autoload this file for us.

For this example, create a helpers.php file in app.

To autoload all we have to do is modify our composer.json file to tell it to load this file. Look for the "autoload" section your `composer.json' file:

"autoload": {
    "classmap": [
        "database"
    ],
    "psr-4": {
        "App\\": "app/"
    },
    "files": [
        "app/helpers.php"
    ]
},

The "files" section is what we are adding. We give it a path from the root of the project. Dump the autoload just incase composer dump and you should be good to go.

Artisan

Help

Get a list of available artisan commands and a brief description.

⚡ php artisan list

Get a list of available artisan commands by their namespace. (Get all commands in the make namespace)

⚡ php artisan list make

Need to get some information on your artisan commands.

⚡ php artisan make:migration --help
⚡ php artisan help make:migration

Generate files in other locations

Want the artisan generator to place your file in a subdirectory?

⚡ php artisan make:controller "Admin\ArticlesController" --resource
⚡ php artisan make:controller Admin\\ArticlesController --resource

This will create your controller in app/Http/Controllers/Admin with the correct namespace.

Macros

Numerous classes throughout the framework are 'macroable'. They are either implementing this behavior themselves or using the Illuminate\Support\Traits\Macroable trait. Macros allows you to add functionality (methods) to certain classes at runtime.

I have a quick article about Macros in Laravel if you would like to know more.

Framework

Installing specific versions

Develop version:

composer create-project laravel/laravel yourproject dev-develop

5.1:

composer create-project laravel/laravel yourproject 5.1

Development

Want to work on some new features of the framework or fix a bug? You can have composer grab the actual source from the repo, including tests, for you.

If you have already created your project like so:

composer create-project laravel/laravel yourproject ...

You can remove the framework directory from vendor and have composer clone the repo:

rm -rf vendor/laravel/framework

composer update laravel/framework --prefer-source

You will have the complete history and all tests available in vendor/laravel/framework.

./vendor/bin/phpunit vendor/laravel/framework/tests/Routing/RouteRegistrarTest.php