We use cookies on this site to enhance your user experience

By clicking the Accept button, you agree to us doing so. More info on our cookie policy

Creating your first Laravel package

Published: Aug 10, 2019 by C.S. Rhymes

I’ve always been interested in making a package for Laravel so I thought I would make a simple example package and share what I had learnt from the process. The package is very simple and just contains some extra collection methods, so I decided to call it extra-collect.

Folder Structure

I started by making a new folder and running composer init to generate a composer.json file. I followed the commands to add the name, chrisrhymes/extra-collect and description A Laravel package containing a collection of collections.

As per most PHP packages, I created a src directory where all the php files will live. I then created a file called ExtraCollectServiceProvider.php in the src directory. Here is the file structure so far.

/src/ExtraCollectServiceProvider.php
composer.json

Autoloader

I then added the following to the composer.json to autoload the service provider and any php classes with the ChrisRhymes\ExtraCollect namespace from the src directory.

"autoload": {
    "psr-4": {"ChrisRhymes\\ExtraCollect\\": "src/"}
}

Automatic Package Discovery

The next step was to sort the automatic package discovery. Since Laravel 5.5 you can add some additional or “extra” lines into your composer.json to allow Laravel to automatically register your service provider when the package is installed.

I followed the example in the Laravel docs site and added the package’s service provider class to the providers array. If you have any facades you can register them in the aliases array, but since I don’t have any in this package, I didn’t.

"extra": {
    "laravel": {
        "providers": [
            "ChrisRhymes\\ExtraCollect\\ExtraCollectServiceProvider"
        ],
        "aliases": {
        }
    }
}

Service Provider

I now focused on the service provider class. The service provider needs to extend the Illuminate\Support\ServiceProvider class and have boot and register methods. I added the new collection methods to the boot method in the service provider, which meant I needed to add a use statement for the Illuminate\Support\Collection class as well.

If you are using an IDE then it will probably complain that it can’t find the Illuminate\Support\ServiceProvider or the Illuminate\Support\Collection classes. To resolve this, I added the Laravel Framework as a dev dependency so it could find the classes.

composer require --dev laravel/framework

This then created a vendor folder for me and installed the Laravel Framework package for me which then stopped the IDE from complaining as it can now find the classes.

.gitignore

Obviously, you don’t want the vendor folder as part of your package so that’s why I added it as a dev dependency. To avoid the vendor folder being included in the project when I pushed it up to GitHub I created a .gitignore file and added the vendor directory, and whilst I was there, added the composer.lock file to the .gitignore as well.

Tests

Before I pushed up my package to GitHub, I wanted to make sure that the code worked as expected, so I thought it would be a good idea to create some tests. The service provider makes use of some Laravel classes so I needed a way of including the framework with my tests.

Luckily there is a package to do just that called Orchestral TestBench, so I used composer to install the package

composer require --dev "orchestra/testbench=^3.8"

The package states you have to extend the Orchestral TestCase instead of the Laravel TestCase, so I created a tests directory with a TestCase class that did just that.

Within the TestCase class, I added the getPackageProviders method and included my packages service provider class so it can be used within the tests.

protected function getPackageProviders($app)
{
    return [
        ExtraCollectServiceProvider::class
    ];
}

As the tests are in the tests directory and not the src directory, the classes won’t be autoloaded. To resolve this I added the following to the composer.json file so anything with the Test namespace would be loaded from the tests directory.

"autoload-dev": {
    "psr-4": {
        "ChrisRhymes\\ExtraCollect\\Test\\": "tests/"
    }
}

I then created the tests, one class for each of the collection methods, ensuring that the test class extended my new TestCase class. Each test collects an array and applies the relevant collection method, before testing the output is what is expected.

I then created a phpunit.xml file stating where the tests can be found and to use the php classes ending in Test.php.

Finally, I added the following script to my composer.json file to run the test using composer test command

"scripts": {
    "test": "phpunit"
}

I ran composer test and luckily all the tests passed.

Readme

I created a simple readme file to help explain to others how the collection methods work. I decided to follow the documentation style of the official Laravel docs Collections page with a usage example and the expected output.

Deploying and Installing the Package

With the example package ready to go, I created a new repository in GitHub (called extra-collect as per the composer.json name), added the git remote repo to my directory, commited the files and pushed them up to GitHub.

I was very excited to start using the package and see how it worked. I had a Laravel project already set up and ready to go on my dev machine so I added my new package in the require section of the composer.json file before running composer update

"chrisrhymes/extra-collect": "dev-master"

But something went wrong, composer couldn’t find my package. It was there, publicly available on GitHub, but then I realised composer needs a bit more help.

I needed to tell composer where the package lived using packagist. I signed up for a packagist account and then added my new package, linking it to the GitHub repo. I was pleasantly surprised how quick and easy it was to use.

I tried composer update again and this time it found the package, installed it and registered the packages service provider automatically. I could now start using my custom collection methods from within a Laravel project.

One last note is that I would suggest you tag a release for your package in GitHub so people can specify a version number instead of using dev-master as per the example above.

I hope you have found this a useful guide to getting started with creating your first Laravel package.

webdev showdev laravel php

Latest Posts

Testing window.open() in JavaScript with Jest
Testing window.open() in JavaScript with Jest

I recently had to write a test for a React component that opened a new browser window. To open the new window I made use of window.open() in my code. This made the component easy to write, but I had to think a bit differently about how to write the test for this.

Why did I become a writer?
Why did I become a writer?

There has been a lot of discussion on Threads recently about becoming a writer, but don’t give up your day job. I have seen a lot of arguments from all sides, some people saying they became a successful full time writer, others saying they would never give up their job, then there are others who became writers full time then went back to another job. Writing has always been a hobby for me, but this discussion has made me think more about why I write.

Adding social icons to the Bulma Clean Theme footer
Adding social icons to the Bulma Clean Theme footer

Version 1.1.0 of Bulma clean theme has been released. It has a small update that allows you to easily add social media links to the footer of your site.

How NOT to make a website

How NOT to make a Website

By C.S. Rhymes

From £1.99 or read for free on Kindle Unlimited!

Nigel's Intranet Adventure

Nigel's Intranet Adventure

By C.S. Rhymes

From £1.99 or read for free on Kindle Unlimited!