- URL: https://www.laruence.com/en/2011/03/24/858.html
- Please include attribution when republishing.
Here are some PHP Coding Tips. Of course, these tips aren't necessarily limited to PHP.
If you have any good insights, feel free to reply to this article directly and share with more people.. Thanks.
This article is updated long-term, follow PHP Coding Tips.
Last updated: 2011-04-02
list( , $mid) = explode(';', $string);
is_null and NULL === have exactly the same effect, but it saves a function call.
PHP has two groups of equality operators ===/!== and ==/!=. ==/!= involves implicit type conversion, while ===/!== strictly compares whether the two operands have the same type and equal value.
We should use === instead of == as much as possible. Besides the fact that the conversion rules are hard to remember, another point is that if you use ===, future maintainers or readers of your code will be very comfortable with it: "at this moment, on this line, this variable is exactly this type!".
continue returns to the head of the loop, and a loop ending naturally already returns to the head of the loop. So with appropriate structuring, we can avoid using this statement entirely, improving efficiency.
switch and in_array both use loose comparison, so when the types of the variables being compared differ, it's easy to make mistakes:
switch ($name) {
case "laruence":
...
break;
case "eve":
...
break;
}
For the switch above, if $name is the number 0, then it will satisfy any case. The same applies in in_array.
The fix is to convert the variable's type to the type you expect before the switch.
switch (strval($name)) {
case "laruence":
...
break;
case "eve":
...
break;
}
And in_array provides a third optional parameter, through which you can change the default comparison mode.
For example, the following code:
if($a) {
} else if ($b) {
} else if ($c || $d) {
}
can be simply rewritten as:
switch (TRUE) {
case $a:
break;
case $b:
break;
case $c:
case $d:
break;
}
Isn't that clearer?
Using an undefined variable is 8x or more slower than using a defined one!
You can imagine: the PHP engine first tries to fetch this variable through normal logic, but the variable doesn't exist, so the engine has to throw a NOTICE, then enter the logic path it should take for undefined variables, and return a new variable.
Also, from a code-reading standpoint, when you use an undefined variable, it confuses readers of your code: "where is this variable initialized, does it have anything to do with the earlier code? with the included files?"
Finally, from a coding-standards standpoint, you should do this too.
list($a, $b) = array($b, $a),
but there's still an anonymous temporary variable created. For integers, doing it with inverse operations is still fairly reliable:
$a = $a + $b; $b = $a - $b; $a = $a - $b;
However, using XOR is better, because + - * / are prone to precision loss or overflow.
echo ~~4.9; echo floor(4.9);
Using double bitwise-not is basically 3x the speed of floor, but one caveat: for large numbers it may overflow:
echo ~~99999999999999.99; //276447231 echo floor(99999999999999.99); //99999999999999
We know that do{}while(0) has many clever uses in C/C++, e.g. eliminating goto, macro code blocks.
So likewise in PHP, you can use do{}while(0) to do some clever things:
do{
if(true) {
break;
}
if(true) {
break;
}
} while(false);
//better than
if(true) {
} else if(true) {
} else {
}
The following code:
@func();
is equivalent to (see Error Suppression and Embedded HTML in PHP Internals):
$report = error_reporting(0); func(); error_reporting($report);
Also, the error-suppression operator can cause some problems, see (Bug where PHP's @ error-suppression breaks reference passing);
Finally, the error-suppression operator can also cause trouble when debugging errors.
Recursion has poor performance, and most recursion is tail recursion, which can be eliminated.
function f($n) {
if ($n = 0) return 1;
return $n * f($n - 1);
}
//becomes:
$result = 1;
for ($y = 1; $y < $n + 1; $y++ ) {
$result *= $y;
}
time() incurs a function call. If you don't need a precise value of the time, you can use $_SERVER['REQUEST_TIME'] instead, which is much faster.
The following code:
for($i=0; $i<strlen($str); $i++) {
}
causes strlen to be called every iteration. Change it to:
for ($i=0, $j=strlen($str); $i<$j; $i++) {
}
Regex is slow; avoid it where possible, and use direct string-processing functions instead, e.g.:
if (preg_match("!^foo_!i", "FoO_")) { }
// replace with:
if (!strncasecmp("foo_", "FoO_", 4)) { }
if (preg_match("![a8f9]!", "sometext")) { }
// replace with:
if (strpbrk("a8f9", "sometext")) { }
if (preg_match("!string!i", "text")) {}
// replace with:
if (stripos("text", "string") !== false) {}
and so on.
The following code:
echo "$name[2]";
PHP can't tell whether the programmer meant $name . "[2]" or $name[2].
So the advice is to always add braces:
echo "{$name}[2]";
//or
echo "${name}[2]";
For operation-type functions, return FALSE on failure, meaning "the operation failed"; for query-type functions, if the value you're looking for isn't found, return NULL, meaning "not found".
Be First to Comment