I understand that these have been drawn up by the PHP Frameworks Interoperability Group, and the focus is to be able to share libraries between the frameworks easily, so it doesn’t actually affect the average developer (unless you want to use framework library code, that is), but I find that coding standards are severely lacking in PHP and I agree with much of what they require (an exception being that the opening brace for class/method/etc is on the next line, but the same line for loops and conditions) so I decided I’m going to adhere as much as possible. Previously I used to code to the Zend Framework 1 guidelines.
So does anyone else code to these, and what are your thoughts on them? Do you vehemently object to anything? The tabs-vs-spaces thing seems to be an item of much contention, I find.
I find the entire thing a bit of a joke really. PSR-0 is backwards. Structuring your files to suit your autoloader rather than your autoloader to suit your file structure is a terrible idea.
As for PSR-1 and PSR-2, following them, or not following them, is going to have zero impact on anything really. If it suits your style anyway, do it, if it doesn’t, it doesn’t matter if you don’t use them. Keep in mind that any decent IDE can format the code in the way you prefer as you open a file.
I disagree about PSR-0, though I do appreciate your reasoning.
Due to the organisational structure defined in PSR-0 it is really easy to write a simple, compatible autoloader that will allow you to use libraries from various frameworks, even if your application code base is completely different. If you conform to their namespace specification as well (\vendor\package\etc) then it also provides a well structured organisation of your own code. If you were to replicate that into a file structure such as /libraries/vendor/package/etc.php then it’s easy to understand where files are and you have no messing when implementing other people’s libs. I like if for that simplicity. We’ve used libs from Symfony, Zend, Guzzle, Doctrine and more, and it all just works with a single autoloader. Maybe it is just more suitable for us than for others, but I like it. It also means that my code will work with other people’s frameworks if they want to use it, which makes it more worth my while.
As for reformatting code when you open a file, that will lead to unnecessary commits to your VCS as files will be detected as changed. It’s much simpler if everyone works to the same standard. Whether you use PSR standards or not, reformatting when you load a file isn’t the answer IMHO.
PSR-0 is going to be replaced soon anyway with PSR-4 which I think addresses this a bit. Also, I think it’s important for everyone on a team to work to the same coding standards, so like PSR-1 and PSR-2 for these - the point about version control is a good one. Given that several large projects have signed up to these standards, they are as good as any to follow. They closely match what I did before anyway (other than I used 2 space indents and put the opening brace of functions, methods and classes on the same line). I don’t think it matters what standards a team uses (though I have strong opinions on tabs vs spaces!), as long as they all use the same one and can reasonably justify why they use them.
Which is exactly the reason that the standard is backwards. They need a whole new standard for these cases where someone wants to do something negligibly different. As I suggested on my blog (and had a big debate with Phil Sturgeon on his), it’s totally inefficient. The standard should provide a way for library authors to tell the autoloader where their files are rather than forcing library authors to follow a specific convention. Then we wouldn’t need PSR-0… and we wouldn’t need to completely restructure and add namespaces to non-compliant libraries to fit the standard, we’d just provide the relevant metadata to the autoloader. But the PSR guys don’t like criticism so I gave up trying to talk sense to them.
I follow some of these rules, but not everything. I never start a new line after defining a class or method, its the way CakePHP does thing too but I actually dont use Cake since I prefer DataMapper over Active Record.
I reread your blog. You make some good points and you are clearly passionate about your ideas. I think the notion of adding an autoload.json file to a project which specifies autoload rules is a good one. You really should make a formal “request for comment” (RFC) somewhere and see if it gets any traction. Or maybe even propose a patch to composer.
As part of the composer install/update process, composer will create a vendor/autoload.php file. In many cases all your application has to do is include vendor/autoload.php and viola, everything will auto load. It’s really quite nice.
I quite like the idea of namespaces revealing the directory structure. It means I know exactly where each file will be in the filesystem based on the structure of the namespace. I don’t see why this is a bad thing. I like it.
In some cases it’s perfectly fine. But imposing that on every library limits flexibility… which is never a good thing. Here’s a really good explanation of several practical issues with it: http://scriptogr.am/mattsah/post/a-useful-critique-of-psr-x However, when I was looking at implementing it I realised how ridiculous it was.
I have a router with various rule types, these are classes, and generally project specific. The router itself sits in the namespace \Router\ The router is configured with rules in the namespace \Router\Conf. The rules are mostly project specific, while the router is the same for every project and sits at the library/framework level. Directory structure wise, this makes sense to store \Router\Router in /framework/router/router.php while storing project specific rules in /application/conf/router/$rule.php
PSR-0 however, dictates this is not allowed and would force me to mix project-specific and library level code just because they have the same top level namespace.
And before anyone says: “But the rules should be in \Conf\Router”. No, they shouldn’t because the router library shouldn’t make assumptions that all the other libraries use a \Conf\ namespace for configuration.
This is the same for any library where you’d want project specific related classes, and library supplied classes in the system.
In this case, I think your clash with PSR-0 reveals an issue with your code, not with PSR-0.
Your library code and your project-specific code almost certainly should not be sharing a namespace. Your library code should live in LibraryName\Router and your project-specific code should live in ProjectName\Conf\Router. Otherwise, one of them is polluting in the other’s space.
The router probably shouldn’t make any assumptions at all about where the configuration lives. Otherwise your router is mandating how the larger application must be organized. The router should simply have its config injected. It doesn’t need to know or care where the config data came from.
EDIT: And even still, PSR-0 will absolutely let you do what you’re describing.