Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Composer library


May 25, 2021 Composer


Table of contents


The repository

This chapter explains the concepts of packages and libraries, what repositories are available, and how they work.

Overview

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.

Package

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.

The repository

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.

Types

Composer

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

packages

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:

  • name
  • version
  • dist or source

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

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.

includes

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.

provider-includes and providers-url

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.

stream options

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

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.

Load a package from the VCS repository

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.

Use a private repository

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.

An alternative to Git

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.

Subversion option

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

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.

Custom vendor alias

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": "*"
    }
}

Package

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.

Hosting your own

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.

  • Separate ecosystem: If your project has its own ecosystem and your own resource pack doesn't need to be re-used by other projects, you might want to separate them from packagist.org. One example is a plug-in for wordpress.

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.

Packagist

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

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.

Artifact

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.

Disable Packagist

You can disable the default Packagist repository in composer.json

{
    "repositories": [
        {
            "packagist": false
        }
    ]
}