PSR Standards and PHP-FIG: Writing Interoperable PHP
Master PHP-FIG PSR standards to write interoperable, maintainable PHP code.
20+ years shipping production PHP systems at scale. Lessons pulled from things that broke in production.
- ✓Basic knowledge of PHP syntax and OOP
- ✓Familiarity with Composer
- ✓PHP 7.4 or higher installed
- PSR standards are PHP coding guidelines by PHP-FIG to ensure code interoperability.
- Key standards: PSR-1 (basic coding), PSR-4 (autoloading), PSR-7 (HTTP messages), PSR-12 (extended coding style).
- Adopting PSRs makes your code compatible with frameworks like Laravel and Symfony.
- Use Composer for autoloading with PSR-4.
- Tools like PHP_CodeSniffer enforce PSR-12 automatically.
Think of PSR standards like traffic rules for PHP developers. Just as traffic rules help cars drive safely together, PSR standards help different PHP libraries and frameworks work together without crashes. Following them means your code can easily plug into any PHP ecosystem.
Imagine you're building a PHP application that needs to send emails, handle payments, and generate PDFs. You find great libraries for each task, but they all have different coding styles, autoloading methods, and ways of handling HTTP requests. Integrating them becomes a nightmare of manual adjustments and compatibility hacks. This is exactly the problem the PHP Framework Interoperability Group (PHP-FIG) set out to solve with PSR (PHP Standards Recommendations) standards.
PHP-FIG is a group of PHP project representatives who collaborate to define common standards. By following PSRs, your code becomes predictable and interoperable with thousands of other PHP packages. Whether you're using a micro-framework or a full-stack CMS, PSR compliance ensures your code plays nicely with others.
In this tutorial, you'll learn the most important PSR standards: PSR-1 (basic coding standard), PSR-4 (autoloading), PSR-7 (HTTP message interfaces), and PSR-12 (extended coding style guide). We'll explore real-world examples, a production incident caused by ignoring PSR-4, and debugging techniques. By the end, you'll be able to write PHP code that any PSR-compliant project can consume.
What is PHP-FIG and Why PSR Standards Matter
PHP-FIG (PHP Framework Interoperability Group) is a collective of PHP project leaders who collaborate to create standards that promote interoperability. PSR (PHP Standards Recommendation) documents define these standards. Adopting PSRs ensures your code can work seamlessly with other PHP libraries and frameworks, reducing integration friction.
- Interoperability: Your code can be used by any PSR-compliant project.
- Maintainability: Consistent coding style makes code easier to read and maintain.
- Tooling: Many tools (e.g., PHP_CodeSniffer, PHPStan) support PSRs out of the box.
- Community: Following PSRs aligns you with best practices adopted by major projects like Laravel, Symfony, and Drupal.
Let's start with the foundational standards.
PSR-1: Basic Coding Standard
PSR-1 defines basic coding elements to ensure a high level of technical interoperability. Key rules: - Files MUST use only <?php and <?= tags. - Files MUST use UTF-8 without BOM. - Namespaces and classes MUST follow PSR-4 autoloading. - Class names MUST be declared in StudlyCaps. - Class constants MUST be declared in UPPER_CASE with underscores. - Method names MUST be declared in camelCase.
Example:
PSR-4: Autoloading Standard
PSR-4 describes a specification for autoloading classes from file paths. It maps fully qualified class names to file paths based on namespace prefixes. This eliminates the need for manual require/include statements.
- A namespace prefix (e.g., App\) maps to a base directory (e.g., src/).
- Sub-namespaces correspond to subdirectories.
- Class file names are case-sensitive and match the class name.
- Namespace: App\Library\Parser
- File: src/Library/Parser.php
Composer autoload configuration:
PSR-7: HTTP Message Interfaces
PSR-7 standardizes HTTP messages (requests and responses) as objects. It defines interfaces for: - Psr\Http\Message\RequestInterface - Psr\Http\Message\ResponseInterface - Psr\Http\Message\ServerRequestInterface - Psr\Http\Message\StreamInterface - Psr\Http\Message\UriInterface
These interfaces allow frameworks and libraries to exchange HTTP data without coupling to specific implementations. For example, a middleware can modify a request object regardless of the underlying framework.
Example using Guzzle (PSR-7 compatible):
PSR-12: Extended Coding Style Guide
PSR-12 extends PSR-2 (now deprecated) with modern PHP features. It covers: - Indentation: 4 spaces, no tabs. - Line length: soft limit 120 chars, hard limit 80 chars recommended. - Keywords: lowercase (true, false, null). - Braces: opening brace on same line for classes/methods, on new line for control structures. - Use declarations: one per line, alphabetically ordered. - Traits: one per line. - Anonymous classes: same as regular classes.
Example:
Other Important PSRs
Beyond the core standards, several other PSRs address specific concerns: - PSR-3: Logger Interface – standardizes logging (e.g., Monolog implements it). - PSR-6: Caching Interface – defines cache pool and item interfaces. - PSR-11: Container Interface – standardizes dependency injection containers. - PSR-14: Event Dispatcher – standardizes event handling. - PSR-18: HTTP Client – defines a client interface for sending PSR-7 requests.
Adopting these PSRs makes your code compatible with a vast ecosystem of packages. For example, using PSR-3 allows you to swap logging libraries without changing your code.
The Autoloading Catastrophe: When PSR-4 Was Ignored
- Always verify namespace-directory mapping matches PSR-4.
- Use composer dump-autoload after adding new classes.
- Test autoloading in a staging environment before production.
- Include autoloading checks in your deployment pipeline.
- Use tools like PHP_CodeSniffer to enforce PSR-4 compliance.
composer dump-autoloadphp -r "require 'vendor/autoload.php'; echo 'OK';"| File | Command / Code | Purpose |
|---|---|---|
| composer.json | { | What is PHP-FIG and Why PSR Standards Matter |
| src | namespace App; | PSR-1 |
| send-request.php | use GuzzleHttp\Client; | PSR-7 |
| src | declare(strict_types=1); | PSR-12 |
| logger-example.php | use Psr\Log\LoggerInterface; | Other Important PSRs |
Key takeaways
Common mistakes to avoid
3 patternsForgetting the trailing backslash in PSR-4 namespace prefix
Not running composer dump-autoload after adding new classes
Using PSR-0 style class names with underscores
Interview Questions on This Topic
What does PSR stand for and what is its purpose?
Frequently Asked Questions
20+ years shipping production PHP systems at scale. Lessons pulled from things that broke in production.
That's Advanced PHP. Mark it forged?
3 min read · try the examples if you haven't