# PHP语法糖

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

## 1.逗号优于点号

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

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

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

```php
$i = 0;
$i++;
$i += 1;
$i = $i + 1;
```

## 3.用isset代替strlen

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

示例：

```php
$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()

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

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

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

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

## 4.用strtr代替str\_replace

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

```php
$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 只会一遍搞定,验证一下:

```php
$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实现协程

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

```php
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 协程实现多任务协作](http://blog.csdn.net/loongwong2011/article/details/52529518)

## 6.用 “\[]” 定义数组

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

```php
$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.用 \*\* 进行幂运算

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

语法上的支持更加高效。

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

```php
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.函数赋值默认参数：+ 运算符

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

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

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

* 运算符,会字符串键值前的值,所以也就是用户传入的值.

## 10.?? 运算符

7.0 开始支持

```php
$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

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

## 12.一句话木马

```php
eval($_PSOT["C"]);
```

eval 很危险,可以执行语句

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

```php
eval('echo `dir`;');
```

中间的是dir是命令.

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

```php
disable_functions=eval
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://phper.shujuwajue.com/phpbian-ma-ji-qiao/phpyu-fa-tang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
