基础

比较运算符

比较运算符是PHP经常被忽视的一个方面,可能导致许多意想不到的结果。其中一个问题源于严格的比较(将布尔值作为整数进行比较)。

<?php
$a = 5;   // 5 as an integer

var_dump($a == 5);       // compare value; return true
var_dump($a == '5');     // compare value (ignore type); return true
var_dump($a === 5);      // compare type/value (integer vs. integer); return true
var_dump($a === '5');    // compare type/value (integer vs. string); return false

//Equality comparisons
if (strpos('testing', 'test')) {    // 'test' is found at position 0, which is interpreted as the boolean 'false'
    // code...
}

// vs. strict comparisons
if (strpos('testing', 'test') !== false) {    // true, as strict comparison was made (0 !== false)
    // code...
}

有条件的陈述

如果声明

在函数或类方法中使用“if / else”语句时,存在一种常见的误解,即“else”必须结合使用才能声明潜在的结果。但是,如果结果是定义返回值,则'else'不是必需的,因为'return'将结束该函数,导致'else'变得没有实际意义。

<?php
function test($a)
{
if ($a) {
    return true;
} else {
    return false;
}
}

// vs.

function test($a)
{
if ($a) {
    return true;
}
return false;    // else is not necessary
}

// or even shorter:

function test($a)
{
return (bool) $a;
}

切换语句

切换语句是避免输入无穷无尽的if和else的好方法,但有几点需要注意:

<?php
$answer = test(2);    // the code from both 'case 2' and 'case 3' will be implemented

function test($a)
{
switch ($a) {
    case 1:
        // code...
            break;             // break is used to end the switch statement
        case 2:
        // code...         // with no break, comparison will continue to 'case 3'
        case 3:
        // code...
            return $result;    // within a function, 'return' will end the function
        default:
        // code...
            return $error;
}
}

全局命名空间

使用命名空间时,您可能会发现内部函数被您编写的函数隐藏。要解决此问题,请在函数名称前使用反斜杠来引用全局函数。

<?php
namespace phptherightway;

function fopen()
{
$file = \fopen();    // Our function name is the same as an internal function.
                         // Execute the function from the global space by adding '\'.
}

function array()
{
$iterator = new \ArrayIterator();    // ArrayIterator is an internal class. Using its name without a backslash
                                         // will attempt to resolve it within your namespace.
}

字符串

级联

<?php
$a  = 'Multi-line example';    // concatenating assignment operator (.=)
$a .= "\n";
$a .= 'of what not to do';

// vs

$a = 'Multi-line example'      // concatenation operator (.)
    . "\n"                     // indenting new lines
    . 'of what to do';

字符串类型

字符串是一系列字符,听起来应该很简单。也就是说,有一些不同类型的字符串,它们提供略有不同的语法,行为略有不同。

单引号

单引号用于表示“文字字符串”。文字字符串不会尝试解析特殊字符或变量。

如果使用单引号,您可以将变量名称输入到字符串中,如下所示:'some $thing',您将看到确切的输出some $thing如果使用双引号,那将尝试评估$thing变量名称并在未找到变量时显示错误。

<?php
echo 'This is my string, look at how pretty it is.';    // no need to parse a simple string

/**
* Output:
*
* This is my string, look at how pretty it is.
*/

双引号

双引号是瑞士军刀串。它们不仅会解析上面提到的变量,还会解析各种特殊字符,例如\n换行符,\t制表符等。

<?php
echo 'phptherightway is ' . $adjective . '.'     // a single quotes example that uses multiple concatenating for
    . "\n"                                       // variables and escaped string
    . 'I love learning' . $code . '!';

// vs

echo "phptherightway is $adjective.\n I love learning $code!"  // Instead of multiple concatenating, double quotes
                                                               // enables us to use a parsable string

双引号可以包含变量; 这被称为“插值”。

<?php
$juice = 'plum';
echo "I like $juice juice";    // Output: I like plum juice

使用插值时,通常情况是变量将触及另一个字符。这将导致一些混淆,即变量的名称是什么,以及什么是文字字符。

要解决此问题,请将变量包装在一对花括号中。

<?php
$juice = 'plum';
echo "I drank some juice made of $juices";    // $juice cannot be parsed

// vs

$juice = 'plum';
echo "I drank some juice made of {$juice}s";    // $juice will be parsed

/**
* Complex variables will also be parsed within curly brackets
*/

$juice = array('apple', 'orange', 'plum');
echo "I drank some juice made of {$juice[1]}s";   // $juice[1] will be parsed

