Using Composer

Even though this is not a necessary component when implementing the MVC pattern, Composer has been an indispensable tool for any PHP web application over the last few years. The main goal of this tool is to help you manage the dependencies of your application, that is, the third-party libraries (of code) that we need to use in our application. We can achieve that by just creating a configuration file that lists them, and by running a command in your command line.

You need to install Composer on your development machine (see Chapter 1, Setting Up the Environment). Make sure that you have it by executing the following command:

$ composer –version

This should return the version of your Composer installation. If it does not, return to the installation section to fix the problem.

Managing dependencies

As we stated earlier, the main goal of Composer is to manage dependencies. For example, we've already implemented our configuration reader, the Config class, but if we knew of someone that implemented a better version of it, we could just use theirs instead of reinventing the wheel; just make sure that they allow you to do so!

Note

Open source

Open source refers to the code that developers write and share with the community in order to be used by others without restrictions. There are actually different types of licenses, and some give you more flexibility than others, but the basic idea is that we can reuse the libraries that other developers have written in our applications. That helps the community to grow in knowledge, as we can learn what others have done, improve it, and share it afterwards.

We've already implemented a decent configuration reader, but there are other elements of our application that need to be done. Let's take advantage of Composer to reuse someone else's libraries. There are a couple of ways of adding a dependency to our project: executing a command in our command line, or editing the configuration file manually. As we still do not have Composer's configuration file, let's use the first option. Execute the following command in the root directory of your application:

$ composer require monolog/monolog

This command will show the following result:

Using version ^1.17 for monolog/monolog
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing psr/log (1.0.0)
    Downloading: 100%

  - Installing monolog/monolog (1.17.2)
    Downloading: 100%
...
Writing lock file
Generating autoload files

With this command, we asked Composer to add the library monolog/monolog as a dependency of our application. Having executed that, we can now see some changes in our directory:

  • We have a new file named composer.json. This is the configuration file where we can add our dependencies.
  • We have a new file named composer.lock. This is a file that Composer uses in order to track the dependencies that have already been installed and their versions.
  • We have a new directory named vendor. This directory contains the code of the dependencies that Composer downloaded.

The output of the command also shows us some extra information. In this case, it says that it downloaded two libraries or packages, even though we asked for only one. The reason is that the package that we needed also contained other dependencies that were resolved by Composer. Also note the version that Composer downloaded; as we did not specify any version, Composer took the most recent one available, but you can always try to write the specific version that you need.

We will need another library, in this case twig/twig. Let's add it to our dependencies list with the following command:

$ composer require twig/twig

This command will show the following result:

Using version ^1.23 for twig/twig
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing twig/twig (v1.23.1)
    Downloading: 100%

Writing lock file
Generating autoload files

If we check the composer.json file, we will see the following content:

{
    "require": {
        "monolog/monolog": "^1.17",
        "twig/twig": "^1.23"
    }
}

The file is just a JSON map that contains the configuration of our application; in this case, the list of the two dependencies that we installed. As you can see, the dependencies' name follows a pattern: two words separated by a slash. The first of the words refers to the vendor that developed the library. The second of them is the name of the library itself. The dependency has a version, which could be the exact version number—as in this case—or it could contain wildcard characters or tag names. You can read more about this at https://getcomposer.org/doc/articles/aliases.md.

Finally, if you would like to add another dependency, or edit the composer.json file in any other way, you should run composer update in your command line, or wherever the composer.json file is, in order to update the dependencies.

Autoloader with PSR-4

In the previous chapters, we also added an autoloader to our application. As we are now using someone else's code, we need to know how to load their classes too. Soon, developers realized that this scenario without a standard would be virtually impossible to manage, and they came out with some standards that most developers follow. You can find a lot of information on this topic at http://www.php-fig.org.

Nowadays, PHP has two main standards for autoloading: PSR-0 and PSR-4. They are very similar, but we will be implementing the latter, as it is the most recent standard published. This standard basically follows what we've already introduced when talking about namespaces: the namespace of a class must be the same as the directory where it is, and the name of the class should be the name of the file, followed by the extension .php. For example, the file in src/Domain/Book.php contains the class Book inside the namespace BookstoreDomain.

Applications using Composer should follow one of those standards, and they should note in their respective composer.json file which one they are using. This means that Composer knows how to autoload its own application files, so we will not need to take care of it when we download external libraries. To specify that, we edit our composer.json file, and add the following content:

{
    "require": {
        "monolog/monolog": "^1.17",
        "twig/twig": "^1.23"
    },
    "autoload": {
        "psr-4": {
            "Bookstore\": "src"
        }
    }
}

The preceding code means that we will use PSR-4 in our application, and that all the namespaces that start with Bookstore should be found inside the src/ directory. This is exactly what our autoloader was doing already, but reduced to a couple of lines in a configuration file. We can safely remove our autoloader and any reference to it now.

Composer generates some mappings that help to speed up the loading of classes. In order to update those maps with the new information added to the configuration file, we need to run the composer update command that we ran earlier. This time, the output will tell us that there is no package to update, but the autoload files will be generated again:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files

Adding metadata

In order to know where to find the libraries that you define as dependencies, Composer keeps a repository of packages and versions, known as Packagist. This repository keeps a lot of useful information for developers, such as all the versions available for a given package, the authors, some description of what the package does (or a website pointing to that information), and the dependencies that this package will download. You can also browse the packages, searching by name or categories.

But how does Packagist know about this? It is all thanks to the composer.json file itself. In there, you can define all the metadata of your application in a format that Composer understands. Let's see an example. Add the following content to your composer.json file:

{
    "name": "picahielos/bookstore",
    "description": "Manages an online bookstore.",
    "minimum-stability": "stable",
    "license": "Apache-2.0",
    "type": "project",
    "authors": [
        {
            "name": "Antonio Lopez",
            "email": "[email protected]"
        }
    ],
    // ...
}

The configuration file now contains the name of the package following the Composer convention: vendor name, slash, and the package name—in this case, picahielos/bookstore. We also add a description, license, authors, and other metadata. If you have your code in a pubic repository such as GitHub, adding this composer.json file will allow you to go to Packagist and insert the URL of your repository. Packagist will add your code as a new package, extracting the info from your composer.json file. It will show the available versions based on your tags or branches. In order to learn more about it, we encourage you to visit the official documentation at https://getcomposer.org/doc/04-schema.md.

The index.php file

In MVC applications, we usually have one file that gets all the requests, and routes them to the specific controller depending on the URL. This logic can generally be found in the index.php file in our root directory. We already have one, but as we are adapting our features to the MVC pattern, we will not need the current index.php anymore. Hence, you can safely replace it with the following:

<?php

require_once __DIR__ . '/vendor/autoload.php';

The only thing that this file will do now is include the file that handles all the autoloading from the Composer code. Later, we will initialize everything here, such as database connections, configuration readers, and so on, but right now, let's leave it empty.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.135.225