PHPer 高手之路
  • Introduction
  • First Chapter
  • 基础
    • 数据类型和常量
    • 字符串
      • 字符编码
      • 字符编码相关编程
    • 引用变量
    • 运算符与错误控制符@
    • 流程控制与条件判断
      • foreach遍历中的引用
    • 函数
    • 文件及目录处理
  • PHP 数组
    • 基础
    • PHP数组操作
    • 输入流 php://input
    • PHP数组的内部实现
    • PHP数组和数据结构
    • 示例技巧
  • PHP文件编程
    • 文件系统
    • 基础
    • 实例技巧
    • PHP中XML处理
    • PHP中JSON处理
    • PHP中CSV处理
    • 大文件上传
  • 正则表达式
    • 基础
    • 正则的引擎
    • 表达式的优化
    • PHP中正则的使用
  • PHP 编码技巧
    • PHP编码习惯
    • PHP语法糖
    • PHP代码优化
    • PHP重点新特性
    • PHP编码规范
  • PHP选项和运行原理
    • PHP SAPI
    • PHP运行模式及安装方式
    • 附录:进程和线程的Q解
    • Apache下的MPM模式
    • Apache 与 Nginx
    • PHP的运行机制及原理
    • PHP垃圾回收机制
    • PHP配置选项
  • PHP安全
    • 跨站脚本攻击(XSS )
    • 跨站请求伪造(CRSF)
  • PHP 高级特性
    • 异常处理(Exceptions)
    • 代码复用(Trait)
    • 预定义接口(Predefined Interfaces)
    • 魔术方法(Magic Methods)
    • 回调函数、匿名函数&闭包
    • 命名空间(Namespaces)
    • 自动加载(Autoload)
    • 反射(Reflection)
    • 魔术常量(Magic constants)
    • 综合实例
  • 附录:关键词
  • 附录:资料
  • 代码的版本控制
    • SVN
    • Git
      • 疑难杂症
  • Linux
    • Linux原理与基础
    • 常见命令
    • Shell 编程
    • awk 与 sed
    • 命令笔记
  • HTTP 协议
    • 请求方法与返回状态码
    • Cookie、Session 的原理
  • MySQL
    • MySQL表存储引擎
  • 标准PHP库(SPL)
    • 数据结构
      • SplPriorityQueue - 优先队列
      • SplQueue - 队列
      • SplStack - 栈的功能
    • 接口
      • Countable - count统计接口
  • 附录:ElasticSearch
  • PHP数据结构
  • 附录:Rabbitmq
  • 附录:guzzle
  • JavaScript
    • 附录:资料
  • 疑难杂症
Powered by GitBook
On this page
  • 1.逗号优于点号
  • 2.$i=$i+1比较低效
  • 3.用isset代替strlen
  • 4.用strtr代替str_replace
  • 5.PHP用yield实现协程
  • 6.用 “[]” 定义数组
  • 7.用 ** 进行幂运算
  • 8.用 ... 定义变长参数函数
  • 8.函数赋值默认参数:+ 运算符
  • 9.函数赋值默认参数:+ 运算符
  • 10.?? 运算符
  • 11.<=> 比较运算符("太空船"运算符)
  • 12.一句话木马

Was this helpful?

  1. PHP 编码技巧

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;
}

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
PreviousPHP编码习惯NextPHP代码优化

Last updated 5 years ago

Was this helpful?

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