Do you know PHP now? Two

Source: Internet
Author: User
Tags anthony ferrara autoloader http post time zones php database php framework rfc traits
Good practice, this time mainly selected some development http://www.php.cn/"target=" _blank ">php application should be used on the good practice of detailed records, especially in good practice part of the password and flow two points. The code style, (my personal) common or common practice is simple to take.

II. Standards If you know Php-fig and PSR, you can skip this part.

The number of PHP components and frameworks is a lot, and the problem is that the separately developed framework does not take into account the communication with other frameworks. This is detrimental to both the developer and the framework itself.

Php-fig to break the old situation
Developers of multiple PHP frameworks are aware of the problem and have talked about it in Php|tek (a popular PHP conference) in 2009. The discussion concludes that we need a standard to improve the interoperability of the framework. The PHP framework Interop group, referred to as Php-fig, has been organized by these developers who met in Php|tek unexpectedly.

Php-fig is a framework that represents spontaneous organization, its members are not elected, and anyone can apply to join Php-fig and can submit feedback on recommendations in the proposed phase. In addition, Php-fig publishes recommendation specifications, not mandatory provisions.

What is 1.PSR?

PSR is the abbreviation for PHP Standards Recommendation (PHP recommended standard). As of today, Php-fig has released five recommended specifications:

    • PSR-1: The basic code style

    • PSR-2: A strict code style

    • PSR-3: Logger interface

    • PSR-4: Auto Load

You will find only four, yes, because the first recommendation specification PSR-0 abandoned, the newly released PSR-4 replaced.

2.PSR-1: The basic code style

If you want to write PHP code that conforms to community standards, you should first follow PSR-1. It is very simple to follow this standard and you may have used it again. The standard details are not written, the point link can be seen.

3.psr-2: A strict code style

PSR-2 is a further definition of PHP code specifications on the basis of PSR-1. This standard solves many centuries of problems, such as indentation, curly braces, and so on. Not much detail is recorded.

In addition, now many Ides (for example, Phpstorm) will have code formatting capabilities, set code formatting standards, write code, and then all formatted, can help you follow the recommendation specification, fixed some line-wrapping, indentation, curly braces and other details.


Setting standards

4.psr-3: Logger interface

This recommendation differs from the first two, which is an interface that specifies the methods that the PHP logger component can implement. The PHP logger component that complies with the PSR-3 recommendation must contain a PHP class that implements the Psr\log\loggerinterface interface. The PSR-3 interface re-uses the RFC 5424 System log protocol, which specifies the nine methods to be implemented:

<?phpnamespace psr\log;interface loggerinterface{public  function Emergency ($message, array $context = Array ()) ;  Public Function alert ($message, array $context = array ());  Public function Critical ($message, array $context = array ());  Public Function error ($message, array $context = array ());  Public Function Warning ($message, array $context = array ());  Public Function notice ($message, array $context = array ());  Public Function info ($message, array $context = array ());  Public Function debug ($message, array $context = array ());  Public function log ($level, $message, array $context = array ());}

Each method corresponds to a log level for the RFC 5424 protocol.

Using the PRS-3 Logger
If you are writing your own PSR-3 logger, you can stop. Because there are already some very good logger components. For example: Monolog/monolog, direct use can be. If the requirements are not met, it is also advisable to expand on this basis.

5.PSR-4: Auto Loader

This recommendation specification describes a standard autoloader strategy. The autoloader policy is to look for PHP classes, interfaces, or traits on demand at run time and load them into the PHP interpreter.

Why automatic loading is important
At the top of the php file, do you often see code similar to the following?

<?phpinclude ' path/to/file1.php '; include ' path/to/file2.php '; include ' path/to/file3.php ';

Using these functions (include (), include_once (), require (), require_once ()) can do a good job if you just load a few PHP scripts. But what if you were to introduce 1000 PHP scripts?