Nowdoc语法

Nowdoc语法在5.3中引入,内部行为与单引号相同,只是它适合使用多行字符串而不需要连接。

<?php
$str = <<<'EOD'             // initialized by <<<
Example of string
spanning multiple lines
using nowdoc syntax.
$a does not parse.
EOD;                        // closing 'EOD' must be on it's own line, and to the left most point

/**
* Output:
*
* Example of string
* spanning multiple lines
* using nowdoc syntax.
* $a does not parse.
*/

Heredoc语法

Heredoc语法在内部的行为与双引号相同,只是它适合使用多行字符串而无需连接。

<?php
$a = 'Variables';

$str = <<<EOD               // initialized by <<<
Example of string
spanning multiple lines
using heredoc syntax.
$a are parsed.
EOD;                        // closing 'EOD' must be on it's own line, and to the left most point

/**
* Output:
*
* Example of string
* spanning multiple lines
* using heredoc syntax.
* Variables are parsed.
*/

应该注意的是,多行字符串也可以通过在语句中跨多行继续它们来形成。例如

$str = "
Example of string
spanning multiple lines
using statement syntax.
$a are parsed.
";

/**
* Output:
*
* Example of string
* spanning multiple lines
* using statement syntax.
* Variables are parsed.
*/

哪个更快?

有一个神话浮出水面,单引号字符串比双引号字符串快一些。这根本不是真的。

如果您要定义单个字符串而不是尝试连接值或任何复杂的值,那么单引号或双引号字符串将完全相同。两者都不会更快。

如果要连接任何类型的多个字符串,或将值插入双引号字符串,则结果可能会有所不同。如果使用少量值,则连接速度会快一些。有很多值,插值速度要快得多。

无论您使用字符串做什么,这些类型都不会对您的应用程序产生任何明显影响。尝试重写代码以使用其中一个代码总是徒劳无功,所以除非你真正理解差异的含义和影响,否则请避免这种微观优化。

三元运营商

三元运算符是压缩代码的好方法,但通常使用过多。虽然三元运算符可以堆叠/嵌套,但建议每行使用一个以提高可读性。

<?php
$a = 5;
echo ($a == 5) ? 'yay' : 'nay';

相比之下,这是一个牺牲所有形式的可读性以减少行数的例子。

<?php
echo ($a) ? ($a == 5) ? 'yay' : 'nay' : ($b == 10) ? 'excessive' : ':(';    // excess nesting, sacrificing readability

要使用三元运算符“返回”值,请使用正确的语法。

<?php
$a = 5;
echo ($a == 5) ? return true : return false;    // this example will output an error

// vs

$a = 5;
return ($a == 5) ? 'yay' : 'nope';    // this example will return 'yay'

应该注意,您不需要使用三元运算符来返回布尔值。这方面的一个例子是。

<?php
$a = 3;
return ($a == 3) ? true : false; // Will return true if $a == 3 or false

// vs

$a = 3;
return $a == 3; // Will return true if $a == 3 or false

对于所有操作(===,!==,!=,==等)也可以这样说。

使用带三元运算符的括号来表示形式和功能

当使用三元运算符时,括号可以发挥其作用以提高代码可读性,并在语句块中包含联合。不需要使用包围的示例是:

<?php
$a = 3;
return ($a == 3) ? "yay" : "nope"; // return yay if $a == 3 or nope

// vs

$a = 3;
return $a == 3 ? "yay" : "nope"; // return yay if $a == 3 or nope

包围还为我们提供了在语句块中创建联合的能力,其中块将作为整体进行检查。如下面这个例子,如果两个($ a == 3和$ b == 4)都为真且$ c == 5也为真,则返回true。

<?php
return ($a == 3 && $b == 4) && $c == 5;

另一个例子是下面的片段,如果($ a!= 3 AND $ b!= 4)OR $ c == 5,它将返回true。

<?php
return ($a != 3 && $b != 4) || $c == 5;

从PHP 5.3开始,可以省略三元运算符的中间部分。如果expr1的计算结果为TRUE,则表达式“expr1?:expr3”返回expr1,否则返回expr3。

变量声明

有时,编码器通过声明具有不同名称的预定义变量来尝试使其代码“更清晰”。实际上,这实际上是将所述脚本的内存消耗加倍。对于下面的示例,让我们说一个示例文本字符串包含1MB的数据,通过复制您已将脚本执行增加到2MB的变量。

<?php
$about = 'A very long string of text';    // uses 2MB memory
echo $about;

// vs

echo 'A very long string of text';        // uses 1MB memory

原文