-
-
Save jamiel/1711933 to your computer and use it in GitHub Desktop.
PHP 5.3 namespaces have taken away the biggest advantage of autoloading | |
----------------------------------------------------------------------- | |
When autoloading was introduced into PHP, the PHP world rejoiced as we no | |
longer needed to require every class we wanted to use in our current file | |
at the top of our code. With the introduction of namespaces this advantage | |
has been completely reversed, where unless you are writing all your code in | |
a single namespace (unlikely) you will end up needing to "use" every class | |
you want to include. | |
To back this up, let us take the Symfony2 framework as an example as of | |
today (31st January 2012). | |
jamiel@gentoo ~/git/symfony/src $ find . -name '*.php' | wc -l | |
1164 | |
So there are 1164 source files in the framework at the moment. | |
jamiel@gentoo ~/git/symfony/src $ egrep -r '^use ' * | wc -l | |
2331 | |
There are 2331 use statements so bearing in mind symfony 1.4 has | |
practically *no* fluff at the top of each class, namespaces have | |
added an extra 2331 new age require statements. | |
The top 10 all have 9 of these annoying declarations! | |
jamiel@gentoo ~/git/symfony/src $ egrep -rc '^use ' * | sed 's/\(.*\):\([0-9]\+\)/\2:\1/' | sort -r | head -n10 | |
9:Symfony/Component/Validator/ValidatorFactory.php | |
9:Symfony/Component/Security/Http/Firewall/RememberMeListener.php | |
9:Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php | |
9:Symfony/Component/HttpKernel/Client.php | |
9:Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php | |
9:Symfony/Component/Form/Extension/Core/Type/TimeType.php | |
9:Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php | |
9:Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php | |
9:Symfony/Bundle/SecurityBundle/SecurityBundle.php | |
9:Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php | |
EDIT: It would seem I am not the first to find this annoying, and this has been discussed before | |
by none other than Mr. Zaninotto | |
http://propel.posterous.com/the-end-of-autoloading |
As @pminnieur said - use
has nothing to do with autoloading. It just explicitly states what classes your class use
s.
It's amazingly useful way to declare class dependencies and to see how deeply some service is integrated into system and whether or not you can move/rename/refactor it. Think about it as additional source documentation level.
That said, sometimes developers go insane with too deep level of namespacing, but it's only a usage problem, not a tool one.
And talking bout autoloading - PSR-0 just gives you ability to forget about class loading altogether either they are in root namespace or not.
If you're using namespace
s and use
s for autoloading - you're doing it wrong!
I understand that the
usestatement is only to declare which namespaces/classes the currently defined namespace/class will use and how it will declare them in
newstatements.
But I don't understand your point about autoload'ing and then require'ing.
Use statements are not meant to trigger the autoloading, this is right. And they don't.
When the class is being instanciated, any other class being instanciated and not yet loaded will trigger the autoloading feature (include_path & spl_ registered ones).
So here you say we shouldn't rely on this behavior to load our classes.
I'm wondering how should I ?
Thank you !
@stephaneerard use namespaces to structurize your code and use
to avoid conflicts with 3rd-party code. Autoloading is a bonus, not requirement.
I'm just saying that complaints like:
use
is a newrequire
instead ofautoloading
is the exact nonsense as saying:
elephant is a new helicopter instead of teleportation
I added a new section to the gist with some thoughts on how things can be improved (revision 728603). I still hate writing "use" statements, though.
<?php
$obj = new Structure\MyClass;
$obj->helloWorld();
$obj = new Structure\MyClass2;
$obj->helloWorld();
So, seems that whole problem appeared just because you haven't RTFM? ;-)
use
doesn't import something into the current scope - it just creates alias for your namespace paths. That's it.
@everzet - Thanks, reverted the update seeing as that improvement exists.
You must not use the
use
statement. You can simply fallback toinstead of
By the way, the
use
statement does not trigger an autoload.PS: It's not there to neglect the advantage of autoloading, it's just an aliasing of your classes. So that
My\Fucking\Long\Class\Name\That\I\Dont\Want\To\Type\Everytime
must only beuse
'd once and is available in a shorter form, e.g.Everytime
in this case.