About PHP, we have a lot of misunderstanding, but in fact, modern PHP is a no matter the development efficiency or execution efficiency are quite high programming language. About the various aspects of modern PHP features, you can refer to <Modern PHP>
the author's previous written PHPthe right way, the Chinese translation: thepath of PHP . At the same time, the author is also a popular PHP framework – the developer of Slim . So this book is well worth reading, and even you just need to understand some of the concepts of OOP, and you don't need to understand PHP development.
- Part 1 Language Feature
- Features
- Namespaces
- Code to an interface
- Trait
- Generators
- Closures
- Zend Opcache
- Built-in HTTP server
- Part 2 Good Pratices
- Standards
- Php-fig
- Psr
- PSR-1 Basic Coding Standard
- PSR-2 Strict Code Style
- PSR-3 Logger Interface
- PSR-4 autoloaders
- Components
- Components
- Composer
- Semantic Versioning
- Create PHP Components
Part 1. Language featurefeaturesnamespaces
The PHP namespace uses "\" characters to split the sumnamespaces. Unlike the operating system's physical file system, the PHP namespace is an abstract concept that does not have to correspond to the file directory one by one. Most of the PHP components are based on the PSR-4 Autoloader standard to organize the mapping of Subnamespaces to the file directory.
Technically, namespaces is just a sign of the PHP language, and the PHP interpreter uses this notation as a prefix for a set of classes/interfaces/functions/constants sets, and that's all.
Namespaces are important because they let us create sandboxed code that works alongside other developer‘s code. This is the cornerstone concept of the modern PHP component ecosystem.
Helpful Tips
1. Multiple Imports
Bad
<?phpuse Symfony\Component\HttpFoundation\Request, Symfony\Component\HttpFoundation\Response, Symfony\Component\HttpFoundation\Cookie;
Good:
<?phpuse Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Cookie;
2. One class per file
3.Global Namespace
If we refer to a class/interface/function/constant,php that does not have a namespace, we will first assume that this class/interface/function/constant is in the current namespace. PHP will not start resolve if it is not found in the current namespace. For code that doesn't have namespaces, PHP thinks they exist in global namespace.
PSR-4
Code to an interface
An interface is a contract between tow PHP objects that lets one object depend not on what another object is but, instead, on what another can do.
Trait
A trait is a partial class implementation(i.e., constants, properties, and methods) that can be mixed into one or more existing PHP classes. Traits work double duty: they say what a class can do (like an interface), and they provide a modular implementation (like class).
Compared to Android development, one of my favorite iOS features is that category,php's trait is a bit like category, but it's not the same:
1. OC can only be extended for specific classes, and PHP trait may inject code units into arbitrary unrelated classes;
2. At the same time, the category in OC does not directly realize the extension of attributes, while PHP trait can implement constants, attributes, and methods;
3. PHP's trait is fundamentally different from the OC category, and OC is a direct extension of the existing class and does not require inheriting the implementation class. PHP's trait need to be used in the definition of the class use
to be clear.
As with the definition of class and interface, ontrait per file.
Generators
Generators are easy to create because they are just PHP functions that use the yield keyword one or more times. Unlike regular PHP functions, generators never return a value. They only yield values.
This concept is not unfamiliar, Python, including Swift, has this feature, can be used in the iteration of a large amount of data, dynamic to obtain data, rather than a one-time generation, to avoid the waste of memory.
During each iteration, PHP will let the generator instance compute and provide the next iteration value. In this process, when generator executes to yield value, generator pauses the execution of its internal state. Only when generator is asked to provide the next iteration value will it continue to execute its internal state. Generator so repeatedly pasuing and resuming, until it reaches the end of the function definition of generator or empty, generator will not finish execution.
Generators are a tradeoff between versatility and simplicity. Generators are forward-only iterators.
Closures
A closure is a function that encapsulates its surrounding state at the time it is created. The encapsulated state exists inside the closure even when the closure lives after it original environment ceases to exist.
The closures here refer to closure and anonymous functions. The above is the author's explanation of the closure, feeling very accurate, more simple and clear than most of the explanations I have seen. Closures are very useful in everyday business development, and it is very convenient to replace the delegate design patterns we often need, without having to define a interface, then implement this interface and pass the corresponding object pointers to the past. Instead, by closure, you simply pass a piece of code, which greatly simplifies everyday business development. So now in iOS development, we usually use block instead of delegate design mode.
PHP Closure or Anonymous function is the same as the PHP function definition syntax, but actually behind the Closure is the Closure class instance, so Closure is considered first-class Value types.
Attach State: PHP closure does not automatically enclose application state, unlike Javascript/oc, which can capture variables outside the scope. Butyou must manually attach state to a PHP closure with the closure object‘s bindTo() method or the use keyword.
It is important to note that PHP closures is objects. And we can make a closure instance variable call because this object implements the __invoke()
magic method, and when we follow one of the closure instance variables, the ()
closure instance variable will look for and invoke the __invoke()
method, For example $closure("Jason")
.
Again, because PHP closure is objects. So, inside closure we can also $this
access the various internal states of closure, but this state is very boring. At the same time, the closure bindTo()
method can have some very interesting special usages This method lets us bind a Closure object‘s internal state to a different object. The bindTo() method accepts an important second argument that specifies the PHP class of the object to which the closure is bound.This lets the closure access protected and private member variables of the object to which it is bound.
. This usage is somewhat similar to the JavaScript bind method, which can change the $this pointer of the closure object.
BindTo () is an interesting usage that is often used by various PHP framework routes, such as:
<?Php class App{ protected $routes=Array();protected $responseStatus=' OK ';protected $responseContentType=' text/html ';protected $responseBody=' Hello World '; Public function addroute($routePath, $routeCallback) { //Closure bind to App class $this->routes[$routePath] =$routeCallback->bindto ($this,__class__); } Public function dispatch($currentPath) { foreach($this->routes as $routePath=$callback) {if($routePath===$currentPath) {$callback(); } }//The state returned here is a modified callback within theHeader' http/1.1 '.$this. ResponseStatus); Header' Content-type: '.$this. Responsecontenttype); Header' content-length: '. Mb_strlen ($this->responsebody));Echo $this->responsebody; }}//Add register a route<?php$app=NewAPP ();$app->addroute ('/users/josh ', function() { //Because this route is bindto to the app class, so here direct access to $this modifies the app's internal state $this->responsecontenttype =' Application/json;charset=utf8 ';$this->responsebody =' {' name ': ' Josh '} ';});$app->dispatch ('/users/josh ');
Zend Opcache
Starting with PHP 5.5.0, PHP introduced the built-in bytecode cache support, called Zend OPcache
. PHP interpreter when executing PHP script, will first compile PHP code to Zend opcodes (machine-code instructions), then will execute bytecode. In all requests, the PHP interpreter needs to handle all PHP files, read/parse/compiles, but we can omit this overhead by pre-compiling PHP files into PHP bytecode, which is Zend OPcache
.
Zend OPcache
is very simple to use, after we configure it, it will automatically cache precompiled PHP bytecode in memory, if available, will execute the PHP bytecode directly, without the need to compile PHP code.
Specific configuration go to Google Bar, one thing to note is that if XDEBUG is configured at the same time, in the php.ini file, you need to load zend opcache extension extension before xdebug.
Built-in HTTP server
PHP introduced the built-in HTTP server from 5.4.0, so we can preview the PHP program directly without having to configure Apache or Nginx.
Remember, the PHP built-in server is a web server. It speaks HTTP, and it can serve static assets in addition to PHP files. It‘s a great way to write and preview HTML locally without installing MAMP, WAMP, or a heavyweight web server.
To use the built-in HTTP server is very simple, under the project root directory, execute the following command:
php -S localhost:4000
If you want other devices on your local network to access PHP Web server, we can start this:
0.0.0.0:4000
If we want to use the PHP INI configuration file to do some special configuration, you can start with the following command:
php -S localhost:8000 -c app/config/php.ini
We can also implement some special routing requirements through the router scripts, which can be started by the following command:
php -S localhost:8000 router.php
In PHP code, we can judge by php_sapi_name()
:
<?phpif (php_sapi_name() === ‘cli-server‘) { // PHP web server} else { // Other web server}
Part 2. Good Praticesstandardsphp-fig
Php-fig (PHP Framework Interop Group):The PHP-FIG is a group of PHP framework representatives who, according to the PHP-FIG website, "talk about the commonalities between our projects and find ways we can work together."
Php-fig is an open organization made up of many different PHP framework developers, and their proposed recommendations are not standards or requirements, more like the recommended collection of best pratices. However, the current more popular is the PHP framework, such as Laravel or Symfony, have complied with these recommendations, so this feeling is more like modern PHP de facto standard, if you want to use a lot of PHP tools and a large variety of open source libraries, It is best to adopt this standard.
The PHP-FIG‘s mission is framework interoperability. And framework interoperability means working together via interfaces, autoloading, and style.
As stated below, Php-fig's mission is to communicate between the different frameworks, so that they can be easily combined with each other. The realization of interoperability at present mainly through three aspects to start: interfaces, autoloading, style:
- Interfaces:
Interfaces enable PHP developers to build, share, and use specialized components instead of monolithic frameworks
, based on Interfaces, we can do a direct use of a framework of a component, such as Laravel HTTP processing part of the direct use of Symfony frameworks symfony/ Httpfoundation components without integrating the entire symfony into the laravel.
- Autoloading:
PHP frameworks work together via autoloading. Autoloading is the process by which a PHP class is automatically located and loaded on-demand by the PHP interpreter during runtime
before the autoloading standard comes out, PHP components and frameworks are based on \__autoload()或spl_autoload_register()
methods to implement their own unique autoloaders, so when we want to use a third-party component, It is necessary to study the implementation of Autoloaders first.
- Style:
PHP frameworks work together via code style.
Psr
The PSR is PHP standards recommendation
the abbreviation for the recommendations document presented by Php-fig, such as Psr-1,psr-2. Each Php-fig recommendation is designed to solve some of the most common problems encountered in the development of a PHP framework.
Currently on the official website of Php-fig, http://www.php-fig.org/psr/can see all the recommendations that are currently being adopted with the following:
The specific PSR document content, may refer to the official website, PSR-1/2/3/4 several documents to have the Chinese translation:
Document |
Original |
Chinese Translation |
PSR-1 Basic Coding Standard |
Https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md |
1190000002521577 |
PSR-2 Coding Style Guide |
Https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md |
1190000002521620 |
PSR-3 Logger Interface |
Https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md |
1190000002521644 |
PSR-4 autoloading Standard |
Https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md |
1190000002521658 |
PSR-1 Basic Coding Standard
PHP tags : using
PSR-2 Strict Code Style
Implement PSR-1 : Requires PSR-1
indentation : Use 4 space characters as indentation
Files And lines : You must use UNIX linefeed (LF) as the end; The file must end with a blank line, and you cannot use the trailing?> PHP tag; try not to more than 80 characters per line, at most more than 120 characters, each line ending cannot contain spaces;
Keywords : All PHP keywords must be lowercase
namespaces : Each namespace declaration must be followed by a blank line; When using use to import or alias namespaces, you must follow a blank line after the usage declaration,
Classes : When you define a class, The opening curly brace (opening bracket) must be a new line, and the closing curly brace (closing bracket) must be a new line after the class body definition, and the Extents/implements keyword must follow the class name definition; for example:
& lt;? PHP namespace my \ app ; class administrator Span class= "Hljs-keyword" >extends user { Class definition Body }
Methods: A method-defined brace rule is similar to a class definition, and opening brackets and closing brackets must have a new row.
Visibility: All property and method defined in a class must declare visibility (Visibility), visibility is public, protected, private one; abstract/ Final must be written before visibility; The static must be written after visibility;
Control Structures : All control structure keyword (if/elseif/else/switch/case/while/do while/for/foreach/try /catch) must be followed by a null character, the rules of the curly braces are different from the class definition, opening brackets with control structure keyword must be on the same line, and closing bracket must be a new line;
We can format the code with the IDE's formatting tools to implement the PSR-1 and PSR-2 codes style. I often use the tools phpstorm can be set. There are other tools, such as Php-cs-fixer or PHP Code Sniffer
PSR-3 Logger Interface
PSR-3 is an interface, and it prescribes methods that can be implemented by PHP logger components.
PSR-4 autoloaders
An autoloader is a strategy for finding a PHP class, interface, or trait and loading it into the PHP interpreter on-demand at runtime. PHP components and frameworks that support the PSR-4 autoloader standard can be located by and loaded into the PHP interpreter with only one autoloader.
With regard to PSR-4, the author of this book has a very concise explanation after reading the official documents and feeling confused:
The essence of PSR-4 is mapping a top-level namespaces prefix to a specific filesystem directory.
, in a nutshell, is the mapping between a namespaces prefix and a particular file directory, and then under this namespace prefix if there are more sub namespace, the Sub The namespaces will be mapped to subdirectories one by one below this particular directory. For example, \oreilly\modernphp namespace and src/physical path one by one mapping, then \oreilly\modernphp\chapter1 corresponding folder is Src/chapter1, and \oreilly\ The file path corresponding to the Modernphp\chapter1\example class is the src/chapter1/example.php file.
PSR-4 lets you map a namespace prefix to a filesystem directory. The namespace prefix can be one top-level namespace. The namespace prefix can also be a top-level namespace and any number of subnamespaces. It‘s quite flexible.
Componentscomponents
Modern PHP is less about monolithic framework and more about composing solutions from specialized and interoperable components.
What is the components ? :A component is a bundle of code that helps solve a specific problem in your PHP application.
Framework andcomponents: if we are creating a small project, we can use some of the PHP components to solve the problem, if we are working on a large project with a multi-person collaborative development, we can use a framework But this is not absolute and should be solved according to the specific problem.
packagist: Like other language package management mechanisms, such as MAVEN, there is also a website https://packagist.org/let us search for information about the PHP components we need. The general well-known reasons, packagist in the domestic very unstable, can use the domestic full-volume mirror to replace, http://www.phpcomposer.com/.
Composer
Composer is a dependency manager for PHP components taht runs on the command line
, like other modern languages, PHP uses composer for dependency management, similar to the Maven/gradle in iOS cocoapods,android, the Npm,ruby gem on the front, which greatly simplifies the cost of managing third-party libraries. So, when we find the components we need on packagist, we can use this library through composer.
When we use composer to add third-party component, composer will automatically help us to download the required PHP components, and will automatically help us create a autoloader that complies with PSR-4.
Similar to Cocoapods, Cocoapods uses Podfile to specify the third-party libraries that need to be relied upon, and to save the version number of the specific third-party library that is currently in use. So we need to add these two files to the version control to be managed, to ensure that different members of the/ci/development environment and other places to use the third-party library version of consistency. The files in the corresponding composer are Composer.json and Composer.lock. It is important to note the difference between the composer install and the composer Update command:
* Composer Install, will not be installed than the composer.lock listed in the higher version of components;
* Composer Update will update your components to the latest stable version and will also update the Composer.lock file to the latest PHP release number.
Semantic Versioning
Modern PHP components uses Semantic Versioning scheme, which also contains the decimal point (.) Three numbers separated, such as 1.13.2. At the same time, this is also a lot of other languages open Source Library version rules, for this has been more curious, finally in modern PHP to see the corresponding explanation.
- Major release Number: The first number is major release numbers, which needs to be incremented only if PHP component is no longer forward-compatible updates.
- Minor release Number: The second number is minor release numbers, which is incremented when PHP component has some minor feature updates and does not compromise version compatibility.
- Patch release Number: The last number is patch release numbers, which is incremented when version-compatible bug fixes occur.
Create PHP Components
This part is very similar to creating your own spec for iOS, it's not a very complex issue, and it's easy to publish a reference book or official document.
Modern PHP reading notes one