A simple recipe for framework decoupling – Matthias Noback

If you want to write applications that are maintainable in the long run, you have to decouple from your framework, ORM, HTTP client, etc. because your application will outlive all of them.

Three simple rules

To accomplish framework decoupling you only have to follow these simple rules:

  1. All services should get all their dependencies and configuration values injected as constructor arguments. When a dependency uses IO, you have to introduce an abstraction for it.
  2. Other types of objects shouldn’t have service responsibilities.
  3. Contextual information should always be passed as method arguments.

Explanations

Rule 1

Following rule 1 ensures that you’ll never fetch a service ad hoc, e.g. by using Container::get(UserRepository::class).
This is needed for framework decoupling because the global static facility that returns the service for you is by definition framework-specific.
The same is true for fetching configuration values (e.g. Config::get('email.default_sender')).

Sometimes a dependency uses IO, that is, it talks to the database, the filesystem, etc.
In that case you should introduce an abstraction for the dependency.
If you depend on a concrete class, that class will work only with the specific library or framework that you’re working with right now, so in order to stay decoupled you should use your own abstraction, combined with an implementation that uses your current library/framework.

Rule 2

Aside from services there will be several other types of objects like entities, value objects, domain events, and data transfer objects, all of which don’t have service responsibilities.
None of them should have service responsibilities, because that means they will either invoke services via some global static facility, or they need special framework/ORM-specific setup meaning they can’t be used in isolation and won’t survive a major framework upgrade or switch.
An example of an object that doesn’t follow rule 2 is an active record model, which may look like an entity, but is able to save itself, which is in fact a service responsibility.

Rule 3

Contextual information is usually derived from the current web request or the user’s session, e.g. the ID of the user who is currently logged in.
Instead of fetching this data whenever you need it (like Auth::getUser()->getId()) you should pass it from method to method as a regular argument.

Combined, rule 1, 2, and 3 ensure that for every method it’s totally clear what it’s doing, what data it needs, and on what service dependencies it relies to do its work.
On top of that, none of the dependencies or method arguments will be framework or library-specific, meaning your application code will be effectively be decoupled from the framework.

Conclusion

If you ask me, these rules are very simple indeed, and they don’t require a lot of extra work compared to tightly coupling everything to your project’s current set of installed packages.
So, why not follow them if you know that your project should still be up-to-date with current standards 3 years from now?

P.S. Following these rules gives you much more than framework decoupling: everything becomes testable in isolation, the tests are fully deterministic and therefore very stable, and they are really fast to run.

Pre-release PHP 8.0 images now available – platform.sh

Like clockwork, the next release of PHP is slated to come out on November 26th. It’s packed with new features and performance improvements, as well as general overall polish. And as usual, you can try it out early on Platform.sh with a single-line change.
We now have a php:8.0-rc container image available. That is rc meaning our prerelease, not PHP’s RC phase. It is PHP 8.0 beta 3 (just released as of this writing), but we will be updating it periodically as new pre-release versions of PHP 8 are released in the coming weeks.

PHP 8.0.0 Beta 3 available for testing – PHP: Hypertext Preprocessor

The PHP team is pleased to announce the sixth testing release of PHP 8.0.0, Beta 3. This continues the PHP 8.0 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.0.0 Beta 3 please visit the download page.Please carefully test this version and report any issues found in the bug reporting system.Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file, or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be the Release Candidate 1, planned for Sep 17 2020.The signatures for the release can be found in the manifest or on the QA site.Thank you for helping us make PHP better.

PHP 8.0.0beta2 Released! – PHP: Hypertext Preprocessor

The PHP team is pleased to announce the fifth testing release of PHP 8.0.0, Beta 2. This continues the PHP 8.0 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.0.0 Beta 2 please visit the download page.Please carefully test this version and report any issues found in the bug reporting system.Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file, or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be Beta 3, planned for Sep 3 2020.The signatures for the release can be found in the manifest or on the QA site.Thank you for helping us make PHP better.