Telephone: 379 14 89 430
Opening hours: Monday to Friday, 9:00 a.m. to 6:00 p.m.
12 May 2025
Publishing a Composer package means making your code installable with a simple CLI command.
composer require vendor/package
and keeping updates, versions, and dependencies under control.
To follow the guide, we need:
$PATHReferring back to the article where we explored how to develop a descriptive statistics library, the repository structure was as follows:
descriptive-statistics-php/
├─ composer.json
├─ composer.lock
├─ phpunit.xml
├─ examples/
│ └─ geometric_mean_demo.php
│ └─ harmonic_mean_demo.php
│ └─ iqr_demo.php
│ └─ mad_demo.php
│ └─ mean_demo.php
│ └─ median_demo.php
│ └─ min_max_demo.php
│ └─ mode_demo.php
│ └─ percentile_demo.php
│ └─ range_demo.php
│ └─ standard_deviation_demo.php
│ └─ trimmed_mean_demo.php
│ └─ variance_demo.php
├─ src/
│ └─ DescriptiveStats.php
├─ tests/
│ └─ DescriptiveStatsTest.php
└─ vendor/
└─ autoload.phpIn the terminal, inside the project folder, we type the command:
composer init
Composer will ask us for some information, starting with the package name, which is expressed as vendor/package-name. In my case, since my account is named “thesimon82”, the package name will be thesimon82/descriptive-statistics. We confirm by pressing Enter.
Now we are asked for the description—
for this project, we’ll enter: Lightweight PHP class for descriptive statistics.
Next is the author field: if we’ve already configured it previously, Composer will show a default author; otherwise, we enter our name and surname manually.
Minimum stability: if it’s a stable release, we enter “stable”.
For Package Type, we enter: “library”.
In license: MIT
We are then asked whether we want to add, one by one, the production packages (require) that the library needs in order to work. In this case, the class is stand-alone (it only uses native PHP functions), so we don’t have any dependencies other than the minimum PHP version—therefore, we can safely answer “no”.
If you’re thinking about PHPUnit for testing the class methods, remember that PHPUnit is only used during development and testing, so it should be placed in require-dev, not in require.
This way, anyone installing the package in a production environment won’t have PHPUnit among their runtime dependencies.
The next prompt, in fact, asks whether we intend to define our development dependencies interactively (require-dev). Here, we type “yes”, and Composer will then prompt us to enter the name of the package.
We now type:phpunit/phpunit
Composer will return a list of matching packages—select phpunit/phpunit by entering the corresponding number.
Then it will ask which version to include.
We simply press Enter to install the latest available version.
It will now ask if we want to install any additional dependency packages, but since we don’t have any others, we simply press Enter.
It will now ask if we want to add a PSR-4 autoload mapping for the classes, suggesting to map the namespace Thesimon82\DescriptiveStatistics.
However, in our project we used Renor\\Statistics, so we type n to skip the proposal.
Finally, we obtain a summary of the entered data:
{
"name": "thesimon82/descriptive-statistics",
"description": "Lightweight PHP class for descriptive statistics",
"type": "library",
"require-dev": {
"phpunit/phpunit": "^12.1"
},
"license": "MIT",
"authors": [
{
"name": "Simone Renzi",
"email": "info@simonerenzi.com"
}
],
"minimum-stability": "stable",
"require": {},
"autoload": {
"psr-4": {
"Renor\\Statistics\\": "src/"
}
}
}
Do you confirm generation [yes]? Here we review the data, and if everything is correct, we confirm with “yes” and proceed to install the dependencies.
At the end, we type the command:
composer dump-autoload to regenerate the class autoloader.
It’s time to make the commit using the following series of commands:
git add .
git commit -m "feat: first stable release"
git tag v1.0.0
git push origin main v1.0.0Now we move to GitHub, and we should see our repository with the latest commit—
in my case: thesimon82 feat: first stable release.
We copy the URL from the address bar at the top and head over to Packagist.
Click on “Submit” at the top, then paste the GitHub link you copied into the text field. Press the Check button.
At this point, Packagist will analyze the composer.json file and immediately display the package details.
Clicking the “Submit” button at the bottom will create the package.
We’re done—now it’s time to test if everything works correctly.
Create a new folder named “Stats Test”, then open the terminal and navigate into that folder using:
Here we type:
composer require thesimon82/descriptive-statistics
Now import this folder into your development environment and create a new file in the root directory named: test.php.
<?php
require_once 'vendor/autoload.php';
use Renor\Statistics\DescriptiveStats;
$stats = new DescriptiveStats([1, 2, 3, 4, 5,6.22]);
echo $stats->mean();As we can see, we’re including the Composer-generated autoloader, which makes all classes mapped via PSR-4 available automatically—without the need for additional require statements.
We define the namespace used in the DescriptiveStats class and instantiate a new object with a numeric dataset.
You’ll recall that the class constructor automatically filters out non-numeric values, reindexes the array keys, and throws an exception if the resulting dataset is empty.
Then, the method mean()is called, which computes the mean and displays it on the screen.
If you now run the command: php test.php from the terminal, and if everything was done correctly, you should see the result:
3.5366666666667,
which is precisely the approximate mean of the values we passed to the class constructor.
We’ve seen how to transform a simple PHP class into a Composer package distributed on Packagist.
Now the library can be installed with a single command, benefits from semantic versioning, continuous integration, and automation that updates the Packagist listing automatically with every new tag.
From this point on, the lifecycle is straightforward:
you implement a feature, run the tests, increment the version, create the tag, and push it to GitHub.
Packagist and Composer will take care of the rest!
[starbox]
© 2025 RENOR & Partners S.r.l. | All rights reserved
Questo sito è protetto da reCAPTCHA e si applicano la Privacy Policy e i Termini di Servizio di Google.