Skip to content

Instantly share code, notes, and snippets.

@igorw
Created October 15, 2013 15:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save igorw/6993738 to your computer and use it in GitHub Desktop.
\section{Basic usage}\label{basic-usage}
\subsection{Installation}\label{installation}
To install Composer, you just need to download the
\texttt{composer.phar} executable.
\begin{verbatim}
$ curl -sS https://getcomposer.org/installer | php
\end{verbatim}
For the details, see the \href{00-intro.md}{Introduction} chapter.
To check if Composer is working, just run the PHAR through \texttt{php}:
\begin{verbatim}
$ php composer.phar
\end{verbatim}
This should give you a list of available commands.
\begin{quote}
\textbf{Note:} You can also perform the checks only without downloading
Composer by using the \texttt{-{}-check} option. For more information,
just use \texttt{-{}-help}.
\begin{verbatim}
$ curl -sS https://getcomposer.org/installer | php -- --help
\end{verbatim}
\end{quote}
\subsection{\texttt{composer.json}: Project
Setup}\label{composer.json-project-setup}
To start using Composer in your project, all you need is a
\texttt{composer.json} file. This file describes the dependencies of
your project and may contain other metadata as well.
The \href{http://json.org/}{JSON format} is quite easy to write. It
allows you to define nested structures.
\subsubsection{The \texttt{require} Key}\label{the-require-key}
The first (and often only) thing you specify in \texttt{composer.json}
is the \texttt{require} key. You're simply telling Composer which
packages your project depends on.
\begin{verbatim}
{
"require": {
"monolog/monolog": "1.0.*"
}
}
\end{verbatim}
As you can see, \texttt{require} takes an object that maps
\textbf{package names} (e.g. \texttt{monolog/monolog}) to
\textbf{package versions} (e.g. \texttt{1.0.*}).
\subsubsection{Package Names}\label{package-names}
The package name consists of a vendor name and the project's name. Often
these will be identical - the vendor name just exists to prevent naming
clashes. It allows two different people to create a library named
\texttt{json}, which would then just be named \texttt{igorw/json} and
\texttt{seldaek/json}.
Here we are requiring \texttt{monolog/monolog}, so the vendor name is
the same as the project's name. For projects with a unique name this is
recommended. It also allows adding more related projects under the same
namespace later on. If you are maintaining a library, this would make it
really easy to split it up into smaller decoupled parts.
\subsubsection{Package Versions}\label{package-versions}
In the previous example we were requiring version \texttt{1.0.*} of
monolog. This means any version in the \texttt{1.0} development branch.
It would match \texttt{1.0.0}, \texttt{1.0.2} or \texttt{1.0.20}.
Version constraints can be specified in a few different ways.
\begin{longtable}[c]{@{}lll@{}}
\hline\noalign{\medskip}
Name & Example & Description
\\\noalign{\medskip}
\hline\noalign{\medskip}
Exact version & \texttt{1.0.2} & You can specify the exact version of a
package.
\\\noalign{\medskip}
Range & \texttt{\textgreater{}=1.0}
\texttt{\textgreater{}=1.0,\textless{}2.0}
\texttt{\textgreater{}=1.0,\textless{}1.1 \textbar{} \textgreater{}=1.2}
& By using comparison operators you can specify ranges of valid
versions. Valid operators are \texttt{\textgreater{}},
\texttt{\textgreater{}=}, \texttt{\textless{}}, \texttt{\textless{}=},
\texttt{!=}. You can define multiple ranges, separated by a comma, which
will be treated as a \textbf{logical AND}. A pipe symbol
\texttt{\textbar{}} will be treated as a \textbf{logical OR}. AND has
higher precedence than OR.
\\\noalign{\medskip}
Wildcard & \texttt{1.0.*} & You can specify a pattern with a \texttt{*}
wildcard. \texttt{1.0.*} is the equivalent of
\texttt{\textgreater{}=1.0,\textless{}1.1}.
\\\noalign{\medskip}
Tilde Operator & \texttt{\textasciitilde{}1.2} & Very useful for
projects that follow semantic versioning. \texttt{\textasciitilde{}1.2}
is equivalent to \texttt{\textgreater{}=1.2,\textless{}2.0}. For more
details, read the next section below.
\\\noalign{\medskip}
\hline
\end{longtable}
\subsubsection{Next Significant Release (Tilde
Operator)}\label{next-significant-release-tilde-operator}
The \texttt{\textasciitilde{}} operator is best explained by example:
\texttt{\textasciitilde{}1.2} is equivalent to
\texttt{\textgreater{}=1.2,\textless{}2.0}, while
\texttt{\textasciitilde{}1.2.3} is equivalent to
\texttt{\textgreater{}=1.2.3,\textless{}1.3}. As you can see it is
mostly useful for projects respecting \href{http://semver.org/}{semantic
versioning}. A common usage would be to mark the minimum minor version
you depend on, like \texttt{\textasciitilde{}1.2} (which allows anything
up to, but not including, 2.0). Since in theory there should be no
backwards compatibility breaks until 2.0, that works well. Another way
of looking at it is that using \texttt{\textasciitilde{}} specifies a
minimum version, but allows the last digit specified to go up.
\subsubsection{Stability}\label{stability}
By default only stable releases are taken into consideration. If you
would like to also get RC, beta, alpha or dev versions of your
dependencies you can do so using
\href{04-schema.md\#package-links}{stability flags}. To change that for
all packages instead of doing per dependency you can also use the
\href{04-schema.md\#minimum-stability}{minimum-stability} setting.
\subsection{Installing Dependencies}\label{installing-dependencies}
To fetch the defined dependencies into your local project, just run the
\texttt{install} command of \texttt{composer.phar}.
\begin{verbatim}
$ php composer.phar install
\end{verbatim}
This will find the latest version of \texttt{monolog/monolog} that
matches the supplied version constraint and download it into the
\texttt{vendor} directory. It's a convention to put third party code
into a directory named \texttt{vendor}. In case of monolog it will put
it into \texttt{vendor/monolog/monolog}.
\begin{quote}
\textbf{Tip:} If you are using git for your project, you probably want
to add \texttt{vendor} into your \texttt{.gitignore}. You really don't
want to add all of that code to your repository.
\end{quote}
Another thing that the \texttt{install} command does is it adds a
\texttt{composer.lock} file into your project root.
\subsection{\texttt{composer.lock} - The Lock
File}\label{composer.lock---the-lock-file}
After installing the dependencies, Composer writes the list of the exact
versions it installed into a \texttt{composer.lock} file. This locks the
project to those specific versions.
\textbf{Commit your application's \texttt{composer.lock} (along with
\texttt{composer.json}) into version control.}
This is important because the \texttt{install} command checks if a lock
file is present, and if it is, it downloads the versions specified there
(regardless of what \texttt{composer.json} says).
This means that anyone who sets up the project will download the exact
same version of the dependencies. Your CI server, production machines,
other developers in your team, everything and everyone runs on the same
dependencies, which mitigates the potential for bugs affecting only some
parts of the deployments. Even if you develop alone, in six months when
reinstalling the project you can feel confident the dependencies
installed are still working even if your dependencies released many new
versions since then.
If no \texttt{composer.lock} file exists, Composer will read the
dependencies and versions from \texttt{composer.json} and create the
lock file.
This means that if any of the dependencies get a new version, you won't
get the updates automatically. To update to the new version, use
\texttt{update} command. This will fetch the latest matching versions
(according to your \texttt{composer.json} file) and also update the lock
file with the new version.
\begin{verbatim}
$ php composer.phar update
\end{verbatim}
If you only want to install or update one dependency, you can whitelist
them:
\begin{verbatim}
$ php composer.phar update monolog/monolog [...]
\end{verbatim}
\begin{quote}
\textbf{Note:} For libraries it is not necessarily recommended to commit
the lock file, see also: \href{02-libraries.md\#lock-file}{Libraries -
Lock file}.
\end{quote}
\subsection{Packagist}\label{packagist}
\href{https://packagist.org/}{Packagist} is the main Composer
repository. A Composer repository is basically a package source: a place
where you can get packages from. Packagist aims to be the central
repository that everybody uses. This means that you can automatically
\texttt{require} any package that is available there.
If you go to the \href{https://packagist.org/}{packagist website}
(packagist.org), you can browse and search for packages.
Any open source project using Composer should publish their packages on
packagist. A library doesn't need to be on packagist to be used by
Composer, but it makes life quite a bit simpler.
\subsection{Autoloading}\label{autoloading}
For libraries that specify autoload information, Composer generates a
\texttt{vendor/autoload.php} file. You can simply include this file and
you will get autoloading for free.
\begin{verbatim}
require 'vendor/autoload.php';
\end{verbatim}
This makes it really easy to use third party code. For example: If your
project depends on monolog, you can just start using classes from it,
and they will be autoloaded.
\begin{verbatim}
$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');
\end{verbatim}
You can even add your own code to the autoloader by adding an
\texttt{autoload} field to \texttt{composer.json}.
\begin{verbatim}
{
"autoload": {
"psr-0": {"Acme\\": "src/"}
}
}
\end{verbatim}
Composer will register a
\href{https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md}{PSR-0}
autoloader for the \texttt{Acme} namespace.
You define a mapping from namespaces to directories. The \texttt{src}
directory would be in your project root, on the same level as
\texttt{vendor} directory is. An example filename would be
\texttt{src/Acme/Foo.php} containing an \texttt{Acme\textbackslash{}Foo}
class.
After adding the \texttt{autoload} field, you have to re-run
\texttt{install} to re-generate the \texttt{vendor/autoload.php} file.
Including that file will also return the autoloader instance, so you can
store the return value of the include call in a variable and add more
namespaces. This can be useful for autoloading classes in a test suite,
for example.
\begin{verbatim}
$loader = require 'vendor/autoload.php';
$loader->add('Acme\\Test\\', __DIR__);
\end{verbatim}
In addition to PSR-0 autoloading, classmap is also supported. This
allows classes to be autoloaded even if they do not conform to PSR-0.
See the \href{04-schema.md\#autoload}{autoload reference} for more
details.
\begin{quote}
\textbf{Note:} Composer provides its own autoloader. If you don't want
to use that one, you can just include
\texttt{vendor/composer/autoload\_namespaces.php}, which returns an
associative array mapping namespaces to directories.
\end{quote}
\href{00-intro.md}{Intro} \textbar{} \href{02-libraries.md}{Libraries}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment