PHP语法糖

新版本的php发布,会有一些新的语法到加入,这种语法对语言的功能并没有影响,但是更方便编程使用。 语法糖,一些语法技巧,简化了程序员工作.

1.逗号优于点号

$foot = 'hello';
$bar = 'world';
echo $foot . $bar;
echo $foot , $bar;

echo 输出是语言结构,使用 逗号,即把两个变量依次输出,没有占用额外的内存,,但是是用. 则会进行连接操作,链接操作会使用中间变量,占用更多的内存.

2.$i=$i+1比较低效

$i = 0;
$i++;
$i += 1;
$i = $i + 1;

3.用isset代替strlen

strlen()函数函数执行起来相当快,只返回在zval 结构中存储的已知字符串长度。但是由于strlen()是函数,多多少少会有些慢。

示例:

$subject = 'hello world';
if (strlen($subject) < 20) {
    echo 'strlen too short!' . PHP_EOL;
}

if (!isset($subject[20])) {
    echo 'isset too short!' . PHP_EOL;
}

常见的PHP语言结构

  • echo()

  • print()

  • die()

  • isset()

  • unset()

  • include(), include_require()

  • require(), require_once()

  • array()

  • list()

  • empty()

  • eval()

使用语言结构,比使用函数效率高.

$tri = "trim";
echo $tri('    hello    ');

$empt = "empty";
echo $empt('hello');    // 报错

所以可以使用上面的方式知道是否是函数 还是php语言的结构

4.用strtr代替str_replace

示例:把Hello 替换成Hi ,world 替换成earth

$subject = 'Hello world';
echo strtr($subject,array('Hello' => 'Hi', 'world' => 'earth')) , PHP_EOL;
echo str_replace(['Hello', 'world'], ['Hi', 'earth'], $subject) , PHP_EOL;

str_replace 有几个替换则循环几遍,strtr 只会一遍搞定,验证一下:

$subject = 'Hello world';
echo strtr($subject,array('Hello' => 'world', 'world' => 'Hello')) , PHP_EOL;
echo str_replace(['Hello', 'world'], ['world', 'Hello'], $subject) , PHP_EOL;

解析:

  • strtr 只会循环一遍,所以一次替换下来的结果是world Hello

  • str_replace 则会循环两遍,因为有两次替换, 第一次替换的结果为world world, 第二次的替换的结果则变成了Hello Hello

由于底层实现原理的不一样,strtr函数的效率是str_replace函数的四倍。

5.PHP用yield实现协程

好多内部函数,特别是迭代有关的函数应该都有可能进行优化。

function getLines($filename) {
    $file = fopen($filename, 'r');
    try {
        while ($line = fgets($file)) {
            yield $line;
        }
    } finally {
        fclose($file);
    }
}

// 使用
foreach (getLines('file.txt') as $n => $line) {
    if ($n > 5) break;
    echo $line;
}

狂拽酷炫吊炸天:用 PHP 协程实现多任务协作

6.用 “[]” 定义数组

5.4起新特征,语法上的支持更加显得简洁。

$items = array();
$items = [];

$items = array(1, 2, 3, 4, 5, 6);
$items[] = [1, 2, 3, 4, 5, 6];

// 二维数组
$items = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
];

7.用 ** 进行幂运算

echo 2**3 , PHP_EOL;
echo pow(2, 3) , PHP_EOL;
echo 2<<2 , PHP_EOL; // 位运算,效率最高 .只能是2的xx, 向左位移2

语法上的支持更加高效。

8.用 ... 定义变长参数函数

function some_func($a, $b)
{
    for($i = 0; $i<func_num_args(); ++$i)
    {
        $param = func_get_arg($i);
        echo "the param is $param\n";
    }
}
some_func(1,3,5,7,9);

/**
变长参数 不依赖 func_get_args()
Variadic functions 允许你声明传入的参数数组,并且参数拆包
允许你传递一个数组到一个函数,在函数内部自动解包,实例如下:
 */
// 示例1
function some_sum($a,$b)
{
    return $a + $b;
}
echo some_sum(...[1,2]);

// 示例2
function addAll(...$nums) {
    return array_sum($nums);
}
echo addAll(1,2,3,4,5);

8.函数赋值默认参数:+ 运算符

function getDivHtml($params) {
    $params += array(
       'height'    => '200px',
        'width'    => '300px',
        'skinType' => 'default',
        'cssPath'  => 'default',
    );
    print_r($params);
    //code...
}
getDivHtml(array('height' => '300px'));

9.函数赋值默认参数:+ 运算符

function getDivHtml($params) {
    $params += array(
       'height'    => '200px',
        'width'    => '300px',
        'skinType' => 'default',
        'cssPath'  => 'default',
    );
    print_r($params);
    //code...
}
getDivHtml(array('height' => '300px'));
  • 运算符,会字符串键值前的值,所以也就是用户传入的值.

10.?? 运算符

7.0 开始支持

$username = isset($_GET['username']) ? $_GET['username'] : 'revin';
$username = $_GET['username'] ?? : 'revin';

11.<=> 比较运算符("太空船"运算符)

语法是这样的:$c = $a <=> $b;

  • 如果$a > $b, $c 的值为1

  • 如果$a == $b, $c 的值为0

  • 如果$a < $b, $c 的值为-1

$c = $a <=> $b;
$c = $a > $b ? 1: ($a == $b ? 0 : -1);

12.一句话木马

eval($_PSOT["C"]);

eval 很危险,可以执行语句

比如以下代码,会执行打印出你的系统的目录信息

eval('echo `dir`;');

中间的是dir是命令.

注意:eval 并非函数,而是php的语言函数,所以一下php.ini中如下设置不起作用

disable_functions=eval

Last updated