Making libraries/packages installable using composer


It may interest you to note that, that every project with a “composer.json” file in its directory is a library/package. Whenever we add the “require” key, we are making a package that will depend on other packages. The major difference between our projects and a standard package is that our projects are packages without names. Therefore, adding the name property  in our “composer.json” makes our project an installable package.

In the last tutorial, we installed and used classes from open source packages, in this tutorial, we will look at how to make our own libraries/project/packages installable using Composer. We will use the word library, package and project to refer to a package, just to make us better understand the concept.

#Package Name

For our library to be installable, we library must have a vendor and package name. We do this by adding these names in the “package.json” file as shown in the code snippet below.

	“name” : “vitalis/hello-world”
	“require”: {

In the above code snippet, “vitalis” is the vendor name and “hello-word” is the package name. The vendor name, as explained in the previous tutorial helps in preventing name conflicts as a package can comfortable have the same package name, but different vendor name. These names are always case insensitive, but the conversion is to use lower cases and dashes for word separators.

#Package Versioning

In most of our development processes, we are likely to make use of Version Control Systems(VCS) like Git in our project. In such cases, we are not required to explicitly state the version of our project/package in the “composer.json” file as composer user VCS branches and tags to resolve the  version constraints.

But in a case when we are maintaining out the package by hand, we must explicitly state the version of our package or project in the “composer.json” file as shown in the code snippet below:

	“version” : “1.0.0”

It is important to note that adding a hard-coded version number to VCS, will result in version and tag conflicts as a composer will not be able to resolve the version of our projects.

#Version by VCS

Composer makes use of our branch and tags to resolve the versions constraints of our project dependencies stated in our required fields. It also maps these versions to their right origins and saves them in the “composer.lock” file

#Publishing to VCS

To publish our package to a VCS repository, our project must contain a composer.json file, so in our case our project is already installable since it contains a ”composer.json” file.

In this tutorial, we will publish “vitalis/hello-world” library to GitHub under https://github.com/agavitalis/hello-world

Now to test our just-published library, we will create a new project locally. We will call this project “vitalis/use-hello-world”. This locally created project will depend on “vitalis/hello-world”, which will turn depend on some other libraries, “monolog/monolog” in this case.

To accomplish this, “vitalis/use-hello-world” project must contain a composer.json file on which we will specify how to require the “vitalis/hello-world” hosted in GitHub. A sample specification of how the composer.json file of “vitalis/use-hello-world” project is shown in the code snippet below:

    "name": "vitalis/use-hello-world",
    "repositories": {
        "type ": "vcs ",
        “url” : “https://github.com/agavitalis/hello-world”
    "require": {
        "vitalis/hello-composer": "dev-master"

The above code snippet shows the content of the “composer.json” file of our locally created “vitalis/use-hello-world” project. We may skip the name option if we don’t have the intention of publishing this project, but we included it for clarity purposes.

The repositories specifications were added to tell the composer where to locate the vitalis/hello-world package .

At this point we can run the “composer install” command, and composer will grab our “vitalis/hello-world” package into the “vitalis/use-hello-world” vendor folder.

#Publishing to Packagist

So far, we can now publish packages, but having to include the VCS details for each package is rather redundant and tiresome, and we will not like to that, thus Packagist.

Packagist is a central repository for composer and it comes enabled by default. Any package published in Packagist is automatically accessible through composer, that was why we were able to specify “monolog/monolog” in the “vitalis/hello-world” package without specifying its repository.

So, to share our vitalis/monolog package to the world, we simply visit https://packagist.org and hit the submit button. This will prompt us to register if we are not yet registered, and it will then allow us to submit the URL to our VCS repository. Once we have done this, our project is live to the world, and it could be installed at one click using composer without having to specify the repository.

Yes, we have successfully gone through the processes of making our libraries installable using composer. In the next tutorials, we will follow these processes and create an actual package, make it live in Packagist, and then consume the package in another project.

Don’t forget to like and share this tutorial with your friends, follow us also on social media for more updates.

Previous: How to auto-update composer packages with webhooks
Next: Package installation using composer

PHP: Tips of the Day

Get first key in a (possibly) associative array?

Starting from PHP 7.3, there is a new built in function called array_key_first() which will retrieve the first key from the given array without resetting the internal pointer. Check out the documentation for more info.

You can use reset and key:

$first_key = key($array);

It's essentially the same as your initial code, but with a little less overhead, and it's more obvious what is happening.

Just remember to call reset, or you may get any of the keys in the array. You can also use end instead of reset to get the last key.

If you wanted the key to get the first value, reset actually returns it:

$first_value = reset($array);

There is one special case to watch out for though (so check the length of the array first):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)

Ref : https://bit.ly/32ecxHN