[dev] Horde Libraries: Trying out Namespaces and PSR-4, PSR 11, PSR 12 without breaking user code

Ralf Lang lang at b1-systems.de
Mon Oct 19 20:13:05 UTC 2020


Am 20.09.20 um 21:46 schrieb Ralf Lang:
> Hello,
>
> Scope:
>
> this weekend's project was an exploration on how to port parts of Horde
> to PSR-4 autoloading, namespaces etc. The goal was making it run
> together with unmodified Horde git master code.
> I picked Horde_Injector for a candidate as I thought it might not be
> trivial but manageable in scope.
> https://github.com/maintaina-com/Injector/tree/refactor-psr4
>
> Horde Injector is a very attractive, simple DI solution without any XML
> or other overhead. It also has very few own dependencies into the Horde
> Framework - It uses Horde_Exception and it suggests using Horde_Test.
>
>
> Method:
>
> I decided the library root should be /src and handle the namespace
> Horde\Injector\.
> I kept every class on its original level, with the exception of
> Horde_Injector which became Horde\Injector\Injector.
>
> I removed some patterns of doing very little, formal things in the
> public methods and implementing the real action in some private _method().
>
> I removed the leading dash from internal properties as advised by PSR-12.
> Most changes were very formal and straight forward.
>
> I only added a few lines of logic to handle autowiring as the original
> implementation breaks (for unchanged user code) by the DependencyFinder
> being scoped \Horde\Injector rather than \.
>
> I added parameter and return type hints to most but not all method
> signatures. I changed getInstance() and hasInstance() to get() and has()
> to make it implement psr-11
>
> I made lib\Horde\Injector* derived from namespaced classes and
> interfaces in src\ and added \ to make the PSR-0 frontends explicitly
> part of the global/main namespace. All PSR-0 classes required a new file
> lib/_autoload.php which is a dependency-ordered unconditional list of
> require_once to src/.
>
> PSR-0 files under lib/ are mostly implement-nothing derived classes. Two
> exceptions are the constructor and the child injector method as they
> would return the namespaced version without the unnamespaced wrapper.
> Also, the PSR-0 getInstance() and hasInstance() methods map to psr-4
> get() and has()
>
> I did not explicitly reference the PSR-11 interfaces. Although my code
> satifies them through duck typing, I did not want to introduce
> derivative questions like autoloading the PSR-11 interface definitions
> in case of an autoloader unaware of the namespaced code behind the
> unnamespaced, user-facing shim. If we do this for real, we should either
> reference the interfaces or derive a class version which does.
>
>
> Outcome:
>
> Some unit tests are still failing due to signature mismatch. Within a
> composer setup, Horde seems to run well from web and many CLI tools run,
> including the quite demanding components app (extends Horde_Injector).
>
>
> Discussion:
>
> I think the hardest decision is whether to use modern type hints in
> method signature or to skip these. It is a breaking change for code
> which disrespects the phpdoc type hints or for derived classes.
> I did not specifically address pear and git-tools installs but only
> tested for composer. It should work for git-tools installations though.
>
> If I wanted 100% signature compat I could either remove type hints or
> move the actual implementation to traits and let both psr-4 and psr-0
> code be independent frontends to the traits. This would look very much
> like the Laravel code base.
>
> I think this worked well . It is a path to gradual porting of many/most
> horde libraries to PSR-4. It does not imply any need to convert
> everything (or any using code of the respective library) within some
> common timeline or project. It would be worhwhile to run some automated
> mass edits to prepend un-namespaced class references with \ to avoid
> ambiguities. That's a rather small investments which would prevent lots
> of headaches.
>
>
> Derivative: My team has experimented with partial PSR-4 conversions of
> internal apps. While we kept the outside interface un-namespaced
> (Api.php, Application.php, app/controllers/*, Ajax/*, ), most app
> internal classes could be converted easily.
> Anything wrapping/deriving from Core/ factories and services is a mess
> though. All testing happened in a composer based setup.
>
>
Return type hints are not supported by phpunit 4's mocking library. This
breaks the test suite at the moment.

-- 
Ralf Lang
Linux Consultant / Developer
Tel.: +49-170-6381563
Mail: lang at b1-systems.de
B1 Systems GmbH
Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de
GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537

-------------- next part --------------
A non-text attachment was scrubbed...
Name: pEpkey.asc
Type: application/pgp-keys
Size: 2688 bytes
Desc: not available
URL: <https://lists.horde.org/archives/dev/attachments/20201019/8e3ca259/attachment.key>


More information about the dev mailing list