Introduction to Composer [ the json scheme]

Coding (Php 7.x)

Sep 19, 2020

What are the secret of composer.json? here is how you write one
 
/img/blog/introduction-to-composer-the-json-scheme.jpg

Introduction

 

Let me start this article with a bold statement:

 

Composer is one of the most important tools you have to master if you’re serious about your career as a PHP developer.

 

I could spend hours writing about how important it is to learn the core feature of the language or what this and that function does.

 

and I did just check my older posts.

 

But the reality is that, once you are good in PHP, which means you are able to code what you desire, you MUST learn tools that aim at making your job easier thus your life better.

 

Composer is one of that tool, 

 

Actually most importantly,

 

Composer is the gateway that let you do that.

 

I have already explained in previous episodes what Composer does and how you can use this tool to ‘download’ useful packages into your project.

 

Today you will learn about another very important part of it.

 

The composer.json file also referred to as the composer.json schema

 

As you might have guessed already this is a JSON file and it defines your project requirements.

 

I could have made a list of all the command you can use inside this file but I am quite sure that you will fall asleep after the third or fourth properties so I decided to take another approach.

 

let's call this approach LEARN BY PROJECTS

 

All the packages that you are a fan include a composer.json file which contains the property we have to discuss in here.

 

What a better way to learn about the properties you can use within the JSON schema and discover how our favourite packages are using them.

 

Below I have listed the composer.json file of some of the most popular PHP projects on GitHub.

 

We are going to spend the next few minutes to discover how the developers of these projects are using it.

 

 

 

 

About this series

 

This article is part of the series Introduction to Composer,

 

If you haven't read the previous part already head to

  1. Installation and components
  2. Command-line interface
  3. Command-line interface part 2
  4. Destructuring composer.json
  5. Repositories
  1.  

 

 

 

 

Starting with laravel/laravel

 

I am quite sure we all know Laravel,

 

Laravel is a PHP framework that makes of its elegant and minimalist syntax its trademark.

 

Released for the first time in June 2011, it is now considered the most popular PHP framework,

 

Fun fact, the website you are reading this sentence is made in Laravel

 

It is available on Composer and the snippet of code below is its composer.json file.

 

Let’s analyze it!

 

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.3",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/framework": "^8.0",
        "laravel/tinker": "^2.0"
    },
    "require-dev": {
        "facade/ignition": "^2.3.6",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^5.0",
        "phpunit/phpunit": "^9.3"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}


 

Name

 

This is very straightforward, this field represents the name of the package, it is formed by two strings separated by a slash.

 

In the first string indicates the name of the vendor the one on the right-hand side instead is the name of the project.

 

This property is required in a composer.json file.

 

The name must be lowercased and the format has to be made of words separated by -, . or _

 

 

Type

 

This field indicates which type of project is the package all about.

 

By default, we may found 4 different types.

 

  • library: This is the default value. What it does is simply to copy the files to the vendor folder.
  • project: This denotes a project rather than a library, Laravel is a project, this type can be used by IDEs to provide listings of projects to initialize when creating a new workspace.
  • metapackage: A package that contains no files only contains requirements and will trigger their installation, it will not write anything to the filesystem. 
  • composer-plugin: these types provide an installer for other packages that have a custom type. 

 

It needs to be mentioned that we can also create custom types such as symfony-bundle, or wordpress-plugin

 

 

Description

 

This is another required property of the composer.json file.

 

Every package needs to have a short description. 

 

This is usually achieved by a long single line.

 

 

Keywords

 

This is not a mandatory field but it is useful if you want to improve the chance your package would be found while someone searches for a package.

 

It is written as an array of strings so it can be searched or filtered.

 

 

License

 

This package is optional too but the guys at composer insist for this property to be used.

 

The most common licenses are:

 

  • Apache-2.0
  • BSD-2-Clause
  • BSD-3-Clause
  • BSD-4-Clause
  • GPL-2.0-only / GPL-2.0-or-later
  • GPL-3.0-only / GPL-3.0-or-later
  • LGPL-2.1-only / LGPL-2.1-or-later
  • LGPL-3.0-only / LGPL-3.0-or-later
  • MIT

 

This field can be either used as a string (like in the case of Laravel here) or as an array of strings. 

 

In some cases, you may also find it as a unique string separated by an or and wrapped by parentheses like the example below


"license": "(LGPL-2.1-only or GPL-3.0-or-later)"

 

 

Require

 

This property is of fundamental importance, in fact, all the requirements have to be installed before the package we want to use can be downloaded.

 

