Introduction to Composer [Command-line interface pt2]
Introduction
A few days ago I saw a meme in which it was written that the cooler sensation for a computer geek was to pretend to use the terminal in front of his peers.
In the beginning, it drew a smile upon my face but after pondering for a while I actually realized how misunderstood the usage of the command line really is.
I still remember quite vividly that to learn the basic command (ls, cd, cp, mv, clear, cat, etc) it took me only a few minutes and after some repetition, I have been using them without any problem for more than 2 decades.
Now I am not saying that we should ditch the mouse forever but as professional web developers, or aspiring one, we should realize that the CLI is still the best way to do things on your machine and there are software that in 2020 still used it as the only way to work on it.
A clear example of it is Composer
Composer is incredibly important,
In fact,
It changed the way PHP developer are making their project forever yet there is no interface, the only way to use its power is by writing command on a terminal.
And that’s what we are going to do today.
But before jumping on it a little foreword:
How to read this article
This is not a typical blog post.
In here you will see all the commands included in the Composer library, some are very common and are being used multiple time a day others are used only in specific cases.
The way you need to look at this post is to read through it and DISCOVER what command you might use , then come here again every now and then to check if there are any commands you can implement in your working routine.
The series
This article is part of the series Introduction to Composer,
If you haven't read the previous part already head to
The Commands
In total Composer includes around 30 commands,
The beautiful fact is that you do not need to know all of them, on the contrary, you probably are only going to use the same 5 to 10-ish.
but, this does not mean that you shouldn’t know that these commands exist and what they do.
Right?
Storytime:
Imagine for a second to work on a PHP project, and your boss tells you that you need to calculate the number of characters that two words differ between each other.
Something similar at the “Did you mean” feature of Google when you enter a typo.
Now think that you wasted hours and hours trying to calculate the best algorithm to do that.
and then months after you discover that this calculation actually has a name and that PHP has a built-in function that does exactly that and it takes one line.
Maybe is not clear by my world but that’s what happened to me just because I had not spent enough time reading the documentation.
As a friend let me tell you.
It is good to learn from your mistake, it is better to learn from other people mistakes.
Below we are going to see the list of commands that were not included in part one and an easy-to-understand explanation of each of them and the flag you can include.
Sound good?
Let’s jump into it!
composer browse / home
The browse and the home command perform the same command (they are alias)
These commands open a package's repository URL or homepage in your default browser.
An example of how this command can be used is:
composer browse guzzlehttp/guzzle
This is going to open your favourite browser and redirect you to the guzzle gitHub official page
They require the name of the package to browse to and also they have a few flags that I have listed below:
| -H --homepage | Open the homepage instead of the repository URL. |
| -s--show | Only show the homepage or repository URL. |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer suggests
The suggests command shows a sorted list of suggested packages by currently installed set of packages.
If you want, you can pass one or several package names in the format of vendor/package to limit output to suggestions made by those packages only.
This command has a few flag specific for its case
- The --by-package groups the output by the package offering the suggestions and it is the default behaviour of Composer
- --by-suggestion groups the output by the suggested packages respectively.
- You can also opt to only have a simple list of suggested package names, using --list.
The other flags usable with the suggest command are:
|
--by-package
| Groups output by suggesting a package |
| --by-suggestion | Groups output by suggested package |
| --no-dev | Exclude suggestions from require-dev packages |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer fund
As you may be aware of several (actually a lot) of packages are open source or created for free by one or a group of fantastic people that what to improve the world we live in.
Some of these packages may need some help to survive.
The composer fund command writes down a list of all the useful links ordered by the package, that can be used to help those creators out.
What you have to do is just type the command and wait for Composer to show you the list.
This command also can be used with some basic flags
They are:
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer depends & composer why
These two commands are an alias,
The depends and the why commands show us which other packages depend on a certain package.
Like installation, require-dev relationships are only considered for the root package.
If we need to, we can also specify a version constraint after the package to limit the results of the search.
Add the --tree or -t flag to show a tree of why the package is depended upon.
The complete list of flags is:
Options:
|
-r, --recursive
| Recursively resolves up to the root package |
| -t, --tree | Prints the results as a nested tree |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer prohibits (why-not)
Not all packages can be installed, or for better saying, not all the packages can be installed without incurring in problems.
Sometimes a package that you want to install is blocked by another one or its constraint.
If that’s the case you can use the commands composer prohibits or composer why-not and it will show you which packages are blocking your package from being installed.
Composer also specifies a version constraint to verify whether upgrades can be performed in your project, and if not why not.
A very useful feature is the one that let you specify the platform requirements, for example (taken straight from the official documentation).
You can check whether you can already upgrade your server to PHP 8.0:
composer prohibits php:8
doctrine/cache v1.6.0 requires php (~5.5|~7.0)
doctrine/common v2.6.1 requires php (~5.5|~7.0)
doctrine/instantiator 1.0.5 requires php (>=5.3,<8.0-DEV)
Like the depends command if you want you can get a recursive lookup (flag -r or --recursive), which will list all packages depending on the packages that cause the conflict.
The flags for this command are:
|
-r, --recursive
| Recursively resolves up to the root package |
| -t, --tree | Prints the results as a nested tree |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer validate
The validate command validates a given composer.json and composer.lock.
It is a sort of JSON link for these two files.
As a rule of thumb, you should ALWAYS run the validate command before you commit your composer.json file, also it is a good practice to validate it before you tag a release.
There are 4 possible results from this command:
- The JSON is actually ok and you will see a nice “./composer.json is valid”
- validation warnings, when --strict is given
- validation error or errors
- If there is a fatal error with the file you’ll get “file unreadable or missing”
Note that you can actually specify which file you want to validate just attaching the name of the file after validate
This command as it own flags that are:
| --no-check-all | Do not validate requires for overly strict/loose constraints |
| --no-check-lock | Do not check if the lock file is up to date |
| --no-check-publish | Do not check for publishing errors |
| -A, --with-dependencies | Also validate the composer.json of all installed dependencies |
|
--strict
| Return a non-zero exit code for warnings as well as errors |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer status
The status command allows you to check if you have local changes in any of your dependencies.
This is especially useful in case you need to modify the code of your dependencies very frequently and these are installed from source.
The results show a list of dependencies that have been modified locally.
With the status command you can use the following flag:
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer self-update & composer selfupdate
This command does not work on the dependencies but rather on Composer itself.
You can type it both way with a hash that divides the two words or all together (no camelcase necessary).
What this command does is to check if there are more update version of the package manager on getcomposer.org.
if a newer version is found, installs it automatically.
You can also specify a version you want by writing it as the last attribute of the command.
composer self-update 1.0.0-alpha7
The flags for this one are:
| -r, --rollback | Revert to an older installation of composer |
| --clean-backups | Delete old backups during an update. This makes the current version of composer the only backup available after the update |
| --no-progress | Do not output download progress. |
| --update-keys | Prompt user for a key update |
| --stable | Force an update to the stable channel |
| --preview | Force an update to the preview channel |
| --snapshot | Force an update to the snapshot channel |
| --1 | Force an update to the stable channel, but only use 1.x versions |
| --2 | Force an update to the stable channel, but only use 2.x versions |
|
--set-channel-only
| Only store the channel as the default one and then exit |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer config
With composer config, you can edit the settings and repositories in either the local composer.json file or the global config.json file.
Additionally, this command lets you edit most properties in the local composer.json.
setting-keys are configurations option name and setting-values are configurations value.
Some settings can take an array of values (like github-protocols), for them more than one setting-value argument are allowed.
You can also edit the values of the several properties, they are description, homepage, keywords, license, minimum-stability, name, prefer-stable, type and version.
There are really a lot of different setting keys and setting values you can use this command with.
To get how they work I suggest using the examples provided as a helper from the terminal (by using composer config -h)
Flags for this command are -g, --global Apply command to the global config file:
| -e, --editor | Open editor |
| -a, --auth | Affect auth config file (only used for --editor) |
| --unset | Unset the given setting-key |
| -l, --list | List configuration settings |
| -f, --file=FILE | If you want to choose a different composer.json or config.json |
|
--absolute
| Returns absolute paths when fetching *-dir config values instead of relative |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer create-project
Here is a little trick that not many know and that can be useful when GitHub act as flaky,
You can use the composer create-project command to create a brand-new project based on an already existing package.
Doing this is like if you are doing git clone and then composer install.
Some of the most frequent use of it is when you can deploy application packages or your project has multiple developers, and they can use this feature to bootstrap the initial development application.
To use this command you just type composer create-project then use the package name as an argument.
Of course,
if you need to you can provide a version as the third argument, by default however the latest version found is used.
Note that in case the directory does not exist already, the composer will create it during the installation.
If you want to use a new or insatiable branch you have to add the flag --stability=dev or, of course, manually specify the version you prefer.
As you can see there are multiple features on this command, it also has plenty of flags you can use it with.
| -s, --stability=STABILITY | Minimum-stability allowed (unless a version is specified). |
| --prefer-source | Forces installation from package sources when possible, including VCS information. |
| --prefer-dist | Forces installation from package dist even for dev versions. |
| --repository=REPOSITORY | Pick a different repository (as URL or JSON config) to look for the package. |
| --repository-url=REPOSITORY-URL DEPRECATED: | Use --repository instead. |
| --add-repository | Add the repository option to the composer.json. |
| --dev | Enables installation of require-dev packages (enabled by default, only present for BC). |
| --no-dev | Disables the installation of require-dev packages. |
| --no-custom-installers DEPRECATED: | Use no-plugins instead. |
| --no-scripts | Whether to prevent the execution of all defined scripts in the root package. |
| --no-progress | Do not output download progress. |
| --no-secure-http | Disable the secure-http config option temporarily while installing the root package. Use at your own risk. Using this flag is a bad idea. |
| --keep-vcs | Whether to prevent deleting the vcs folder. |
| --remove-vcs | Whether to force deletion of the vcs folder without prompting. |
| --no-install | Whether to skip installation of the package dependencies. |
|
--ignore-platform-reqs
| Ignore platform requirements (php & ext- packages). |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer dump-autoload (or dumpautoload)
This is one of the commands that I personally use most often.
If you add one or many new classes in your project you NEED TO UPDATE the autoloader so it can take them into account,
the most logical way to do that is by installing or updating composer.
Problem is that these practices are time-consuming and not very performant.
What you can do instead is to use composer dump-autoload to update the autoloader.
If you are in a production environment can be a good idea to converts PSR-0/4 packages into classmap ones.
The reason is that, depending on the size of your application, the autoloader can become a big beast so this trick improves its performance.
You can use composer dump-autoload with the standard flags:
| --no-scripts | Skips the execution of all scripts defined in composer.json file. |
| -o, --optimize | Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production. |
| -a, --classmap-authoritative | Autoload classes from the classmap only. Implicitly enables --optimize
. |
| --apcu | Use APCu to cache found/not-found classes. |
|
--no-dev
| Disables autoload-dev rules. |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer clear-cache / clearcache / cc
Having good performances is a big goal for our application, the guys at composer know that so the implemented a feature that saves packages from composer's cache directory.
Well, there are some times where you want to refresh them or you do not want them in the cache.
This command deletes everything inside the cache.
Flags are:
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer licenses
Nothing complicated here,
Each package has been created by a developer,
he/she can choose under what license leave his/her package.
the command Composer licenses lists all the packages present in the project and what type of license they have.
Flags are:
| -f, --format=FORMAT | Format of the output: text or JSON [default: "text"] |
| --no-dev | Disables search in require-dev packages. |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer run-script
Maybe that’s new to you but composer.json can have and run several scripts.
The composer run-script command runs the scripts that are defined in the _composer.json _file.
For the record they look like this:
{
"scripts": {
"post-update-cmd": "MyVendor\\MyClass::postUpdate",
"post-package-install": [
"MyVendor\\MyClass::postPackageInstall"
],
"post-install-cmd": [
"MyVendor\\MyClass::warmCache",
"phpunit -c app/"
],
"post-autoload-dump": [
"MyVendor\\MyClass::postAutoloadDump"
],
"post-create-project-cmd": [
"php -r \"copy('config/local-example.php', 'config/local.php');\""
]
}
}
This command also can be used alongside one or more flags:
|
--timeout=TIMEOUT
| Sets script timeout in seconds, or 0 for never. |
| --dev | Sets the dev mode. |
| --no-dev | Disables the dev mode. |
| -l, --list | List scripts. |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer exec
This command executes the binary you specified as an attribute.
You can execute any command and this will ensure that the Composer bin-dir is pushed on your PATH before the command runs.
To check what binaries are available on your project type:
composer exec --list
Other useful flags you can use with this command are:
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer diagnose
The diagnose command checks common errors to help to debug problems.
This is very useful in case you think you have a bug in your application.
You might want to run the diagnose command to perform automated checks for many common problems.
The process exit code will be 1 in case of warnings and 2 for errors.
The result of this command looks something like this:
Checking composer.json: OK
Checking platform settings: OK
Checking git settings: OK
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com oauth access: OK
Checking disk free space: OK
Checking pubkeys:
Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0 87719BA6 8F3BB723 4E5D42D0 84A14642
Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B 0C708369 153E328C AD90147D AFE50952
OK
Checking composer version: You are not running the latest stable version, run `composer self-update` to update (1.10.8 => 1.10.10)
Composer version: 1.10.8
PHP version: 7.3.15
PHP binary path: /usr/local/Cellar/php@7.3/7.3.15/bin/php
OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019
This command does not have special flags but supports all the default one:
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
composer archive
This command generates a zip or a tar archive for a given package in a given version that you provide as the attribute.
It can also be used to archive your entire project without excluded/ignored files.
This archive will contain the files and directories of the Composer project or the specified package in the specified version and writes it to a specified directory.
Here is how it works:
composer archive phpunit 9.2.2 --format=zip --dir=/myFolder
The flags for this command are as following:
|
-f, --format=FORMAT
| Format of the resulting archive: tar or zip |
| --dir=DIR | Write the archive to this directory |
| --file=FILE | Write the archive with the given file name. Note that the format will be appended. |
| --ignore-filters | Ignore filters when saving package |
| -h --help | Display this help message |
| -q, --quiet | Do not output any message |
| -V, --version | Display this application version |
| --ansi | Force ANSI output |
| --no-ansi | Disable ANSI output |
| -n, --no-interaction | Do not ask any interactive question |
| --profile | Display timing and memory usage information |
| --no-plugins | Whether to disable plugins. |
| -d, --working-dir=WORKING-DIR | If specified, use the given directory as the working directory. |
| --no-cache |
Prevent use of the cache
|
| -v|vv|vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug |
Conclusion
Here is the end of what is the command of Composer,
As I said previously you do not need to know them all ,
I can assure you that there are a few of them that you will never actually use.
But, it is very good to know that these commands exist and coming here and reading about that can help you solve problems in half of the time.
Once you have done it and if you want to get back to PHP you can about some hidden gem in the basics of PHP article.
Otherwise, feel free to start another series,
fancy learning about Design Patterns, in here we walk about the Factory Method Pattern in PHP.