Laravel create packages

What is Laravel Package?

Packages are used to add new functionality in laravel. You can create a package that other people can use. For example, if you have created user roles and permission functionality.

You can bundle the code that does this logic and create a package so that other developer can use the similar functionality in their laravel project.

How to create a laravel Package?

In order to create a new package first of all let's create a new laravel project. To learn how to install laravel follow the tutorial below:

Install Laravel Project

Once laravel is installed we need to create a new directory structure for our packages. let's open a terminal window while being in root folder of our laravel project:

mkdir packages​

Packages often use namespaces so that one vendor can have multiple packages. For example, I have a github account and my username is pcb this will be the name of the vendor.

Now, I create 4 different packages meaning 4 different repositories which will use their own name. Let say that I want to create a package that deals with timezone.

I would name my package like pcb/timezone. Next, I have to create such directory structure for my laravel packages. Open terminal window and create such directory structure by running following commands:

# create directory structure
cd packages;
mkdir pcb;
cd pcb;
mkdir timezones;

# our new directory structure will look
# like following
-- packages
    |-- pcb
        |-- timezones​

Now, we have a basic package directory structure. We will create some files within our package folder which are necessary files that each laravel package might have.

Create directory structure for our Package

Let's take a look at following image to understand directory structure for our pcb/timezones package:

First of all we need to add composer.json file in this file we will define some basic things about our package and if our package depends on some other dependencies then we will also add them here.

Let's open our composer.json file and add following contents:

{
    "name": "pcb/timezones",
    "description": "Sample Laravel Package to show timezones",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Sandip Patel",
            "email": "demo@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
      "psr-4": {
        "PCB\\TimeZones\\": "src/"
      }
    }
}

In composer.json file we defined a namespace PCB\TimeZones for our src folder. All the files within src folder will use this namespace.

Next, we will create a .gitignore file and add following contents.

/vendor​

Create a service provider

Service provider is the main file that connects our package with laravel app. Using this class you load following things in laravel app.

  • You can add migrations
  • You can add translations
  • You can merge configurations
  • You can define routes
  • You can load more classes and many other things

To learn what more you can do follow the official package development tutorial shown below:

Package Development

For our package we need to load routes only. Let's include our routes in TimezonesServiceProvider.php file:

namespace PCB\TimeZones;

use Illuminate\Support\ServiceProvider;

class TimezonesServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        include __DIR__.'/routes.php';
    }
}

Add routes.php file

Let's add routes.php in packages/pcb/timezones/src folder with one route defined:

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('timezones/{timezone}', 'PCB\TimeZones\TimezonesController@index');

Add controller file

Next, we have to create a controller file with one method which will be called when someone tries to access the route url we defined earlier in our routes.php file.

Let's create a new controller called TimezonesController.php file in src folder with following contents:

namespace PCB\TimeZones;

use Carbon\Carbon;
use App\Http\Controllers\Controller;

class TimezonesController extends Controller
{
    public function index($timezone)
    {
        echo Carbon::now($timezone)->toDateTimeString();
    }
}

We have added all the necessary files for our package to work. Basically we have added following additional functionality to existing laravel app.

  • When user access /timezones/UTC it will show current time in UTC format
  • User can supply the different timezone to check date in different timezone
  • Basically we can add multiple pages that deals with timezones if we want to

Benefits of using laravel package

If you are working for a company where they have different clients and for each clients they might have some features in common.

For example, if they have user management functionality then you can create a package that has the logic for user management and you can load this package via composer for other clients.

Using this approach you can save a lot of time in copy pasting functionality when your company adds new client. A good thing is you make one change to your package and update the package for all of your clients.

How to load this new package in existing app

Now, to use this new package in our laravel app. First, go to project root of your laravel app and open composer.json file and add namespace in psr-4:

autoload": {
    "classmap": [
        "database"
    ],
    "psr-4": {
        "App\\": "app/",
        "PCB\\TimeZones\\": "packages/pcb/timezones/src"
    }
}

Now, run following composer command to load our pacakge:

# load our new namespace
composer dump-autoload

# run our laravel app
php artisan serve​

Go to your browser and hit http://localhost:8000/timezones/UTC  and you will see current time in UTC format. You can change the last parameter to some other timezone and it will display the same time in that new timezone.

Note: we have manually included our package in laravel app however if you want to load it via packagist you have to follow different steps.

We will cover how to add package via packagist in some other tutorial.

To exerciselore similar package you can checkout the following github pacakge:

Laravel Modular Package