Before the PSR-4 recommendation specification, the authors of the PHP components and frameworks used the AutoLoad () and Spl_autoload_register () functions to register their custom autoloader policies. However, the autoloader for each PHP component and framework uses a unique autoloader. Therefore, the use of a number of components, but also a very troublesome thing.

The recommended use of the PSR-4 autoloader specification is to solve this problem and facilitate the interoperability of components.

PSR-4 Auto Loader policy
The PSR-4 recommendation specification does not require changing the way the code is implemented, it only suggests how to use the file system directory structure and the PHP namespace to organize the code. The essence of PSR-4 is to match the prefix of the namespace with the directory in the file system . For example, I can tell php,\oreilly\modernphp the classes, interfaces, and traits in the namespace are in the src/directory of the physical file system, so that PHP knows the classes, interfaces, and traits in the namespace prefixed with \oreilly\modernphp src/ directories and files in the directory.

How to write PSR-4 autoloader
If you are writing your own PSR-4 autoloader, please stop. We can use the dependency Manager composer Auto-generated PSR-4 autoloader.

Third, good practice

1. Filtering, verifying and escaping

Filtering HTML

Use the Htmlentities () function to filter the input.

<?php$input = ' <p><script>alert ("You won the Nigerian lottery!"); </script></p> '; Echo htmlentities ($input, ent_quotes, ' UTF-8 ');

Note that: By default, the Htmlentities () function does not escape single quotes, and the character set of the input string cannot be detected. The correct use is: the first argument input string, the second parameter is set to Ent_quotes constant, the transfer single quotation mark, the third parameter is set to the character set of the input string .

More ways to filter HTML input, you can use the HTML purifier library. This library is robust and secure, with drawbacks: Slow and may be difficult to configure.

SQL query

A bad way to build SQL queries:

$sql = sprintf (  ' UPDATE users SET password = '%s ' WHERE id =%s ',  $_post[' password '],  $_get[' id ']);

If psasword=abc";-- , it causes the records password to modify the entire users table to be not ABC. If you need to use input data in a SQL query, use the PDO preprocessing statement .

User profile Information

A. Filtering the email address in the user profile
This removes the characters, numbers, and!#$%& ' *+-/=?^_{|} ~@. All other symbols except for [].

<?php$email = ' beckjiang@meijiabang.cn '; $emailSafe = Filter_var ($email, Filter_sanitize_email);

B. Filtering foreign characters in user profiles

<?php$string = "foreign character"; $safeString = Filter_var (  $string,  filter_sanitize_string,  filter_flag_strip_ low| Filter_flag_encode_high);

Validating data

Validation data is different from filtering, and validation does not delete information from the input data, but only confirms that the input data meets expectations.

Verify e-mail address
We can pass a filter_validate_* flag to the Filter_var () function, in addition to the e-mail address, you can also verify the Boolean value, floating point number, integer, IP address, regular expression, and URL.

<?php$input = ' beckjiang@meijiabang.cn '; $isEmail = Filter_var ($input, Filter_validae_email); if ($isEmail!== false) {  echo "Success";} else {  echo "Fail";}

2. Password

There are many kinds of hashing algorithms, such as MD5, SHA1, Bcrypt, and Scrypt. Some algorithms are fast enough to validate data integrity, while others are slow and designed to improve security. A slow, high-security algorithm is required to generate passwords and store passwords.

Currently, peer-reviewed, the safest hashing algorithm is bcrypt. Unlike MD5 and SHA1, Bcrypt is deliberately designed slowly. The bcrypt algorithm automatically adds salt to prevent potential rainbow table attacks. The bcrypt algorithm is never outdated, and if the computing speed of the computer becomes faster, we only need to increase the value of the working factor.

Recalculate the hash value of the password
Here is the script for the logged-on user:

