[Modern PHP] Chapter III Standard

Source: Internet
Author: User
Tags autoloader php framework rfc system log codeigniter
The number of PHP components and frameworks is incredibly large. There are mega-frameworks like Symfony and Laravel, as well as miniature frameworks like Silex and slim. There are even traditional frameworks that have existed long before modern PHP components appear, such as CodeIgniter. The modern PHP ecosystem is a veritable code melting pot that helps developers build amazing applications.

Unfortunately, the old PHP frameworks were developed in a relatively closed environment, and they were not able to share code with other PHP frameworks. If your project uses an old PHP framework, you will be stuck in the frame and trapped in the framework's own ecosystem. If you are satisfied with the tools provided by the framework itself, there is no problem with this relatively concentrated environment. However, if you use the CodeIgniter framework and want to pick a few good libraries from the Symfony framework, you may not be so lucky unless you write a one-time adapter specifically for your project.

What we've got here's a failure to communicate (where we can't communicate at all)

--The classic lines of bullet in the movie bars

Do you see the problem? Frameworks developed in closed environments are not designed to interoperate with other frameworks. This is a very inefficient design for developers (constrained by the chosen framework) or for the framework itself, which has repeatedly developed some existing code. Nevertheless, I have good news to tell you. The PHP community's understanding of the framework has transitioned from a centralized framework model to a distributed ecosystem of highly efficient, common, and focused components.

Php-fig's rescue plan

Some developers of the PHP framework were aware of the problem, so they discussed it in the 2009 Php|tek (the famous PHP Conference). The core of the discussion is how to improve the interoperability and development efficiency within the framework. For example, if a PHP framework could share a non-coupled log class like Monolog, would we not have to develop a new tightly coupled logging class every time? If a PHP framework could use the excellent HTTP request and response classes in the Symfon/httpfoundation component of the Symfony framework, would we not need to develop our own HTTP Request and the response class? To achieve this goal, the PHP framework needs to use some common language for interaction and to share their framework. And what they need is the standard.

The developers of the PHP framework that ran into the Php|tek conference eventually created the PHP framwork Interop Group (php-fig). Php-fig is made up of representatives of a group of PHP framework projects, and according to Php-fig's official website, their job is to "discuss the commonality of their projects to find a way to work together." Php-fig has developed some recommendations (recommendations), and the PHP framework can voluntarily choose whether to implement these recommendations to enhance interactivity and share their respective frameworks.

Php-fig is a group of self-created organizations for the PHP Framework project. Its members are not elected, and there is nothing special about them other than the willingness to develop the PHP community. Anyone can apply for membership. Anyone can submit their own feedback to php-fig recommendations at the proposed stage. The final Php-fig recommendations is often adopted and implemented by many of the largest and most popular PHP frameworks. I highly encourage you to be part of the php-fig, so just send your feedback and help your favorite PHP framework build the future together.

We often say that Php-fig is responsible for providing various recommendations, it is very important to understand this, because the recommendation is not the same as the rule, the recommendation is not to be executed. These recommendations are carefully thought-out and crafted to provide more convenience to PHP developers (and even the authors of the PHP framework).

Framework Collaboration

Php-fig's task is to achieve framework collaboration. Framework collaboration means collaborative work through interfaces, automatic loading, and coding styles.


The PHP framework works together through a shared interface. The framework uses the PHP interface to confirm which methods are provided by the third-party dependent libraries, regardless of how they are implemented by these dependent libraries.

Refer to chapter II for a detailed description of the PHP interface.

For example, a PHP framework happily shares a third-party logger object, assuming that the object implements emergency (), alert (), Critical (), error (), warning (), notice (), info () and debug () these several methods. The specifics of how these methods are implemented are irrelevant. Each framework only needs to be concerned with whether the third-party dependent libraries implement these methods.

Interfaces allow PHP developers to construct, share, and use functionally-exclusive components instead of huge frameworks.

Auto Load

PHP frameworks work together through automatic loading. With the auto-load feature, the PHP interpreter can automatically locate and load a PHP class as needed at run time.

Before the PHP standard was developed, PHP components and frameworks used the Magic function \_autoload () or higher-level spl_autoload_register () methods to implement their own independent autoloader. This forces us to familiarize ourselves with each of the components and frameworks that are unique to their respective autoloader to use them. Today, the vast majority of modern PHP components and frameworks are compatible with the common Auto loader standard. This means that we can use a unified autoloader to combine and match multiple PHP components together.

Coding style

PHP frameworks work together through coding styles. Your coding style determines the space, capitalization, and position of parentheses (especially important). If all PHP frameworks unify a standard set of coding styles, then PHP developers don't have to adapt to the new coding style every time they use the new PHP framework, and the code for the PHP framework doesn't seem so strange. A standard coding style can also reduce the entry threshold for newcomers in a project, so they can focus on solving bugs without having to spend a lot of time learning unfamiliar coding styles.

The standard coding style can also improve our own projects. Each developer has a unique obsession with coding, and the trouble arises when developers work together on the same codebase. A standard set of coding styles helps all team members immediately understand each other's code in the same code base without having to control who the author of the Code is.

What is PSR?

PSR is the abbreviation for PHP Standards Recommendation (PHP recommended standard). If you've read a few blogs about PHP recently, you may have seen a few terms like PSR-1, PSR-2, and PSR-3. These are the recommendations of Php-fig. Their names begin with psr-and end with a number. Each Php-fig recommendation is designed to address specific issues that are frequently encountered in most PHP frameworks. In order not to allow the various PHP frameworks to constantly solve the same problem, they can adopt these php-fig recommendations and build their own frameworks based on shared solutions.

As of the publication of this book, Php-fig has released 5 recommendations:

  • PSR-1: Basic Coding style
  • PSR-2: Strict coding style
  • Psr-3:logger interface
  • PSR-4: Auto Load

  • If you count, you will find only 4 recommendations, yes, Php-fig has abandoned the earliest PSR-0 recommendation. The original recommendation has been replaced by the newest PSR-4.

    Note that these recommendations of php-fig perfectly match the three ways I mentioned earlier about working together: interface, auto-load, and coding style. This is no coincidence.

    I am really excited about these recommendations for Php-fig. They are the cornerstone of the modern PHP ecosystem. They define the way in which PHP components and frameworks work together. I admit that discussing PHP standards is not an eye-catching topic, but they (in my mind) are a prerequisite for understanding modern PHP.

    PSR-1: Basic coding Style

    If you want to write your own code to be compatible with PHP community standards, start from PSR-1. This is the simplest standard to use. It's so simple that you don't realize that you may already be using these standards. PSR-1 provides simple guidelines that you can implement without having to spend too much effort. PSR-1 is designed to provide a baseline coding style that can participate in the PHP framework. To be compatible with the PSR-1 standard you need to meet several requirements below:

    PHP tags

    You must include your PHP code in or between tags. You may not use any other PHP tag syntax.

    Character encoding

    All PHP files must use UTF-8 encoding that does not contain a byte order mark (a byte sequence mark) (BOM). This may sound like a bit of a hassle, but most editors or Ides can automatically handle it for you.

    File usage

    In a separate PHP file, either define the declaration (a class, a trait, a function or a constant, etc.), or perform an operation that produces a result (such as outputting information or modifying data). But you can't do both. This is a simple task for you and requires a little forethought and planning.

    Auto Load

    Your PHP namespace and class must support the PSR-4 auto-load standard. All you have to do is declare a proper name for your PHP and make sure that their definition files are saved in the correct path. We will discuss PSR-4 later.

    Class name

    Your PHP class name must use the common CamelCase (uppercase hump) format. This format is also known as titlecase. such as Coffeegrinder, Coffeebean and Pourover.

    Constant name

    Your PHP constants must all be capitalized. You can use underscores to separate words if you want. such as Woot, Let_our_powers_combine and Great_scott.

    Method name

    Your PHP method name must use the common CamelCase (lowercase hump) format. This means that the first letter of the method name is lowercase, and the first letter of each subsequent sub-word is still capitalized. such as Phpisawesome, Ilovebacon and Tennantismyfavoritedoctor.

    PSR-2: Strict coding style

    After implementing the PSR-1 standard, the next step is to implement the PSR-2 standard. The PSR-2 standard defines a PHP coding style that contains stricter guidelines.

    The PSR-2 coding style is a gift from many contributors around the world to the PHP framework, sharing their own unique coding styles and preferences. The common, rigorous coding style allows developers to write code that is easy to understand for other people.

    Unlike PSR-1, the PSR-2 recommendation incorporates stricter guidelines. Some PSR-2 guidelines may not be as you wish. However, PSR-2 is also the preferred coding style for most popular PHP frameworks. There's no need to use PSR-2, but if you use it, your PHP code's readability and usability will be greatly improved for other developers.

    It is recommended that you use a more rigorous PSR-2 coding style, even if I use the word strict, but it is very simple to write, in fact, more than write to get used to. In addition, there are a number of tools that can automatically format code into PSR-2 style for us to use.

    Implement PSR-1

    PSR-2 coding style is the premise that you must first implement the PSR-1 coding style

    Indent in

    This is a hot topic between the two camps. One side prefers to use a tab tab for code indentation. The other side (the cooler side) prefers to use several spaces for code indentation. PSR-2 recommended that PHP code should be indented with four spaces

    Depending on your experience, the space character is more suitable for indenting because the spaces are almost identical in different code editors. The width of a tab tab varies from one code editor to another. Using four space characters to indent the code guarantees the best visual consistency of your code.

    Files and rows

    Your PHP file must use the Unix line break (LF) as the end of each line, the end of the file must have a blank line, you can not use the?> PHP tag as the end. Each line of code should not exceed 80 characters. Even if the standard is relaxed, the code for each line cannot exceed 120 characters. There can be no extra spaces at the end of each line. This sounds a lot of work, but it's essential. Most code editors can automatically wrap code at the width of a line, filter the null character at the end, and end with a UNIX line break. All of these questions should be handled automatically, without you having to think about them every time.

    At first I thought ignoring the end of the?> PHP tag was a very strange requirement. But ignoring the end tag to avoid an unknown output error is really a good habit. If you use the?> end tag at the end of the file and then have a blank line in the back, the empty row is treated as an output resulting in an error (for example, when you use the header function to set the HTTP header).


    I know that many PHP developers write true, false, and Null in full-capitalization form. If that's what you're doing, try to forget about the habit of using the all lowercase notation from now on. PSR-2 recommended that all PHP keywords should be written in full lowercase.

    Name space

    After each namespace declaration, there must be a blank line. Similarly, when using the Use keyword to import namespaces or their aliases, you must also add a blank line after the usage declaration, see the following example:

    namespace My\component;use symfony\components\httpfoundation\request;use symfony\components\httpfoundation\ Response;class app{    //Definition of Class}


    As with indentation, the position of parentheses in the class definition also raises another strongly controversial topic. Some people prefer to place the opening brackets in the same row after the class name, while others prefer a different line, placing the opening brackets in a new row after the class name. PSR-2 It is recommended that the opening parenthesis of a class definition be placed in a new row after the definition statement for the class name, as in the following example. The closing parenthesis of a class definition must be placed in a new row after the end of the class definition body. Maybe you've done what we said, so it's no big deal. If your class inherits from other classes or implements other interfaces, the extends and implements keywords must remain in the uniform row with the class name:



    The parentheses position in the method definition is the same as the bracket position defined by the class. The opening parenthesis of the method definition is placed in a new row after the method name. The closing parenthesis of the method definition is placed in a new row at the end of the method definition body. Note the parameters of the method. There can be no spaces after the first parenthesis, and no spaces before the most parentheses. The parameters of each method (except the last one) are followed by a comma and a space:


    You must declare a scope for each class's properties and methods. The scope is one of public, protected, or private, and the scope determines whether a property or method can be accessed inside or outside the class. Old-fashioned PHP developers may be accustomed to adding the VAR keyword to the class's attributes and underlining it before the private method. Never learn to do this, you must use one of the three scopes described earlier. If you need to declare a property or method of a class as abstract or final, then the abstract and final modifiers must precede the scope. If you declare a property or method static, the static modifier must be placed after the scope:

    Control structure

    This may be the guiding principle that I am most prone to make mistakes. All the key words of the control structure must follow a separate null character. Control structure keywords include: If, ElseIf, else, switch, case, while, do while, for, foreach, try, catch. If you need to use a pair of parentheses for the control structure keyword, make sure that you do not add a space after the first parenthesis, and no spaces in front of the last parentheses. Unlike the definition of classes and methods, the opening brackets must be placed after the control structure keyword and remain in the same line as the control structure keyword. The closing parenthesis of the control structure keyword must be a different line. Here is a simple example to illustrate these guidelines:

         Isawake () = = True) {do    {        $gorilla->beatchest (),    } while ($ibis->isasleep () = = = True);    $ibis->flyaway ();}

    You can automatically compatible with PSR-1 and PSR-2 coding styles. Many code editors follow PSR-1 and PSR-2 to format your code. In addition, there are tools to help you check and format your code in accordance with PHP standards. For example, PHP code Sniffer, which we often call phpcs, can be used to report the difference between your code and a given PHP code standard, either directly on the command line or in the IDE. You can install phpcs with almost any package management system (such as pear, Homebrew, aptitude, or Yum).

    You can also use Fabien Potencier's php-cs-fixer to fix most of the code incompatibilities. This tool is not perfect, but with it you only need to spend very little effort to ensure that you follow the PSR compatibility as much as possible.

    Psr-3:logger interface

    The third Php-fig recommendation is not a set of guidelines, as in the previous ones. PSR-3 is an interface that specifies a method that can be used to implement a PHP logger component.

    A logger is an object that can write information to a given output according to a variety of important degrees. The information that is recorded can be used to analyze, inspect, and remediate the operation, stability, and performance of the application. For example, during development, debug information is written to a text file, the site access statistics are saved to the database, or a fatal error analysis report is sent to the site administrator by mail. Currently the most popular PHP logger component is Monolog/monolog, the author is Jordi Boggiano.

    Many PHP frameworks have different requirements on log records. Before Php-fig was established, each framework resolved the log records differently, usually with a set of its own unique implementations. In the spirit of collaborative work and specialization (the theme of modern PHP unchanged), Php-fig established the PSR-3 logger interface. The framework accepts PSR-3-compatible logger to achieve two important goals: to give the development of logging to a third party, and the user of the framework to choose the logger component they like. For everyone, it's a winning result.

    Write a PSR-3 class of logger

    A PHP logger component that is compatible with the PSR-3 recommended standard must contain a class that implements the Psr\log\loggerinterface interface. The PSR-3 interface replicates the RFC 5424 System log protocol and defines nine methods:

    Each interface method corresponds to one level of the RFC 5424 protocol and receives two parameters. The first parameter, $message, must be a string or an object that contains the __tostring () method. The second parameter, $context, is optional and provides an array to hold the values of the placeholders to replace the tags (placeholders) in the first parameter.

    Complex logger information can be constructed using the $context parameter. You can use the placeholders (placeholder) in the message. A placeholder looks like {placeholder_name} so that it has a starting curly brace, a placeholder name, and an ending curly brace. Placeholders are not allowed to contain spaces. The $context parameter is an associative array whose keys correspond to the name of the placeholder (the middle portion of the two brackets), and its value can be used to replace the corresponding placeholder in the message text.

    To write a PSR-3 logger, create a new PHP class, implement the Psr\log\logger interface and provide a concrete implementation for each interface method.

    Using PSR-3 Logger

    If you're developing your own PSR-3 logger, take your time and consider whether it's wise to waste your days. I strongly do not recommend you to develop your own logger, why? Because there are now some of the perfect PHP logger components to use.

    If you need a PSR-3 logger, it's good to use Monolog/monolog directly. Don't waste events looking everywhere. The Monolog component fully implements the PSR-3 interface, and it is very easy to extend with custom message formatting tools and handlers. Monolog's message handlers allows you to send log messages to text files, syslog, mailboxes, Hipchat, Slack, Web servers, remote APIs, databases, and wherever you can imagine. In some extreme cases, if Monolog cannot provide a handler to satisfy your wonderful output target, it is very simple to develop your own Monolog message handler and integrate it into monolog. Example 3-1 demonstrates how simple it is to set up Monolog and log messages to a text file:

    Example 3-1 using Monolog

          Pushhandler (New Streamhandler (' Logs/development.log ', Logger::D ebug)); $log->pushhandler (New Streamhandler (' Logs/production.log ', logger::warning));//Use Logger$log->debug (' This is a debug message '); $log->warning (' This is a warning message ');


    The recommended standard for the fourth Php-fig describes a standardized autoloader strategy. Autoloader is a strategy for finding PHP classes, interfaces, or trait and loading them into the PHP interpreter at run time, on demand. PHP components and frameworks that support the PSR-4 Autoloader standard can be located and loaded into the PHP interpreter with a unique autoloader. Many of the components that work together can be linked to the modern PHP ecosystem, PSR-4.

    Why Autoloader so important?

    Do you often see this code at the top of your PHP file?

    You see it often, right? You may already be familiar with the require (), require_once (), include (), and inluce_once () functions. These functions are used to load an external PHP file into the current script, and if you don't have a lot of PHP scripts, that code works perfectly fine. But what if you need to include hundreds of PHP scripts? What if you need to include thousands of scripts? This exposes the extension of the require () and include () functions, which is why PHP autoloader is so important. A autoloader is a strategy for finding PHP classes, interfaces, or trait on demand at run time and loading them into the PHP interpreter, and it does not need to explicitly indicate the path of the file that needs to be loaded, as in the previous example.

    Before Php-fig introduced the PSR-4 recommendation criteria, the authors of the PHP components and frameworks used the __autoload () and Spl_autoload_register () functions to register their custom autoloader policies. Unfortunately, the autoloader of each PHP component and framework are unique, with each autoloader using different logic to locate and load PHP classes, interfaces, and trait. Developers were forced to use these components and frameworks when they had to invoke the autoloader of each component when their PHP application was initialized. I always like to use the Twig template component of Sensio Labs. This component is really great. However, without PSR-4, I would have to read Twig's documentation to figure out how to register its custom autoloader in my own application's initialization file, as follows:

    Imagine that every PHP component in your application, you have to look at the document to know how to register their unique autoloader. Php-fig was aware of the problem and proposed PSR-4 autoloader recommendations to facilitate the collaborative work of components. Thanks to PSR-4, we can use just one autoloader to load all the PHP components in our application. It's unbelievable. Most modern PHP components and frameworks are compatible with PSR-4. If you develop and publish your own components, make sure they are also compatible with PSR-4! Let your components work together like Symfony, Doctrine, Monolog, Twig, guzzle, Swiftmailer, PHPUnit, carbon, and many other components.

    PSR-4 autoloader Strategy

    As with other PHP autoloader, PSR-4 describes a strategy for locating and loading PHP classes, interfaces, and trait at run time. The PSR-4 recommendation does not require you to modify the implementation of your own code. In fact, PSR-4 just gives advice on how to organize your code into file system directories and PHP namespaces. The PSR-4 autoloader policy relies on PHP namespaces and file system directories to locate and load PHP classes, interfaces, and trait.

    The essence of PSR-4 is to map a top-level namespace prefix to a specific file system directory. For example, I can tell PHP that all classes, interfaces, or trait under the \oreilly\modernphp namespace are stored in src/, the physical file system directory. PHP now knows that any class, interface, or trait that uses the \oreilly\modernphp namespace prefix can correspond to subdirectories and files in the src/directory. For example, the \oreilly\modernphp\chapter1 namespace corresponds to the Src/chapter1 directory, and the \oreilly\modernphp\chapter1\example class corresponds to the src/chapter1/ example.php file.

    PSR-4 allows you to map a namespace prefix to a file system directory. The namespace prefix can be a top-level namespace. The namespace prefix can also be a top-level namespace plus any number of sub-namespaces. It's quite flexible.

    Remember the vendor namespace we mentioned in chapter two? The PSR-4 autoloader strategy is closely related to the release code to other developers ' components and framework authors. The code for a PHP component is under a unique vendor namespace, and the author of the component can specify which file system directory corresponds to the component's vendor namespace, as I demonstrated earlier. We will explore this concept in the fourth chapter.

    How to develop a PSR-4 Autoloader (and why not advise you to do so)

    We know that PSR-4 's compatible code has a namespace corresponding to the basic file system path. We also know that the sub-namespaces under the namespace prefix correspond to subdirectories of the base file system directory. Example 3-2 shows an implementation of the Autoloader borrowed from the Php-fig Web site, which can be used to find and load classes, interfaces, and trait based on PSR-4 autoloader policies.

    Example 3-2 PSR-4 autoloader

    Copy and paste this code into your application, modify the $prefix and $base_dir variables, then you have a PSR-4 autoloader that you can work with. However, if you want to write your own PSR-4 autoloader yourself, get your hands off and ask yourself if it's really worth it. Why? Because we can use the composer Dependency Management tool to automatically generate PSR-4 autoloader. It's really handy, that's what I'll be introducing in the fourth chapter below.
  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.