This is a simple step-by-step guide to making a PHP composer package that can be listed publicly on packagist.org for anyone in the world to install. We’ll be using Github to update the package. We’ll also add some testing with PHPUnit.
The basic steps to creating a new composer package are as follows.
composer init
composer install
git tag 0.0.1
then git push --tags
After following these steps, your package should now be published on packagist. Any future changes you make should be pushed to Github and make a new tag like this… git tag 0.0.2
and git push --tags
. You can list all the tags with git tag
. Every time you update in this way, Github will get updated, and packagist will also get updated automatically.
Our class is called Bar, so our main PHP file has to be Bar.php (upper/lowercase matters!). We’ll put it in a directory called “src”…
<?phpnamespace Foo;class Bar {public function helloworld(){return 'Hello, World!';}}
Here is a sample composer.json file. Our namespace is “Foo” so we say that Foo is in the src directory in the composer.json…
{"name": "foo/bar","license": "MIT","require": {"php": "^7.0"},"require-dev": {"phpunit/phpunit": "^5.7"},"autoload": {"psr-4": {"Foo\\": "src/"}}}
To use the package, import it by copy/pasting the command line instructions from Packagist. It’ll be something like this… composer require foo/bar
. Then, once the package has been installed into the vendor directory, you can start using it, like this, for example…
<?phprequire_once 'vendor/autoload.php';$test = new Foo\Bar();$test->helloworld();
For testing purposes. Each time you update you need to make sure the latest version is downloaded from Packagist.
Make sure the composer.json of the project you’re inporting the package into has a composer.json like this. You’ll need to make sure the package you’re testing is greater than or equals to >=
instead of ^
which specifies an exact version.
{"name": "neil/test","authors": [{"name": "neil","email": "[email protected]"}],"require": {"foo/bar": ">=0.4.3","phpunit/phpunit": "^6.5"}}
But, even then composer update
may still not do anything when you update the package. You may need to composer clearcache
first, then update composer. Also, sometimes there is a short lag in Packagist updating so don’t get too worried if it doesn’t update straight away first time.
To add testing you might want to use something like PHPUnit or PHPSpec. This is using PHPUnit 6.5 which runs with PHP 7.0…
composer require --dev phpunit/phpunit
Make a directory called tests and make a file called BarTest.php…
<?phpdeclare(strict_types=1);use PHPUnit\Framework\TestCase;use Foo\Bar;final class BarTest extends TestCase{public function testOutputsExpectedTestString(){$this->assertEquals('Hello, World!',Bar::helloworld());}}
Then, making sure you’re using the “dev” packages you can run the test in the command line like so…
vendor/bin/phpunit --bootstrap vendor/foo/bar/src/Bar.php vendor/foo/bar/tests/BarTest
Unit tests will only work on public functions, not private functions.
The name of the class must be exactly the same as the filename, and vice versa. If your class is called SomeClass, the file must be SomeClass.php.
Errors can also come from not using git tag to create a version or not having all the info packagist needs in the composer.json.
Quick Links
Legal Stuff