<?phpsession_start (); try {//Get e-mail address from request body $email = Filter_input (input_  POST, ' email ');  Obtain the password from the request body $password = Filter_input (input_post, ' password ');  Use the email address to get the user (note that this is fictitious code) $user = User::findbyemail ($email);  Verify that the password and the account's password hash Match if (Password_verify ($password, $user->password_hash) = = = False) {throw new Exception (' Invalid  Password ');  }//If necessary, recalculate the hash value of the password $currentHashAlgorithm = Password_default;  $currentHashOptions = Array (' cost ' = 15);  $passwordNeedRehash = Password_needs_rehash ($user->password_hash, $currentHashAlgorithm, $currentHashOptions  ); if ($passwordNeedsRehash = = = True) {//Save the newly computed password hash (note that this is a fictitious code) $user->password_hash = Password_hash ($pass    Word, $currentHashAlgorithm, $currentHashOptions);  $user->save (); }//Save login status to reply ...//redirect to Profile page ...} catch (Exception $e) {//exception handling ...} 

It is important to note that before you log in, be sure to use the Password_needs_rehash () function to check if the existing password hash in the user record is out of date. If it expires, the password hash value is recalculated .

Password Hash API prior to PHP5.5.0
If you cannot use PHP5.5.0 or later, you can use the Ircmaxell/password-compat component developed by Anthony Ferrara. This component implements all the functions in the PHP password hash API:

    • Password_hash ()

    • Password_get_info ()

    • Password_needs_rehash ()

    • Password_verify ()

3. Date, time, and time zone

DateTime class

The DateTime class provides an object-oriented interface for managing dates and times.

Without parameters, create an instance that represents the current date and time:

<?php$datetime = new DateTime ();

To create an instance of an incoming parameter:

<?php$datetime = new DateTime (' 2017-01-28 15:27 ');

Specifies the format, statically constructed:

<?php$datetime = Datetime::createfromformat (' M J, Y h:i:s ', ' Jan 2, 2017 15:27:30 ');

DateInterval class

A DateInterval instance represents a fixed length of time (for example, "two days"), or a relative time period (for example, "Yesterday"). The DateInterval instance is used to modify a DateTime instance.

Use the DateInterval class:

<?php//Create a DateTime instance $datetime = new DateTime ()//Create an interval of two weeks $interval = new DateInterval (' p2w ');//Modify a DateTime instance $ Datetime->add ($interval); Echo $datetime->format (' y-m-d h:i:s ');

To create a reverse DateInterval instance:

<?php//the past day $interval = new DateInterval ('-1 days ');

Datetimezone class

If your app caters to international customers, you might want to fight the time zone.

Create, use time zones:

<?php$timezone = new Datetimezone (' america/new_york '); $datetime = new DateTime (' 2017-01-28 ', $timezone);

After instantiation, you can also use the setTimeZone() function to set up the city:

$datetime->settimezone (New Datetimezone (' Asia/hong_kong '));

Dateperiod class

Sometimes we need to iterate over a series of dates and times that recur over time, and the Dateperiod class solves this problem. The construction method of the Dateperiod class accepts three parameters, and all must provide:

    • A DateTime instance that represents the date and time at which the iteration started.

    • An DateInterval instance that represents the interval to the next date and time.

    • An integer that represents the total number of iterations.

an Dateperiod instance is an iterator that produces a DateTime instance each time it is iterated .

Use the Dateperiod class:

<?php$start = new DateTime (), $interval = new DateInterval (' p2w '); $period = new Dateperiod ($start, $interval, 3); FOREAC H ($period as $nextDateTime) {  echo $nextDateTime->format (' y-m-d h:i:s '), Php_eol;}

4. Database

PHP applications can persist information in many types of databases, such as MySQL, SQLite, Oracle, and so on. If you use multiple databases in your project, you need to install and learn a variety of PHP database extensions and interfaces, which adds to the cognitive and technical burden.

It is for this reason that PHP native provides the PDO extension (PHP data Objects, which means PHP object), and PDO is a series of PHP classes that abstract specific implementations of different databases. The introduction and use of PDO is not written, more commonly used.

5. Flow

In modern PHP features, the flow may be the best but least used. Although PHP4.3.0 introduces streams, many developers do not know the existence of streams because few people refer to streams, and the flow of documents is scarce. The official explanation is difficult to understand, and one saying is that the function of the stream is to transfer data between the origin and the destination .

I understand the flow as a conduit, which is equivalent to bringing water from one place to another. In the process of water flowing from the origin to the destination, we can filter the water, change the water quality, add water, or drain water (hint: water is a metaphor for data).

Flow Encapsulation Protocol

Streaming data is different, and each type requires a unique protocol to read and write data. We call these protocols a flow encapsulation protocol. For example, we can read and write file systems, communicate with Remote Web servers via HTTP, HTTPS, or SSH, and open and read zip, RAR, or Phar Compressed files. These communication methods include the following same procedure:

    1. Start communication.

    2. Read the data.

    3. Write the data.

    4. End the communication.

Although the process is the same, the way files are read and written in the file system differs from the way HTTP messages are done. The purpose of the Flow encapsulation protocol is to encapsulate these differences using a common number of ports.

Each flow has a protocol and a target. The format is as follows:

<scheme>://<target>

That's a bit of a rip-off, first look at examples, using the HTTP streaming encapsulation protocol to communicate with the Flickr API:

<?php$json = file_get_contents (  ' Http://api.flickr.com/services/feeds/photos_public.gne?format=json ');

do not mistakenly think that this is a normal page the string parameter of the url,file_get_contents () function is actually a stream identifier. The HTTP protocol allows PHP to encapsulate the protocol using HTTP streaming . It looks like a normal web page URL, because the HTTP streaming wrapper protocol is:). Other flow encapsulation protocols may not be the case.