If any of these requirement fails the package is not usable.

 

 

Require-dev

 

This property is similar to the one we've just seen but it works only on a dev environment,

 

it means it is supposed to be used for things like running tests or other development processes.

 

Both the command composer install and composer update have a --no-dev flag that, if used, prevent the component from being installed

 

 

Provide

 

It contains a list of packages that are provided by this package. 

 

Mostly used for common interfaces. 

 

The format is the same of require and require-dev, name of the package as key and version as value.

 

 

Config

 

the config property is used to set all the configuration option that the package has to use.

 

It is only used when the package is of type Project and it is composite by a series of options.

 

You can see the whole list on the 6th section of Composer Official documentation (https://getcomposer.org/doc/06-config.md)

 

below we will describe the one used by Laravel:

 

 

Optimize-autoloader

 

This option has a false value by default, in case of Laravel the project needs to always optimize when dumping the autoloader

 

preferred-install.

 

Three different values accepted for this option, they are source, dist or auto.

 

What this option do is to allow you to set which install method Composer has to use.

 

You can also use different patterns and give them a different value according to your needs.

 

sort-packages

 

It indicates if the packages need to be sorted by name in the composer.json file, by default the value is set as false.

 

 

Scripts

 

A script can be a PHP callback or a package-specific command

 

In the case of Laravel, we got both

 

With the current file, we have 3 events, there are many other available, you can check them on the apposite article about scripts on the Composer manual 

 

 

Scripts-descriptions

 

You can add a custom description to your script, 

 

The format has to be the same of the scripts property and it takes a string as a value

 

 

Extra

 

This is simply an extra data that is used by the script property

 

 

Autoload

 

This is probably the most common command you'll see on a composer.json file.

 

Autoload is an amazing feature that allows Composer to load all the classes on your project automatically.

 

There are 2 autoloader supported (PSR-4 and PSR-0), it also supports classmap generation and files.

 

Let's see them in detail.

 

 

PSR-4

 

Inside the PSR-4 it is defined as a map that contains namespace and the path of the class.

 

Namespace prefixes must end in \\ to avoid conflicts between similar prefixes.

 

During the installation or update of Composer, all the reference of PSR-4 are combined into a key/value array,

 

You can find this array at the path vendor/composer/autoload_psr4.php

 

 

PSR-0

 

Like the previous section, even with PSR-0, we define a map of namespaces to paths,

 

Like before each declaration should end in \\ to make sure the autoloader responds exactly. 

 

The combined array this time is stored at the path vendor/composer/autoload_namespaces.php.

 

If your application has only one class in the global namespace, instead of using a namespace declaration, you can use PSR-0 to can specify it.

 

 

Classmap

 

Classmap is represented as a map, it is built by scanning all the classes in the /php and .inc files in a specified directory,

 

This also combines the data into an array, you can look at it at vendor/composer/autoload_classmap.php.

 

 

Files

 

Alternatively, you can choose to load the file explicitly on every request,

 

To do that you’ll need to use the files option.

 

You can opt for this alternative when your package has PHP functions that cannot be autoloaded by PHP.

 

 

Autoload-dev

 

This works exactly like the paragraph above but the rules defined only worth on a development environment.

 

This autoloader is in charge of loading the classes the run test suites and that should not be included into the main autoload

 

 

Minimum-stability

 

This property act as a filter,

 

Every package you are using has a version, each of these versions has a stability property.

 

It can be that a package is still in the development phase or that it is ready and tested.

 

This property filter among your packages when you are resolving your dependencies and ignore all the packers that are below the value requested in the composer.json file.

 

The possible values for this property are dev, alpha, beta, RC and stable.

 

 

Authors

 

Either you are developing a package or you want to use one, it is very useful to be able to contact the authors for support or say thanks for their effort.

 

Also, imagine that while you are using a dependency you find a bug, as a good peer you might want to contact the developer that did it and help him out or at least notify him about the problem.

 

The authors' property takes an array of 4 key/value pairs.

 

They are name, email, homepage (if the author has a personal website) and his role while developing the package

 

 

Homepage

 

The homepage property consists of a simple string containing the URL of the website of the project

 

 

Suggest

 

It may happen like in the case of the Composer’s composer.json that the authors of the package suggest other packages that work well alongside it.

 

The format of this property is very simple, it an object in which the key is the full name of the package and the value is a string containing the message or some info about the package itself.

 

These messages are displayed after the main package has been installed.

 

In the case of Composer the packages suggested are ext-openssl and the extension ext-zip and ext-zlib

 

 

Bin

 

Indicates a folder or files that have to be dealt with as binary and symlinked into the bin-dir.

 

A vendor binary is a command-line script that a package wants to pass to a user that install the package.

 

Only the packages containing other scripts that are needed by the package user should be listed as vendor binary,

 

For more information about it have a look at the official Vendor Binaries Composer documentation.

 

 

Support

 

Similar to the Author property, it takes meta-informations about the package.

 

In this case, the support information is:

  • email: Email address for support.
  • issues: URL to the issue tracker.
  • forum: URL to the forum.
  • wiki: URL to the wiki.
  • irc: IRC channel for support, as irc://server/channel.
  • source: URL to browse or download the sources.
  • docs: URL to the documentation.
  • rss: URL to the RSS feed.
  • chat: URL to the chat channel.

 

 

Prefer-stable

 

This property takes a boolean as a value,

 

When set as true, Composer will prefer more stable packages over unstable ones during the finding of compatible packages if possible. 

 

This property has less priority compared to the minimum-stability one, in fact, in case a dev version or only alphas are available for a package, those will still be selected only if the minimum-stability allows for it.

 

 

Funding

 

In the era of open-source, it is common for someone that develops a package to ask for support or donation.

 

The founding property is composed by an object that contains a type (e.g. Patreon, opencollective, tidelift or GitHub.) and a URL key, with includes the address where it is possible to donate.

 

 

 

That’s if for now!

 

Below you can see few real examples of composer.json file for some of the most popular PHP packages 

 

 

fzaninotto/faker

 

Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you.

 

Faker is heavily inspired by Perl's Data::Faker, and by ruby's Faker.

 

Faker requires PHP >= 5.3.3.

 

see fzaninotto/faker on GitHub

 

{
    "name": "fzaninotto/faker",
    "type": "library",
    "description": "Faker is a PHP library that generates fake data for you.",
    "keywords": [
        "faker",
        "fixtures",
        "data"
    ],
    "license": "MIT",
    "authors": [
        {
            "name": "François Zaninotto"
        }
    ],
    "require": {
        "php": "^5.3.3 || ^7.0"
    },
    "require-dev": {
        "ext-intl": "*",
        "phpunit/phpunit": "^4.8.35 || ^5.7",
        "squizlabs/php_codesniffer": "^2.9.2"
    },
    "autoload": {
        "psr-4": {
            "Faker\\": "src/Faker/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Faker\\Test\\": "test/Faker/"
        }
    },
    "extra": {
        "branch-alias": {
            "dev-master": "1.9-dev"
        }
    },
    "config": {
        "sort-packages": true
    }
}

 

 

composer/composer

 

Composer helps you declare, manage, and install dependencies of PHP projects.

 

See https://getcomposer.org/ for more information and documentation.

 

see composer/composer on GitHub

 

{
    "name": "composer/composer",
    "type": "library",
    "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
    "keywords": [
        "package",
        "dependency",
        "autoload"
    ],
    "homepage": "https://getcomposer.org/",
    "license": "MIT",
    "authors": [
        {
            "name": "Nils Adermann",
            "email": "naderman@naderman.de",
            "homepage": "https://www.naderman.de"
        },
        {
            "name": "Jordi Boggiano",
            "email": "j.boggiano@seld.be",
            "homepage": "https://seld.be"
        }
    ],
    "require": {
        "php": "^5.3.2 || ^7.0 || ^8.0",
        "composer/ca-bundle": "^1.0",
        "composer/semver": "^3.0",
        "composer/spdx-licenses": "^1.2",
        "composer/xdebug-handler": "^1.1",
        "justinrainbow/json-schema": "^5.2.10",
        "psr/log": "^1.0",
        "seld/jsonlint": "^1.4",
        "seld/phar-utils": "^1.0",
        "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0",
        "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0",
        "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0",
        "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0",
        "react/promise": "^1.2 || ^2.7"
    },
    "require-dev": {
        "symfony/phpunit-bridge": "^4.2 || ^5.0",
        "phpspec/prophecy": "^1.10"
    },
    "suggest": {
        "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
        "ext-zip": "Enabling the zip extension allows you to unzip archives",
        "ext-zlib": "Allow gzip compression of HTTP requests"
    },
    "config": {
        "platform": {
            "php": "5.3.9"
        },
        "platform-check": false
    },
    "extra": {
        "branch-alias": {
            "dev-master": "2.0-dev"
        }
    },
    "autoload": {
        "psr-4": {
            "Composer\\": "src/Composer"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Composer\\Test\\": "tests/Composer/Test",
            "Composer\\PHPStanRules\\": "phpstan/Rules/src",
            "Composer\\PHPStanRulesTests\\": "phpstan/Rules/tests"
        },
        "classmap": [
            "phpstan/Rules/tests/data"
        ]
    },
    "bin": [
        "bin/composer"
    ],
    "scripts": {
        "compile": "@php -dphar.readonly=0 bin/compile",
        "test": "simple-phpunit"
    },
    "scripts-descriptions": {
        "compile": "Compile composer.phar",
        "test": "Run all tests"
    },
    "support": {
        "issues": "https://github.com/composer/composer/issues",
        "irc": "irc://irc.freenode.org/composer"
    }
}

 

 

guzzle/guzzle

 

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.

 

  • Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc...
  • Can send both synchronous and asynchronous requests using the same interface.
  • Uses PSR-7 interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle.
  • Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients.
  • Abstracts away the underlying HTTP transport, allowing you to write environment and transport agnostic code; i.e., no hard dependency on cURL, PHP streams, sockets, or non-blocking event loops.
  • Middleware system allows you to augment and compose client behavior.

 

see guzzle/guzzle on GitHub

 

{
    "name": "guzzlehttp/guzzle",
    "type": "library",
    "description": "Guzzle is a PHP HTTP client library",
    "keywords": [
        "framework",
        "http",
        "rest",
        "web service",
        "curl",
        "client",
        "HTTP client",
        "PSR-7",
        "PSR-18"
    ],
    "homepage": "http://guzzlephp.org/",
    "license": "MIT",
    "authors": [
        {
            "name": "Michael Dowling",
            "email": "mtdowling@gmail.com",
            "homepage": "https://github.com/mtdowling"
        },
        {
            "name": "Márk Sági-Kazár",
            "email": "mark.sagikazar@gmail.com",
            "homepage": "https://sagikazarmark.hu"
        }
    ],
    "require": {
        "php": "^7.2.5",
        "ext-json": "*",
        "guzzlehttp/promises": "^1.0",
        "guzzlehttp/psr7": "^1.6.1",
        "psr/http-client": "^1.0"
    },
    "provide": {
        "psr/http-client-implementation": "1.0"
    },
    "require-dev": {
        "ext-curl": "*",
        "ergebnis/composer-normalize": "^2.0",
        "php-http/client-integration-tests": "dev-phpunit8",
        "phpunit/phpunit": "^8.5.5",
        "psr/log": "^1.1"
    },
    "suggest": {
        "ext-curl": "Required for CURL handler support",
        "ext-intl": "Required for Internationalized Domain Name (IDN) support",
        "psr/log": "Required for using the Log middleware"
    },
    "config": {
        "sort-packages": true
    },
    "extra": {
        "branch-alias": {
            "dev-master": "7.1-dev"
        }
    },
    "autoload": {
        "psr-4": {
            "GuzzleHttp\\": "src/"
        },
        "files": [
            "src/functions_include.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "GuzzleHttp\\Tests\\": "tests/"
        }
    }
}

 

 

sebastianbergmann/phpunit

 

PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.

 

see sebastianbergmann/phpunit on GitHub

 

{
    "name": "phpunit/phpunit",
    "description": "The PHP Unit Testing framework.",
    "type": "library",
    "keywords": [
        "phpunit",
        "xunit",
        "testing"
    ],
    "homepage": "https://phpunit.de/",
    "license": "BSD-3-Clause",
    "authors": [
        {
            "name": "Sebastian Bergmann",
            "email": "sebastian@phpunit.de",
            "role": "lead"
        }
    ],
    "support": {
        "issues": "https://github.com/sebastianbergmann/phpunit/issues"
    },
    "prefer-stable": true,
    "require": {
        "php": ">=7.3",
        "ext-dom": "*",
        "ext-json": "*",
        "ext-libxml": "*",
        "ext-mbstring": "*",
        "ext-xml": "*",
        "ext-xmlwriter": "*",
        "doctrine/instantiator": "^1.3.1",
        "myclabs/deep-copy": "^1.10.1",
        "phar-io/manifest": "^2.0.1",
        "phar-io/version": "^3.0.2",
        "phpspec/prophecy": "^1.11.1",
        "phpunit/php-code-coverage": "^9.1.5",
        "phpunit/php-file-iterator": "^3.0.4",
        "phpunit/php-invoker": "^3.1",
        "phpunit/php-text-template": "^2.0.2",
        "phpunit/php-timer": "^5.0.1",
        "sebastian/cli-parser": "^1.0",
        "sebastian/code-unit": "^1.0.5",
        "sebastian/comparator": "^4.0.3",
        "sebastian/diff": "^4.0.2",
        "sebastian/environment": "^5.1.2",
        "sebastian/exporter": "^4.0.2",
        "sebastian/global-state": "^5.0",
        "sebastian/object-enumerator": "^4.0.2",
        "sebastian/resource-operations": "^3.0.2",
        "sebastian/type": "^2.2.1",
        "sebastian/version": "^3.0.1"
    },
    "require-dev": {
        "ext-PDO": "*",
        "phpspec/prophecy-phpunit": "^2.0.1"
    },
    "config": {
        "platform": {
            "php": "7.3.0"
        },
        "optimize-autoloader": true,
        "sort-packages": true
    },
    "suggest": {
        "ext-soap": "*",
        "ext-xdebug": "*"
    },
    "bin": [
        "phpunit"
    ],
    "autoload": {
        "classmap": [
            "src/"
        ],
        "files": [
            "src/Framework/Assert/Functions.php"
        ]
    },
    "autoload-dev": {
        "classmap": [
            "tests/"
        ],
        "files": [
            "tests/_files/CoverageNamespacedFunctionTest.php",
            "tests/_files/CoveredFunction.php",
            "tests/_files/NamespaceCoveredFunction.php"
        ]
    },
    "extra": {
        "branch-alias": {
            "dev-master": "9.4-dev"
        }
    }
}

 

 

phpmailer/phpmailer

 

Many PHP developers need to send email from their code. The only PHP function that supports this is mail(). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments.

 

Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong! Please don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own. Try SwiftMailer, Zend/Mail, ZetaComponents etc.

 

The PHP mail() function usually sends via a local mail server, typically fronted by a sendmail binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server.

 

see phpmailer/phpmailer on GitHub

 

{
    "name": "phpmailer/phpmailer",
    "type": "library",
    "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
    "authors": [
        {
            "name": "Marcus Bointon",
            "email": "phpmailer@synchromedia.co.uk"
        },
        {
            "name": "Jim Jagielski",
            "email": "jimjag@gmail.com"
        },
        {
            "name": "Andy Prevost",
            "email": "codeworxtech@users.sourceforge.net"
        },
        {
            "name": "Brent R. Matzelle"
        }
    ],
    "funding": [
        {
            "url": "https://github.com/synchro",
            "type": "github"
        }
    ],
    "require": {
        "php": ">=5.5.0",
        "ext-ctype": "*",
        "ext-filter": "*",
        "ext-hash": "*"
    },
    "require-dev": {
        "friendsofphp/php-cs-fixer": "^2.2",
        "phpunit/phpunit": "^4.8 || ^5.7",
        "doctrine/annotations": "^1.2"
    },
    "suggest": {
        "psr/log": "For optional PSR-3 debug logging",
        "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
        "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
        "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
        "ext-mbstring": "Needed to send email in multibyte encoding charset",
        "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
    },
    "autoload": {
        "psr-4": {
            "PHPMailer\\PHPMailer\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "PHPMailer\\Test\\": "test/"
        }
    },
    "license": "LGPL-2.1-only"
}

 

 

Become a Patron!

 

 

Conclusion

 

As I said previously Composer is one of the most important tools that you must learn if you want to take your career as a PHP developer seriously.

 

In this post, we have seen some of the first 10 commands now available on your arsenal.

 

as I said previously my advise is to read through them and try to understand what they do and what flag you may find more useful during your day to day job.

 

You don't need to learn every command and every flag by heart,

 

it would be enough for you to know that these commands exist and when to actually use them.

 

In the following posts, we are going to discover more command and some Composer tricks, for this reason, if you haven't done it already add your email to the subscription form and be notified as soon as the article comes out.

 

What you can do now?

 

after learning about tools it is good to go back and brush up you PHP knowledge, you can do that by reading the basics of PHP

 

Otherwise, you can jump on another series and learn about Domain-driven design.

 

 
 
If you like this content and you are hungry for some more join the Facebook's community in which we share info and news just like this one!

Other posts that might interest you

Coding (Php 7.x) Aug 28, 2020

Discovering Higher Order Functions [refactoring to Collections]

Adam Wathan book See details
Coding (Php 7.x) Nov 5, 2020

Introduction to Composer [all about repositories]

See details
Get my free books' review to improve your skill now!
I don't want to improve