PHP-FIG PSR WTF
Steve Lacey
PHP Framework Interoperability Group
The idea behind the group is for project representatives to talk about the commonalities between our projects and find ways we can work together. Our main audience is each other, but we’re very aware that the rest of the PHP community is watching. If other folks want to adopt what we’re doing they are welcome to do so, but that is not the aim.
Member projects
Some notable voters
Phil Sturgeon @philsturgeon PyroCMS |
Kris Wallsmith @kriswallsmith Assetic & Buzz |
||
Bernhard Schussek @webmozart Symfony2 |
Jordi Boggiano @seldaek Composer & Packagist |
||
|
Larry Garfield @crell Drupal |
|
Cal Evans @calevans PHP Community |
Voting on
Proposed Standards Recommendations (PSRs)
Workflow
-
Pre-Draft
-
Draft
-
Review
-
Accepted
Accepted standards
PSR-0 | Autoloading |
PSR-1 | Basic coding standards |
PSR-2 | Coding style guide |
PSR-3 | Logger interface |
PSR-4 | Better autoloading |
PSR-0: Autoloading Standard
A fully-qualified namespace and class
must have the following structure:
\<Vendor Name>\(<Namespace>\)*<Class Name>
Each namespace separator is converted to a
DIRECTORY_SEPARATOR when loading from the file system
Namespace | Path | |
---|---|---|
\Doctrine\Common\ IsolatedClassLoader |
–> |
/path/to/project/lib/vendor/
Doctrine/Common/ IsolatedClassLoader.php |
\Symfony\Core\Request | –> |
/path/to/project/lib/vendor/
Symfony/Core/Request.php |
The fully-qualified namespace and class is suffixed with .php when loading from the file system.
Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace
Faux namespace | Path |
---|---|
Zend_View_Helper_FormCheckbox |
/path/to/project/lib/vendor/ Zend/View/Helper/ FormCheckbox.php |
-
Supports older projects with less legwork
-
Allows libraries to continue supporting <=5.2
PSR-0 defines the rules an autoloader must follow
as opposed to how the autoloader should be written
...or you know, Composer
PSR-1: Basic Coding Standard
Overview
- Files MUST use only <?php and <?= tags.
- Files MUST use only UTF-8 without BOM for PHP code.
- Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.
- Namespaces and classes MUST follow PSR-0.
- Class names MUST be declared in StudlyCaps.
- Class constants MUST be declared in all upper case with underscore separators.
-
Method names MUST be declared in camelCase.
PHP Tags
PHP code MUST use the long <?php ?> tags or the short-echo <?= ?> tags; it MUST NOT use the other tag variations.
Character Encoding
Side Effects
The phrase "side effects" means execution of logic not directly related to declaring classes, functions, constants, etc., merely from including the file.
While PSR-0 looks at basic "make sure it aint broke" interoperability, PSR-1 takes a slightly higher road and helps make sure that from the outside looking in, it all looks the same. Is this style guide? No. It means that a consistent interface can be kept for any components being used.
- Phil Sturgeon in the PHP-FIG mailing list
PSR-2: Coding Style Guide
Provides a Coding Style Guide for projects looking to standardise their code.
"PSR-2′s purpose is to have a single style guide for PHP code that results in uniformly formatted shared code."
phpcs --standard=PSR2 *.php
github.com/squizlabs/PHP_CodeSniffer
FILE: Tests/AllTests.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
14 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
119 | ERROR | Each PHP statement must be on a line by itself
--------------------------------------------------------------------------------
FILE: Tests/ApiTest.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AND 1 WARNING(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
19 | ERROR | Method name "ApiTest::ExampleApiCall" is not in camel caps format
19 | WARNING | Line exceeds 120 characters; contains 126 characters
21 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
--------------------------------------------------------------------------------
FILE: Tests/AppTest.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
33 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
--------------------------------------------------------------------------------
FILE: Tests/BillingTest.php
--------------------------------------------------------------------------------
FOUND 7 ERROR(S) AND 20 WARNING(S) AFFECTING 27 LINE(S)
--------------------------------------------------------------------------------
56 | WARNING | Line exceeds 120 characters; contains 130 characters
70 | ERROR | Each PHP statement must be on a line by itself
88 | WARNING | Line exceeds 120 characters; contains 130 characters
91 | WARNING | Line exceeds 120 characters; contains 144 characters
92 | WARNING | Line exceeds 120 characters; contains 143 characters
93 | WARNING | Line exceeds 120 characters; contains 143 characters
94 | WARNING | Line exceeds 120 characters; contains 144 characters
95 | WARNING | Line exceeds 120 characters; contains 144 characters
96 | WARNING | Line exceeds 120 characters; contains 144 characters
97 | WARNING | Line exceeds 120 characters; contains 140 characters
98 | WARNING | Line exceeds 120 characters; contains 142 characters
99 | WARNING | Line exceeds 120 characters; contains 147 characters
100 | WARNING | Line exceeds 120 characters; contains 144 characters
101 | WARNING | Line exceeds 120 characters; contains 147 characters
102 | WARNING | Line exceeds 120 characters; contains 141 characters
123 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
153 | WARNING | Line exceeds 120 characters; contains 130 characters
565 | WARNING | Line exceeds 120 characters; contains 122 characters
573 | WARNING | Line exceeds 120 characters; contains 131 characters
575 | WARNING | Line exceeds 120 characters; contains 130 characters
593 | ERROR | Expected "foreach (...) {\n"; found "foreach(...){\n"
602 | ERROR | Opening brace should be on a new line
605 | WARNING | Line exceeds 120 characters; contains 131 characters
608 | WARNING | Line exceeds 120 characters; contains 131 characters
617 | ERROR | Opening brace should be on a new line
635 | ERROR | Opening brace should be on a new line
658 | ERROR | The closing brace for the class must go on the next line after
| | the body
--------------------------------------------------------------------------------
FILE: Tests/ContactTest.php
--------------------------------------------------------------------------------
FOUND 21 ERROR(S) AND 11 WARNING(S) AFFECTING 32 LINE(S)
--------------------------------------------------------------------------------
256 | WARNING | Line exceeds 120 characters; contains 123 characters
327 | WARNING | Line exceeds 120 characters; contains 149 characters
336 | WARNING | Line exceeds 120 characters; contains 149 characters
339 | WARNING | Line exceeds 120 characters; contains 142 characters
350 | ERROR | Expected "foreach (...) {\n"; found "foreach(...) {\n"
363 | WARNING | Line exceeds 120 characters; contains 123 characters
407 | WARNING | Line exceeds 120 characters; contains 142 characters
417 | ERROR | Expected "foreach (...) {\n"; found "foreach(...) {\n"
459 | WARNING | Line exceeds 120 characters; contains 149 characters
464 | WARNING | Line exceeds 120 characters; contains 123 characters
468 | WARNING | Line exceeds 120 characters; contains 149 characters
471 | WARNING | Line exceeds 120 characters; contains 146 characters
536 | ERROR | No space found after comma in function call
575 | ERROR | No space found after comma in function call
582 | ERROR | No space found after comma in function call
595 | ERROR | No space found after comma in function call
608 | ERROR | No space found after comma in function call
628 | ERROR | No space found after comma in function call
635 | ERROR | No space found after comma in function call
636 | ERROR | No space found after comma in function call
645 | ERROR | No space found after comma in function call
646 | ERROR | No space found after comma in function call
652 | ERROR | No space found after comma in function call
653 | ERROR | No space found after comma in function call
672 | ERROR | No space found after comma in function call
674 | ERROR | No space found after comma in function call
707 | ERROR | No space found after comma in function call
711 | ERROR | No space found after comma in function call
712 | ERROR | No space found after comma in function call
719 | ERROR | No space found after comma in function call
739 | ERROR | No space found after comma in function call
1055 | WARNING | Line exceeds 120 characters; contains 177 characters
--------------------------------------------------------------------------------
FILE: Tests/GeneralTest.php
--------------------------------------------------------------------------------
FOUND 15 ERROR(S) AND 1 WARNING(S) AFFECTING 16 LINE(S)
--------------------------------------------------------------------------------
50 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
51 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
52 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
53 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
54 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
55 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
56 | ERROR | Multi-line function call not indented correctly; expected 12
| | spaces but found 10
64 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
66 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
67 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
68 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
69 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
70 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
71 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
72 | ERROR | Multi-line function call not indented correctly; expected 16
| | spaces but found 14
76 | WARNING | Line exceeds 120 characters; contains 153 characters
--------------------------------------------------------------------------------
FILE: Tests/SpaceTest.php
--------------------------------------------------------------------------------
FOUND 6 ERROR(S) AND 5 WARNING(S) AFFECTING 8 LINE(S)
--------------------------------------------------------------------------------
43 | WARNING | Line exceeds 120 characters; contains 122 characters
45 | WARNING | Line exceeds 120 characters; contains 123 characters
48 | WARNING | Line exceeds 120 characters; contains 123 characters
51 | WARNING | Line exceeds 120 characters; contains 129 characters
258 | ERROR | Expected 1 space after FUNCTION keyword; 0 found
265 | ERROR | No space found after comma in function call
265 | ERROR | No space found after comma in function call
265 | ERROR | No space found after comma in function call
265 | ERROR | No space found after comma in function call
285 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
289 | WARNING | Line exceeds 120 characters; contains 148 characters
--------------------------------------------------------------------------------
FILE: Tests/UserTest.php
--------------------------------------------------------------------------------
FOUND 9 ERROR(S) AND 3 WARNING(S) AFFECTING 12 LINE(S)
--------------------------------------------------------------------------------
33 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
49 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
67 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
85 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
112 | WARNING | Line exceeds 120 characters; contains 129 characters
118 | ERROR | No space found after comma in function call
122 | ERROR | No space found after comma in function call
126 | ERROR | No space found after comma in function call
139 | WARNING | Line exceeds 120 characters; contains 125 characters
145 | ERROR | Opening brace should be on a new line
149 | ERROR | Expected "try {\n...} catch (...) {\n"; found "try {\n...}
| | catch(...) {\n"
153 | WARNING | Line exceeds 120 characters; contains 136 characters
--------------------------------------------------------------------------------
FILE: Tests/VCardTest.php
--------------------------------------------------------------------------------
FOUND 7 ERROR(S) AFFECTING 7 LINE(S)
--------------------------------------------------------------------------------
77 | ERROR | Spaces must be used to indent lines; tabs are not allowed
78 | ERROR | Spaces must be used to indent lines; tabs are not allowed
79 | ERROR | Spaces must be used to indent lines; tabs are not allowed
80 | ERROR | Spaces must be used to indent lines; tabs are not allowed
81 | ERROR | Spaces must be used to indent lines; tabs are not allowed
82 | ERROR | Spaces must be used to indent lines; tabs are not allowed
407 | ERROR | Opening brace should be on a new line
--------------------------------------------------------------------------------
FILE: Tests/bootstrap.php
--------------------------------------------------------------------------------
FOUND 0 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
1 | WARNING | A file should declare new symbols (classes, functions,
| | constants, etc.) and cause no other side effects, or it should
| | execute logic with side effects, but should not do both. The
| | first symbol is defined on line 3 and the first side effect is
| | on line 5.
--------------------------------------------------------------------------------
php php-cs-fixer.phar fix .
In an ideal world, every PHP project would adopt the recommendations found in PSR-1 and PSR-2. However, due to taste (i.e. “Naming convention x looks better than y!”, “Tabs over spaces!”) and historical segmentation between various coding styles, there have only been a sparse amount of PHP projects adopting PSR-1 and PSR-2 in its entirety.
By everyone shirking their own preferences, we have one consistent style from the outside-in, meaning I can use ANY package – not just whichever happens to be camelCase.
- Phil Sturgeon in the PHP-FIG mailing list
PSR-3: Logger Interface
Describes a common interface for logging libraries.
PSR Log Package
A shared interface standard, like PSR-3, results in frameworks, libraries and other applications being able to type hint on that shared interface, allowing developers to choose a preferred implementation.
net.tutsplus.com/tutorials/php/psr-huh
In other words: if a logging component is known to adhere to PSR-3, it can simply be swapped with a different PSR-3 compliant logging component. This assures maximum interoperability between calls to logger implementations.
net.tutsplus.com/tutorials/php/psr-huh
Monolog implements PSR-3
It’s therefore known to implement the Psr\Log\LoggerInterface and its associated guidelines found in the PSR-3 document.
Because of this, you could swap out Monolog for any other PSR-3 compliant logger... if someone else felt like writing one.
PSR-4: Autoloader
This PSR describes a specification for autoloading classes from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be autoloaded according to the specification.
...and it's now accepted (yay!)
Namespaces are real, no need to fake it
No more Zend_Email_Imap, it's Zend\Email\Imap. PSR-0 lets either of those map to the same filepath, which causes some oddities.
PSR-4 removes this.
Overly Verbose Folder Structure.
Now that Composer is a thing, its more common to see a mapping like: Foo/Bar/Baz would link to vendor/foo/bar/src/Foo/Bar/Baz.
Autoloader error handling
Why?
Pros:
|
Cons:
|
Composer team on board - already a WIP
Assuming you're using namespaces (and not _'s), upgrading an application will require nothing, it will be completely seamless and use the existing Composer autoloader.
PSR-0 will probably be deprecated some day, but no date has been set for that. If it happens, it will be a damn long time away.
Why are the PSR's so varied?
The PHP-FIG is not a standards body, it's a group that makes recommendations for ways in which frameworks (and other projects in general) can combine their efforts to create interoperable code. That gives it a fairly open-ended remit when it comes to what it releases as PSR's.
- Phil, again,
in the PHP-FIG mailing list
Where next?
This to me is the central point of the PHP-FIG as by defining these standards it can stop the need to build 6 different damn adapter classes for your composer package if you want it to work with Buzz, Guzzle, Zend HTTP, Curl, Whatever). This happens a lot and it sucks.
Further reading
The FIG intends to host a cross-section of the PHP ecosystem, not only framework developers.
Thanks!
Copy of PHP-FIG PSR WTF
By boxcore
Copy of PHP-FIG PSR WTF
- 397