file://Flow Encapsulation Protocol

We use file_get_contents() , fopen() , fwrite() and fclose() functions to read and write file systems. Because PHP uses the Stream encapsulation protocol by default file:// , we rarely think of these functions as using PHP streams.

Implicit use of the file:// Flow Encapsulation protocol:

<?php$handle = fopen ('/etc/hosts ', ' RB '), while (feof ($handle)!== true) {  echo fgets ($handle);} Fclose ($handle);

Explicitly using the file:// Flow Encapsulation protocol:

<?php$handle = fopen (' file:///etc/hosts ', ' RB '), while (feof ($handle)!== true) {  echo fgets ($handle);} Fclose ($handle);

Stream context

Some PHP streams can accept some column-selectable parameters called stream contexts, which are used to customize the behavior of the stream. The stream context is created using a stream_context_create() function.

For example, do you know that you can use a file_get_contents() function to send an HTTP POST request? If you want to do this, you can use a stream context object:

<?php$requestbody = ' {' username ': ' Beck '} '; $context = stream_context_create (Array ('  http ' = = Array (    ' Method ' = ' and ' POST ',    ' header ' = ' content-type:application/json;charset=utf-8;\r\n '.                 Content-length: ". Mb_strlen ($requestBody),    "content" ($requestBody  ))); $response = file_get_contents (' https:// My-api.com/users ', false, $context);

Flow Filter

The real powerful thing about PHP's flow is to filter, transform, add, or delete data transferred in the stream .

Note: PHP has several stream filters built in: string.rot13, String.ToUpper, String.ToLower, and String.strp_tags. These filters are useless, and we're going to use a custom filter.

To attach a filter to an existing stream, use the stream_filter_append() function. For example, if you want to convert the contents of a file into uppercase letters, you can use the String.ToUpper filter. It is not recommended to use this filter in the book, just to show how to attach the filter to the flow:

<?php$handle = fopen (' data.txt ', ' RB '); Stream_filter_append ($handle, ' string.toupper '); while (feof ($handle)!== true) {  echo fgets ($handle);//<--output is all uppercase letters}fclose ($HANDLE);

php://filterattach the filter to the stream using the Flow wrapper protocol:

<?php$handle = fopen (' php://filter/read=string.toupper/resource=data.txt ', ' RB '), while (feof ($handle)!== true) {  Echo fgets ($handle);//<--The output is all uppercase letters}fclose ($HANDLE);

To see a more realistic flow filter example, if our Nginx access log is saved in Rsync.net, one day's access is saved in a log file, and each log file is compressed using bzip2, with the name format: yyyy-mm-dd.log.bz2. One day, the leader asked me to extract access data for a domain name for the past 30 days. Iterate bZIP compressed log files using the DateTime class and stream filters :

<?php$datestart = new \datetime (); $dateInterval = \dateinterval::createfromdatestring ('-1 day '); $datePeriod = new \ Dateperiod ($dateStart, $dateInterval, 30);//Create iterator foreach ($datePeriod as $date) {  $file = ' Sftp://user: pass@rsync.net/'. $date->format (' y-m-d '). ' log.bz2 ';  if (file_exists ($file)) {    $handle = fopen ($file, ' RB ');    Stream_filter_append ($handle, ' bzip2.decompress ');    while (feof ($handle)!== true) {      $line = fgets ($handle);      if (Strpos ($line, ' www.example.com ')!== false) {        fwrite (STDOUT, $line);      }    }    Fclose ($handle);  }}

Calculate the date range, determine the name of the log file, connect rsync.net by FTP, download the file, unzip the file, iterate through each file line by row, extract the corresponding row, and then write the access data to an output target. With PHP streaming, you can do all these things in less than 20 lines of code.

Custom Stream Filters

In most cases, you will use a custom stream filter. The custom stream filter is a PHP class that inherits the built-in Php_user_filter class. This class must be implemented filter() , onCreate() and onClose() methods. Also, you must use stream_filter_register() a function to register your custom stream filter.

The PHP stream divides the data into sequential buckets, and the amount of stream data in a bucket is fixed. A bucket received by a filter within a certain time is called a bucket queue . Each bucket object in a bucket queue has two exposed properties: Data and Datalen, respectively, and the length of the content and content in the bucket.

The following defines a flow filter that handles dirty word :

<?phpclass Dirtywordsfilter extends php_user_filter{/** * @param resource $in     Stream the bucket queue * @param resource $out stream the bucket queue * @param resource $consumed The number of bytes processed * @param resource $closing   Is the last bucket queue in the stream?    */Public Function filter () {$words = array (' grime ', ' dirt ', ' grease ');    $wordData = Array ();      foreach ($words as $word) {$replacement = Array_fill (0, Mb_strlen ($word), ' * ');    $wordData [$word] = implode ("', $replacement);    } $bad = Array_keys ($wordData);    $goods = Array_values ($wordData); Iterates over each bucket in the bucket queue while ($bucket = stream_bucket_make_writeable ($in)) {//review dirty word in bucket data $bucket->data = Str_re      Place ($bad, $goods, $bucket->data);      Increase the amount of data processed $consumed + = $bucket->datalen;    Stream_bucket_append ($out, $bucket) by placing the bucket in a queue flowing downstream;  } return psfs_pass_on; }}

filter()The function of the method is to accept and process the flow data in the re-transfer bucket. The return value of this method is PSFS_PASS_ON constant, indicating that the operation was successful.

Register Stream Filter
Next, we must stream_filter_register() register this custom Dirtwordsfilter stream filter with a function:

<?phpstream_filter_register (' Dirty_words_filter ', ' dirtwordsfilter ');

The first parameter is the filter name used to identify the custom filter, and the second parameter is the class name of the custom filter.

Using the Dirtwordsfilter Flow filter

<?php$handle = fopen (' data.txt ', ' RB '); Stream_filter_append ($handle, ' dirty_words_filter '); while (feof ($handle)! = = True) {  echo fgets ($handle);//<--output after review of text}fclose ($handle);

6. Errors and exceptions

For error and exception handling, be sure to follow four rules:

    • Be sure to let PHP report errors.

    • Errors are displayed in the development environment.

    • Errors cannot be displayed in the production environment.

    • Errors are logged in both the development environment and the production environment.

Errors and anomalies in the daily use of more than the record.

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.