May 25, 2021 Composer
This chapter explains the concepts of packages and libraries, what repositories are available, and how they work.
Before we look at the existence of different types of libraries, we need to understand some basic concepts to understand how Composer is built on them.
Composer is a dependency management tool. I t installs some resource packs locally. A package is essentially a directory of things. U sually it stores PHP code, but in theory it can be anything. And it contains a description with a name and a version number that identifies the package.
In fact, each version is treated as a separate package within the composer. Although this distinction doesn't matter when you use composer, it's important when you want to change it.
In addition to the name and version number, useful metadata is stored. C losest to the installation is the source information, which states where the contents of the resource pack are available. Package data points to the contents of the package in two ways: dist and source.
Dist: Dist points to an archive that packages data for a version of a resource pack. This is usually a stable version that has already been released.
Source: Source points to a source in development. T his is usually a source code repository, such as git. This is available when you want to modify the downloaded resource pack.
You can use either of them, or at the same time. This depends on other factors, such as the "user-supplied option" and "package stability", which will be preferred.
A repository is the source of a package. I t is a list of packages/versions. Composer will look at all the repositories you define to find the resource packs your project needs.
By default, the Packagist.org registered with Composer.
You can
composer.json
and add them to your project.
The definition of a repository can only be used for "root packages" and the repository defined in the package on which you depend will not be loaded. If you want to know why, read FAQ entry.
The type of the main repository is
composer
It uses a single
packages.json
that contains all the resource pack metadata.
This is packagist.org resources used by the computer. T
o reference a
composer
you only need to provide a
packages.json
file.
F
or example,
packagist.org
/packages.json
its URL should
packagist.org
The
example.org/packages.json
should be
example.org
The only field that is required
packages
Its JSON structure is as follows:
{
"packages": {
"vendor/package-name": {
"dev-master": { @composer.json },
"1.0.x-dev": { @composer.json },
"0.0.1": { @composer.json },
"1.0.0": { @composer.json }
}
}
}
@composer.json
will read
composer.json
content from the specified version of this package, which should contain at least the following information:
This is the simplest package definition:
{
"name": "smarty/smarty",
"version": "3.1.7",
"dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip"
}
}
It can also contain any fields described in the composer.json schema.
notify-batch
field allows you to specify a URL that will be called when the user installs each package.
The URL can be an absolute path (for the same domain name as its repository) or a full URL address.
For example, use the following values:
{
"notify-batch": "/downloads/"
}
For
example.org/packages.json
monolog/monolog
in the file, it
POST
request to the
example.org/downloads/
using the following JSON request body:
{
"downloads": [
{"name": "monolog/monolog", "version": "1.2.1.0"},
]
}
version
field will contain a standardized version number.
notify-batch
field is optional.
For larger libraries, you can split
packages.json
into multiple files.
includes
field allows you to reference these additional files.
Instance:
{
"includes": {
"packages-2011.json": {
"sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
},
"packages-2012-01.json": {
"sha1": "897cde726f8a3918faf27c803b336da223d400dd"
},
"packages-2012-02.json": {
"sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
}
}
}
The SHA-1 code of the file allows it to be cached and re-requested only when the hash value changes.
This field is optional. You may not need it to customize the repository.
For very large libraries, such as packagist.org using so-called provider files is the preferred method.
provider-includes
field allows you to set a list to state the package name provided by this repository.
In this case, the hash algorithm of the file must use sha256.
providers-url
how to find these provider files on the server.
It is an absolute path that starts with the root of the repository.
Instance:
{
"provider-includes": {
"providers-a.json": {
"sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c"
},
"providers-b.json": {
"sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac"
}
},
"providers-url": "/p/%package%$%hash%.json"
}
These files contain the name of the resource pack and hash values to verify the integrity of the files, such as:
{
"providers": {
"acme/foo": {
"sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82"
},
"acme/bar": {
"sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233"
}
}
}
The above file states that
acme/foo
acme/bar
can be found in this
providers-url
the package name and replacing the value
%hash%
sha256 by loading the file referenced by providers-url.
%package%
These files themselves contain only the definition of packages mentioned above.
These fields are optional. You may not need them to customize the repository.
packages.json
files are loaded with a PHP stream. Y
ou can
options
parameter to set additional flow information. Y
ou can set any valid PHP flow context option.
For more information, check
out Context options and parameters.
VCS represents the version control system. T his includes version management systems such as git, svn, or hg. Composer has a resource type from which packages can be installed from these systems.
Here are a few use cases. T
he most common is to maintain a third-party library that maintains its own fork. I
f you use some libraries in your project and you decide to change something in those libraries, you'll want your project to use your own version of the fix. I
f this library is on GitHub (which often happens), you can simply fork it and push your changes into this fork. A
fter that you update the
composer.json
file, add your fork as a repository, and change the version constraints to point to your custom branch.
For a naming convention for version constraints,
check out the Library (Resource Pack).
For example, suppose you fork a monolog and fix a bug in the
bugfix
branch:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
When you
php composer.phar update
you should get the version you modified instead of
monolog/monolog
Note that you should not rename the package unless you really intend to get rid of the original package and use your own fork for the long term. T hat way Composer will get your package correctly. If you are sure that you want to rename the package, you should operate on the default branch (usually the master branch) instead of the attribute branch, because the name of the package is taken from the default branch.
If other packages depend on this branch of your fork, you may need to set it as an in-line alias for the version number to accurately identify the version constraint. For more information, see Alias.
The exact same solution also lets you work with a private code base on your GitHub and BitBucket:
{
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "[email protected]:vendor/my-private-repo.git"
}
]
}
The only requirement is to install the SSH key for a git client.
Git is not the only version management system supported by the VCS repository.
The following are supported:
In order to get resource packs from these systems, you must install the corresponding client, which may be inconvenient. F
or this reason, special support is provided for the GitHub and BitBucket APIs to obtain resource packs without installing a version control system.
Get the zip archive in the
dist
the VCS repository.
The VCS driver automatically detects the repository type based on the URL.
But if possible, you need to explicitly
git
svn
hg
as the repository
vcs
If you set the
no-api
key to
true
on a github repository it will clone the repository as it would with any other git repository instead of using the GitHub API.
But unlike using the
git
driver directly, composer will still attempt to use github's zip files.
Because Subversion does not have a native branch and label concept, Composer assumes that by default the
$url/trunk
$url/branches
$url/tags
I
f your repository uses a different layout, you can change these values.
For example, if you use a capital name, you can configure the repository like this:
{
"repositories": [
{
"type": "vcs",
"url": "http://svn.example.org/projectA/",
"trunk-path": "Trunk",
"branches-path": "Branches",
"tags-path": "Tags"
}
]
}
If you don't have any branches or label folders in your repository directory,
branches-path
tags-path
to
false
If it is a package located in a subdirectdirecte, for example,
/trunk/foo/bar/composer.json
/tags/1.0/foo/bar/composer.json
then you can let the composer access the subdirectdirecte set by the
"package-path"
this example can be set to
"package-path": "foo/bar/"
pear
type repository makes it possible to install resource packs from any PEAR channel. C
omposer adds prefixes (similar to
pear-{渠道名称}/
to avoid conflicts.
Prefixes (such as pear-channel alias) are also
pear-{渠道别名}/
For example,
pear2.php.net
{
"repositories": [
{
"type": "pear",
"url": "http://pear2.php.net"
}
],
"require": {
"pear-pear2.php.net/PEAR2_Text_Markdown": "*",
"pear-pear2/PEAR2_HTTP_Request": "*"
}
}
In this case, the short name (alias) of the channel is
pear2
PEAR2_HTTP_Request
the package should be
pear-pear2/PEAR2_HTTP_Request
Note: The
pear
of the pear type does a complete request for each requires, so installation speed can be significantly reduced.
It is allowed to alias the PEAR channel package by customizing the vendor name.
Cases:
Suppose you have a private PEAR library and want to use Composer to integrate dependencies from VCS. Your PEAR library contains the following resource packs:
BasePackage
。
IntermediatePackage
BasePackage
TopLevelPackage1
TopLevelPackage2
rely
IntermediatePackage
If there is no vendor alias, Composer uses the PEAR channel name as part of the package name:
pear-pear.foobar.repo/BasePackage
pear-pear.foobar.repo/IntermediatePackage
pear-pear.foobar.repo/TopLevelPackage1
pear-pear.foobar.repo/TopLevelPackage2
Suppose that at some point after that, you want to migrate your PEAR package, use the Composer repository and naming
foobar
the vendor name.
Projects that previously used pear packages will not see updated resource packs because they have different vendor names
foobar/IntermediatePackage
and
pear-pear.foobar.repo/IntermediatePackage
You can avoid this by specifying
vendor-alias
to the PEAR repository from the start to get a package name that won't go out of style.
To illustrate this point, the following example gets
BasePackage
TopLevelPackage1
and
TopLevelPackage2
resource packs from your PEAR repository, and
IntermediatePackage
repository:
{
"repositories": [
{
"type": "git",
"url": "https://github.com/foobar/intermediate.git"
},
{
"type": "pear",
"url": "http://pear.foobar.repo",
"vendor-alias": "foobar"
}
],
"require": {
"foobar/TopLevelPackage1": "*",
"foobar/TopLevelPackage2": "*"
}
}
If you want to use a project that doesn't support composer in any of these ways, you can still use
package
type to define the repository.
Basically, you can define the same information as the
composer
in
packages.json
but you need to define each such resource pack separately.
Similarly, at a minimum, you should include the
name
version
dist
source
This is an example of a smarty template engine:
{
"repositories": [
{
"type": "package",
"package": {
"name": "smarty/smarty",
"version": "3.1.7",
"dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip"
},
"source": {
"url": "http://smarty-php.googlecode.com/svn/",
"type": "svn",
"reference": "tags/Smarty_3_1_7/distribution/"
},
"autoload": {
"classmap": ["libs/"]
}
}
}
],
"require": {
"smarty/smarty": "3.1.*"
}
}
Usually you don't need to
source
because you don't really need it.
Note: The library type has the following limitations, so you should avoid using it as much as possible:
- Composer will not update the resource pack unless you modify
version
field.- Composer will not update commit references, so if you
master
reference, you will have to delete the package to force the update, and you will have to face an unstable lock file.
Although most of the time you'll probably put your resource pack on packagist.org, you'll also be told some use cases here so that you can host your own repository.
Private company packages: If you're an employee of a company that uses composer for internal resource packs, you might want to keep them private.
For self-hosted packages, it is recommended to
composer
type repository setting, which provides the best performance.
Here are some tools to help you create a
composer
resources.
The bottom layer of the packagist is open source. T his means you can just install your own copy of the packagist, retrofit it and use it. I t's really straightforward and simple. However, due to its size and complexity, Satis is recommended for most SMEs.
Packagist is a Symfony2 application and is hosted on GitHub github.com/composer/packagist. I t uses composer internally and acts as a proxy between the VCS repository and the composer user. It has a list of all VCS resource packs, periodically re crawls them, and serves them as a composer repository.
To set up your copy, simply follow github.com/composer/packagist of the list.
Satis is a static
composer
repository generator.
It's like an ultra-lightweight, static file-based version of packagist.
You give it a
composer.json
defining the VCS and the repository.
It gets all the packages you list and
packages.json
as a repository
composer
composer types.
For more details, github.com/composer/satis and Satis article.
In some cases, you may not be able to have any of the online repositories mentioned earlier. T
ypical example could be cross-organisation library exchange through built artifacts。 O
f course most of the time they are private.
To simplify maintenance, you can simply
artifact
repository type to refer to a folder that contains ZIP archives of those private packages:
{
"repositories": [
{
"type": "artifact",
"url": "path/to/directory/with/zips/"
}
],
"require": {
"private-vendor-one/core": "15.6.2",
"private-vendor-two/connectivity": "*",
"acme-corp/parser": "10.3.5"
}
}
Each zip artifact is just a ZIP archive, placed at
composer.json
unzip -l acme-corp-parser-10.3.5.zip
composer.json
...
If you have two different versions of the resource pack, they are imported.
When a new version of the archive is added to the artifact folder, and
update
command, that version is imported and Composer updates to the latest version.
You can disable the default Packagist repository in
composer.json
{
"repositories": [
{
"packagist": false
}
]
}