Below you will find pages that utilize the taxonomy term “Package Design”
On using PSR abstractions
Several years ago, when the PHP-FIG (PHP Framework Interop Group) created its first PSRs (PHP Standard Recommendations) they started some big changes in the PHP ecosystem. The standard for class auto-loading was created to go hand-in-hand with the then new package manager Composer. PSRs for coding standards were defined, which I’m sure helped a lot of teams to leave coding standard discussions behind. The old tabs versus spaces debate was forever settled and the jokes about it now feel quite outdated.
Final classes by default, why?
I recently wrote about when to add an interface to a class. After explaining good reasons for adding an interface, I claim that if none of those reasons apply in your situation, you should just use a class and declare it “final”.
PHP 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition with final. If the class itself is being defined final then it cannot be extended.
Reusing domain code
Last week I wrote about when to add an interface to a class. The article finishes with the claim that classes from the application’s domain don’t usually need an interface. The reason is that domain code isn’t going to be swapped out with something else. This code is the result of careful modelling work that’s done based on the business domain that you work with. And even if you’d work on, say, two financial software projects in a row, you’ll find that the models you produce for each of them will be different in many subtle (if not radical) ways. Paradoxically you’ll find that in practice a domain model can sometimes be reused after all. There are some great examples out there. In this article I explain different scenarios of where and how reuse could work.
Packages: the case for clones
Don’t reinvent the wheel
There is this ongoing discussion in the PHP community (and I guess in every software-related community) about reinventing wheels. A refreshing angle in this debate came from an article by Phil Sturgeon pointing to the high number of “duplicate” packages available on Packagist. I agree with Phil:
Sometimes these are carbon copies of other packages, but often they are feature-weak versions of established packages.
It doesn’t make sense to do the same thing over and over again. At least I personally don’t try to make this mistake. If I want to write code that “already exists”, at least I don’t publish it on Packagist.
Composer "provide" and dependency inversion
This is a response to Peter Petermann’s article Composer and virtual packages. First, let’s make this totally clear: I don’t want to start an Internet war about this, I’m just pointing out some design issues that may arise from using Composer’s provide
option in your package’s composer.json
file. This means it’s also nothing personal. To Peter: you wrote a very nice article and shed light on an underused feature of Composer. Thank you for that!
Backwards compatible bundle releases
The problem
With a new bundle release you may want to rename services or parameters, make a service private, change some constructor arguments, change the structure of the bundle configuration, etc. Some of these changes may acually be backwards incompatible changes for the users of that bundle. Luckily, the Symfony DependenyInjection component and Config component both provide you with some options to prevent such backwards compatibility (BC) breaks. If you want to know more about backwards compatibility and bundle versioning, please read my previous article on this subject.
Semantic versioning for bundles
A short introduction to semantic versioning
Semantic versioning is an agreement between the user of a package and its maintainer. The maintainer should be able to fix bugs, add new features or completely change the API of the software they provide. At the same time, the user of the package should not be forced to make changes to their own project whenever a package maintainer decides to release a new version.
Exposing resources: from Symfony bundles to packages
Symfony bundles: providing services and exposing resources
When you look at the source code of the Symfony framework, it becomes clear that bundles play two distinct and very different roles: in the first place a bundle is a service container extension: it offers ways to add, modify or remove service definitions and parameters, optionally by means of bundle configuration. This role is represented by the following methods of BundleInterface
:
namespace Symfony\Component\HttpKernel\Bundle;
interface BundleInterface extends ContainerAwareInterface
{
/** Boots the Bundle. */
public function boot();
/** Shutdowns the Bundle. */
public function shutdown();
/** Builds the bundle. */
public function build(ContainerBuilder $container);
/** Returns the container extension that should be implicitly loaded. */
public function getContainerExtension();
...
}
The second role of a bundle is that of a resource provider. When a bundle is registered in the application kernel, it automatically starts to expose all kinds of resources to the application. Think of routing files, controllers, entities, templates, translation files, etc.
Decoupling your (event) system
About interface segregation, dependency inversion and package stability
You are creating a nice reusable package. Inside the package you want to use events to allow others to hook into your own code. You look at several event managers that are available. Since you are somewhat familiar with the Symfony EventDispatcher component already, you decide to add it to your package’s composer.json
:
{
"name": "my/package"
"require": {
"symfony/event-dispatcher": "~2.5"
}
}
Your dependency graph now looks like this:
Principles of PHP Package Design - First part of the book is now available
Seven months, two presentations and three blog posts later, I’ve published the first installment of my new book, Principles of PHP Package Design.
From the introduction of the book:
Naturally the biggest part of this book covers package design principles. But before we come to that, we first take a close look at what constitutes packages: classes and interfaces. The way you design them has great consequences for the characteristics of the package in which they will eventually reside. So before considering package design principles themselves, we first need to take a look at the principles that govern class design. These are the so-called SOLID principles. Each letter of this acronym stands for a different principle, each of which we will briefly (re)visit in the first part of this book.
There's no such thing as an optional dependency
On several occasions I have tried to explain my opinion about “optional dependencies” (also known as “suggested dependencies” or “dev requirements”) and I’m doing it again:
There’s no such thing as an optional dependency.
I’m talking about PHP packages here and specifically those defined by a composer.json
file.
What is a dependency?
First let’s make sure we all agree about what a dependency is. Take a look at the following piece of code:
The "dark" side of PHP
About the nature of PHP and its misuse in package design
This text will be part of the introduction of my upcoming book Principles of PHP Package Design. If you’d like to be notified when the book is released, you can subscribe on the book’s page. This will entitle you to a 20% discount once the book is available for download.
Before we continue with the “main matter” of this book, I’d like to introduce you to the mindset I had while writing it. This particular mindset amounts to having a constant awareness that PHP has somewhat of a dark side, as well as keeping our hopes high that it is very well possible to expose this “dark side” to a warm sun of programming principles, coding standards and generally good ideas, collected over the years, carefully nurtured and enhanced by great programmers of different languages and cultures.
PHP - The Future of Packages
Recently I tweeted about phpclasses.org. It was not such a friendly statement:
Why does phpclasses.org still exist? Most of the “packages” contain dangerous, stupid or useless code.
Manuel Lemos, the man behind PHP Classes, made me pull back a bit by pointing out that I was generalizing and that they do what they can to encourage people to do a good job. I recognize their effort. And of course, there is also good code on phpclasses.org
.
Experiences with PHP open source software in a Symfony-friendly environment
These days, good PHP object-oriented libraries are all around and easily available. To me, it is actually thrilling to be part of this flourishing community, while working with Symfony2 and blogging about the Framework, the Components and their neighbors (like Silex). It seems like everything is made for contributing to this nice and friendly environment, with tools like GitHub (online collaboration), Composer (dependency management), Packagist (package archive) and Travis CI (continuous integration).
Still, to me, contributing felt like too big a step to take right now. Until a few weeks ago, when I was looking for something I needed (a PHP client for the Microsoft Translator API) and could not find a decent solution. I decided to make it myself, and share it online. Below I’ve written down my steps. As you can see, they are very easy and would require just a bit of extra time. So, take from it what you need, and start contributing!