Programming Guide for PHP developers The first part reduces complexity, developer Programming Guide
PHP is a very high-freedom programming language. It is a dynamic language and has great latitude for programmers. As a PHP programmer, to make your code more effective, you need to know a lot of specifications. For many years, I have read many books on programming and have discussed code style issues with many senior programmers. I certainly don't remember any particular rule from which book or person, but this article (and the next article) expresses my view on how to write better code: the code that can withstand the test is usually very readable and easy to understand. This code makes it easier for others to find a problem, or it can be easier to reuse code.
Reduce the complexity of the function body
In a method or function body, reduce complexity as much as possible. The relatively low complexity makes it easy for others to read the code. In addition, this also reduces the likelihood of code problems, makes it easier to modify, and makes it easier to fix problems.
Reduce the number of parentheses in a function
Use if, ElseIf, else, and switch as few of these statements as possible. They will add more parentheses. This makes the code more difficult to understand and harder to test (because each parenthesis requires a test case overlay). There is always a way to avoid this problem.
Proxy decision ("command, don't go to query (tell, Don t ask)")
Sometimes the If statement can be moved to another object, which is clearer. For example:
if ($a->somethingistrue ()) { $a->dosomething ();}
Can be changed to:
$a->dosomething ();
Here, the specific judgment is done by the dosomething () method of the $a object. We do not need to do more to do this, just need to safely call DoSomething (). This way gracefully follows the command, not to query the principle. I suggest you take a closer look at this principle, which can be applied when you are querying information from an object and making judgments based on that information.
Using map
Sometimes you can use the map statement to reduce if, elseif, or else uses, for example:
if ($type = = = ' json ') { return $jsonDecoder->decode ($body);} ElseIf ($type = = = ' xml ') { return $xmlDecoder->decode ($body);} else{ throw new \logicexception ( ' Type ' '. $type. ' is not supported ' );}
Can be streamlined to:
$decoders = ...;//a map of type (string) to corresponding Decoder objects if (!isset ($decoders [$type])) { Thrownew\log Icexception ( ' Type ' '. $type. ' is not supported ' );}
This way of using map also allows your code to follow the extension of open, off the principle of modification.
Coercion Type
Many if statements can be avoided by stricter usage types, such as:
if ($a instanceof a) { //happy path return $a->someinformation ();} ElseIf ($a = = = null) { //alternative path return ' default information ';}
You can simplify by forcing the $a to use Type a:
Return $a->someinformation ();
Of course, we can support the "null" case in other ways. This will be mentioned in the following article.
Return Early
Most of the time, a branch in a function is not a true branch, but rather a pre-or post-set condition, like this://preconditions
if (! $a instanceof a) { throw new \invalidargumentexception (...);}//Happy Pathreturn $a->someinformation ();
Here the IF statement is not a branch of the function execution, it is just a check on a precondition. Sometimes we can ask PHP to do a pre-condition check (for example, using appropriate type hints). However, PHP is not able to complete all the pre-condition checks, so still need to keep some in the code. To reduce complexity, we need to return as early as possible when we know that the code will go wrong, enter an error, and already know the result.
The effect of returning early is that the following code does not need to be indented as before:
Check preconditionif (...) { thrownew ... ();} Return Earlyif (...) { return ...;}//Happy path ... return ...;
Like the template above, the code changes to be easier to read and understand.
To create a small logical unit
If the function body is too long, it is difficult to understand what the function is doing. The use of tracking variables, variable types, variable declaration periods, called helper functions, and so on, all consume a lot of brain cells. If the function is small, it is helpful to understand the function function (for example, the function simply accepts some input, does some processing, and then returns the result).
Using auxiliary functions
After using the previous principle to reduce parentheses, you can also make the function clearer by splitting the function into smaller logical units. You can think of a line of code that implements a subtask as a set of code that is separated directly by a blank line. Then consider how to split them into auxiliary methods (i.e., the refinement method in refactoring).
A helper method is typically a private method that is called only by an object of the particular class to which it belongs. Typically, they do not require access to the instance's variables, which requires a method defined as static. In my experience, the helper methods of private (static) are often aggregated into separate classes and defined as public (static or instance) methods, at least when testing-driven development uses a collaborative class.
Reduce temporary variables
Long functions usually require some variables to hold the intermediate results. These temporary variables are tricky to track: You need to remember whether they are initialized, whether they are useful, what the value is now, and so on.
The auxiliary functions mentioned in the previous section help reduce temporary variables:
Public function Capitalizeandreverse (array $names) { $capitalized = array_map (' Ucfirst ', $names); $capitalizedAndReversed = Array_map (' Strrev ', $capitalized); return $capitalizedAndReversed;}
Using the helper method, we can use no temporary variables:
Public function Capitalizeandreverse (array $names) { return Self::reverse ( self::capitalize ($names)) ;} private static function reverse (array $names) { return Array_map (' Strrev ', $names);} private static function Capitali Ze (array $names) { return Array_map (' Ucfirst ', $names);}
As you can see, we turn functions into a combination of new functions, which makes them easier to understand and easier to modify. In some way, the code is also somewhat in line with "Extended Open/modified shutdown" because we basically do not need to modify the auxiliary function.
Since many algorithms need to traverse the container to get a new container or to calculate a result, it makes sense to treat the container itself as a "top citizen" and attach the relevant behavior:
classnames{ private $names; Public function __construct (array $names) { $this->names = $names; } Public function reverse () { return to new self ( array_map (' Strrev ', $names) ); } Public function capitalize () { return to new self ( array_map (' Ucfirst ', $names) );} } $result = (Newnames ([...])) ->capitalize ()->reverse ();
Doing so simplifies the combination of functions.
Although reducing temporary variables usually leads to good design, there is no need to kill all the temporary variables in the example above. Sometimes the use of temporary variables is very clear, the role is at a glance, there is no need to streamline.
Use a simple Type
Tracking the current value of a variable is always cumbersome, especially if the type of the variable is not clear. And if the type of a variable is not fixed, it is a nightmare.
Arrays contain only values of the same type
When using an array as a traversal container, be sure to use only the same type of value, regardless of the situation. This can reduce the complexity of looping through the array to read the data:
foreach ($collection as $value) { //If you specify the type of $value, you do not need to do type checking}
Your code Editor will also provide you with type hints for array values:
/** * @param datetime[] $collection */public function dosomething (array $collection) { foreach ($collection as $value) { //$value is a datetime type }}
And if you're not sure $value is a DateTime type, you have to add a pre-judgment to the function to check its type. The Beberlei/assert library can make this thing a little simpler:
Useassert\assertion Public Function dosomething (array $collection) { assertion::allisinstanceof ($collection, \ Datetime::class); ...}
This throws a InvalidArgumentException exception if the container contains content that is not a DateTime type. In addition to forcing input of values of the same type, using assertions (assert) is also a means of reducing the complexity of the code, because you can not do type checking on the head of the function.
Simple return value type
As long as the return value of the function may have different types, it will greatly increase the complexity of the calling code:
$result = SomeFunction (); if ($result = = = False) { ...} else if (Is_int ($result)) { ...}
PHP does not prevent you from returning different types of values (or using different types of parameters). But doing so will only create a lot of confusion, and your program will be filled with if statements everywhere.
The following is an example of a frequently encountered return mix type:
/** * @param int $id * @return user|null */public function FindByID ($id) { ...}
This function returns the user object or null, which is problematic, and if you do not check the user object for which the return value is legitimate, we cannot call the method that returns the value. Before PHP 7, doing so would cause "Fatal error" and then the program would crash.
In the next article we will consider null and tell you how to deal with them.
Readable expressions
We have discussed a number of ways to reduce the overall complexity of a function. In finer granularity we can also do something to reduce the complexity of the code.
Hide complex logic
It is often possible to turn complex expressions into auxiliary functions. Take a look at the following code:
if ($a | | $b) && $c) { ...}
Can be made simpler, like this:
if (Somethingisthecase ($a, $b, $c)) { ...}
When reading the code, it is clear that this judgment relies on $a, $b and $c three variables, and the function name can also be very good at expressing the content of the judging condition.
Using Boolean expressions
The contents of an if expression can be converted to a Boolean expression. However, PHP does not force you to provide a Boolean value:
$a =new\datetime (), .... if ($a) { ...}
The $a is automatically converted to a Boolean type. Forcing type conversions is one of the main sources of bugs, but there is also a problem with the complexity of the code's understanding because the type conversions are implicit. An alternative to the implicit conversion of PHP is to explicitly type-convert, for example:
if ($a instanceof DateTime) { ...}
If you know that the comparison is of type bool, you can simplify this:
if ($b = = = False) { ...}
Use! The operator can also be simplified:
if (! $b) { ...}
Don't Yoda style expressions.
Yoda-style expressions are like this:
if (' hello ' = = = = $result) { ...}
The main purpose of this expression is to avoid the following error:
if ($result = ' Hello ') { ...}
Here ' Hello ' is assigned to the $result and then becomes the value of the entire expression. ' Hello ' is automatically converted to the bool type, where it is converted to true. So the code in the If branch will always be executed here.
Using Yoda-style expressions can help you avoid these kinds of problems:
if (' hello ' = $result) { ...}
I don't think there will be any such errors in the actual situation, unless he is still learning basic PHP syntax. Also, the Yoda-style code has a cost: readability. Such expressions are not easy to read and easy to understand because they do not conform to natural language habits.
The above is the whole content of this article, I hope that everyone's study has helped.
Articles you may be interested in:
- Code for deferred execution effects in PHP and JS programming
- The difference between this,self,parent that you need to understand in the PHP programming process
- "PHP Programming Fastest Clear" Fourth: date, form reception, session, Cookie
- "PHP Programming Fastest Clear" sixth: MySQL database operation
- Object-oriented programming of PHP learning notes
- Drill down into PHP's canonical programming naming summary
- PHP Programming Style specification sharing
- PHP Using Socket Programming Example
- PHP Multi-Process Programming example
http://www.bkjia.com/PHPjc/1093710.html www.bkjia.com true http://www.bkjia.com/PHPjc/1093710.html techarticle Programming Guide for PHP developers The first part reduces complexity, and the Developer Programming Guide PHP is a highly liberal programming language. It is a dynamic language and has great tolerance for programmers ...