Sharing your Symfony code using Packagist and Composer

Reusing code in is a common practise for developers to avoid repetition. Instead of copying around a bunch of files like in the past, the modern developer toolchain includes package managers and shared repositories. Using shared code is a must for developers working with Symfony, but sharing your own functionality is not as common. Let's learn how to do it.

Symfony is built using the PHP programming language. In addition to the core language and frameworks (like Symfony) built with it there is an ecosystem of tools. The most common mechanism to share code is using the Composer package manager. This piece of software manages dependencies of software components needed for a project. It manages the complexity of finding the correct combination of packages and installs them to your project.

Composer is a client application that needs to be backed by a repository of code. A repository is a central collection of code with attached metadata such as version data, other dependencies, etc. You can host your own repository, but the PHP community mostly uses the Packagist.org repository. At the time of writing there are over 272,000 individual packages hosted on Packagist.

As a practical example, let's examine the steps needed to share the eZ Platform field type contents conversion command created in a previous blog post. It is useful across projects that makes it worth sharing. It is also simple enough to use as an example. It also integrates into the Symfony Framework making it ready to use right after installation without configuration.

There are four steps needed in publishing a piece of Symfony functionality on Packagist:

  • Wrap your code in a Symfony Bundle
  • Add Composer metadata
  • Push to a GitHub (or other) repository
  • Publish on Packagist

The bundle system in Symfony is a mechanism to package code, configuration, templates, etc. into a single package. There's a lot you can do, and if you're interested I recommend watching the SymfonyCasts screencast: Creating a Reusable (& Amazing) Symfony Bundle

Today we are packaging a single console command, so we'll need the following in our Bundle:

  • Bundle boilerplate
  • Services configuration file
  • Command code

The boilerplate code includes the Bundle class and the dependency injection class. They load the included services configuration file in YAML format. With these in place the Symfony framework can bootstrap our bundle and load the heart of our application: the console command to convert image field contents to image asset fields using the eZ Platform PHP API.

With our code in place we'll need to add metadata for the Composer package manager. This is stored in the composer.json file at the root. The easiest way to generate it with Composer:

$ composer init

  Welcome to the Composer config generator

This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [janit/ezplatform-migrate-image-asset]: 
Description []: Copy eZ Platform image field contents to image asset field type
Author [, n to skip]: n
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []: symfony-bundle
License []: MIT

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no

{
    "name": "janit/ezplatform-migrate-image-asset",
    "description": "Copy eZ Platform image field contents to image asset field type",
    "type": "symfony-bundle",
    "license": "MIT",
    "require": {}
}

Do you confirm generation [yes]? yes
$ 

In the above configuration place special focus on the package name. The package name should match the package name you will have on Packagist. If your package needs other dependencies, etc. you should list them here so Composer can resolve all the dependencies like other libraries, etc. In our case our package has no external dependencies, so we don't need anything here.

Once your code is complete, create a repository on GitHub or elsewhere and push your code there. Publishing on packagist.org is straightforward. Once you've logged in you can submit a package from the top menu. For this you will need a repository URL (Git, Subversion or Mercurial), you can enter your newly created repository. Submit your package and move forward.

Packagist will now pull your packages' metadata from the repository and publish it in the public catalogue. Please note that you will need to have a proper version tagged in your repository, to learn how to do this learn more about Versions and Constraints in the Composer documentation.

Once everything is verified your package is published and you can install it with Composer:

composer require janit/ezplatform-migrate-image-asset

To see how the publishing process works you can watch the video below:

Insights and News