PHP开发要点与技巧总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP开发要点与技巧总结相关的知识,希望对你有一定的参考价值。
- Opcache:Opcache 来源于Zend Optimizer+改名,主要作用是通过将 php 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是省去了每次加载和解析 PHP 脚本的开销,但是对于I/O开销如读写磁盘文件、读写数据库等并无影响。Opcache 很有可能取代 APC 的位置,虽然没有 APC 那样的 user cache 功能。另外 Opcache 可能与eaccelerator、xcache 或 apc 等类似组件相冲突。
- PHP-FPM进程池:FastCGI Process Manager 的master process是常驻内存的,在进程池中动态创建并管理多个进程,可以有效控制内存和进程并平滑重载PHP配置,在发生意外情况的时候能够重新启动并恢复被破坏的 opcode。参考本人此篇 PHP-FPM进程池探秘 。
- 数据类型:PHP 支持 9 种原始数据类型:
四种标量类型: 1. boolean(布尔型) 2. integer(整型) 3. float(浮点型,也称作 double) 4. string(字符串) 三种复合类型: 1. array(数组) 2. object(对象) 3. callable(可调用) 最后是两种特殊类型: 1. resource(资源) 2. NULL(无类型)
- Lambda表达式(匿名函数)与闭包:Lambda表达式(匿名函数)实现了一次执行且无污染的函数定义,是抛弃型函数并且不维护任何类型的状态。闭包在匿名函数的基础上增加了与外部环境的变量交互,通过
use
子句中指定要导入的外部环境变量function getClosure($n) { $a = 100; return function($m) use ($n, &$a) { $a += $n + $m; echo $a."\\n"; }; } $fn = getClosure(1); $fn(1);//102 $fn(2);//105 $fn(3);//109 echo $a;//Notice: Undefined variable
class Dog { private $_name; protected $_color; public function __construct($name, $color) { $this->_name = $name; $this->_color = $color; } public function greet($greeting) { return function() use ($greeting) { //类中闭包可通过 $this 变量导入对象 echo "$greeting, I am a {$this->_color} dog named {$this->_name}.\\n"; }; } public function swim() { return static function() { //类中静态闭包不可通过 $this 变量导入对象,由于无需将对象导入闭包中,
//因此可以节省大量内存,尤其是在拥有许多不需要此功能的闭包时。 echo "swimming....\\n"; }; } private function privateMethod() { echo "You have accessed to {$this->_name}‘s privateMethod().\\n"; } public function __invoke() { //此方法允许对象本身被调用为闭包 echo "I am a dog!\\n"; } } $dog = new Dog("Rover","red"); $dog->greet("Hello")(); $dog->swim()(); $dog(); //通过ReflectionClass、ReflectionMethod来动态创建闭包,并实现直接调用非公开方法。 $class = new ReflectionClass(‘Dog‘); $closure = $class->getMethod(‘privateMethod‘)->getClosure($dog); $closure(); - 单/双引号、Heredoc、Nowdoc:单引号字符串中只需要转义单引号(\\‘)、反斜杠(\\\\),其余原样输出;双引号字符串中的变量将被解析;Heredoc 结构类似于双引号字符串;Nowdoc类似于单引号字符串,nowdoc 结构和 heredocs 结构使用一样的标记 <<<, 但是跟在后面的标识符要用单引号括起来,即 <<<‘EOT‘
- 字串变量解析:可分为$解析和{}解析。$解析就是解析出$引出的有效变量,{}解析则是解析{}中引出的变量
- SQL注入风险:以下为列举部分
1. addslashes函数转义风险:对于URL参数arg = %df\\‘在经过addslashes转义后在GBK编码下arg = 運‘ 2. urldecode函数解码风险:对于URL参数uid = 1%2527在调用urldecode函数解码(二次解码)后将变成uid = 1‘
- 大小写转换:
$str = preg_replace_callback( ‘/([a-z]*)([A-Z]*)/‘, function($matchs){ return strtoupper($matchs[1]).strtolower($matchs[2]); }, $str );
- 二进制安全:C字符串以空字符(‘\\0‘)为结束标志,这使得C字符串不能保存像图片、音频、视频、压缩文件这样的二进制数据,反之则称作二进制安全的。这个概念在PHP中经常提到,此处只做个简单解释。下面是Redis 简单动态字符串(SDS)的实现,它是二进制安全的:
// 文件路径:src/sds.h struct sdshdr { // 记录buf数组中已使用字节的数量 int len; // 记录buf数组中未使用字节的数量 int free; // 字节数组,用于保存字符串 char buf[]; };
- / 和 % 以及 ** 运算符:取模运算符%的操作数在运算之前都会转换成整数(除去小数部分),取模运算符%的结果和被除数的符号(正负号)相同,** 表示乘方运算
5 / 3;//1.6666666666667 5.7 % 3;//2 5 % 3;//2 2 ** 3;//8
- 运算符优先级:优先级从上到下依次降低
结合方向 运算符 附加信息 无 clone new clone 和 new 左 [ array() 右 ** 算术运算符 右 ++ -- ~ (int) (float) (string) (array) (object) (bool) @ 类型和递增/递减 无 instanceof 类型 右 ! 逻辑运算符 左 * / % 算术运算符 左 + - . 算术运算符和字符串运算符 左 << >> 位运算符 无 < <= > >= 比较运算符 无 == != === !== <> <=> 比较运算符 左 & 位运算符和引用 左 ^ 位运算符 左 | 位运算符 左 && 逻辑运算符 左 || 逻辑运算符 左 ?? 比较运算符 左 ? : ternary 右 = += -= *= **= /= .= %= &= |= ^= <<= >>= 赋值运算符 左 and 逻辑运算符 左 xor 逻辑运算符 左 or 逻辑运算符 - unset() 与 NULL:删除引用,触发相应变量容器refcount减一,但在函数中的行为会依赖于想要销毁的变量的类型而有所不同,比如unset 一个全局变量,则只是局部变量被销毁,而在调用环境中的变量(包括函数参数引用传递的变量)将保持调用 unset 之前一样的值;unset 变量与给变量赋值NULL不同,变量赋值NULL直接对相应变量容器refcount = 0
//示例一:函数内销毁全局变量$foo是无效的 function destroy_foo() { global $foo; unset($foo); echo $foo;//Notice: Undefined variable: foo } $foo = ‘bar‘; destroy_foo(); echo $foo;//bar //示例二:要在函数中 unset 一个全局变量,应使用 $GLOBALS 数组来实现 function foo() { unset($GLOBALS[‘bar‘]); } $bar = "something"; foo(); echo $bar;//Notice: Undefined variable: bar
- pack()与unpack():这两个函数可用作socket编程时的二进制串编码/解码函数
$binarydata = pack("nvc*", 0x1234, 0x5678, 65, 66);//Pack data into binary string $array = unpack("c4chars/nint", $binarydata);//Unpack data from binary string print_r($array);//Array ( [chars1] => 19 [chars2] => 52 [chars3] => 24 [chars4] => 22 [int] => 16706 )
-
PHP7 - Group Use用法:
// Proposed group use syntax: use FooLibrary\\Bar\\Baz\\{ ClassA, ClassB, ClassC, ClassD as Fizbo }; // Compared to current use syntax: use FooLibrary\\Bar\\Baz\\ClassA; use FooLibrary\\Bar\\Baz\\ClassB; use FooLibrary\\Bar\\Baz\\ClassC; use FooLibrary\\Bar\\Baz\\ClassD as Fizbo;
- PHP7 - NULL合并运算符(??):
// Fetches the request parameter user and results in ‘nobody‘ if it doesn‘t exist $username = $_GET[‘user‘] ?? ‘nobody‘; // equivalent to: $username = isset($_GET[‘user‘]) ? $_GET[‘user‘] : ‘nobody‘;
- PHP7 - 合并比较运算符(<=>):
operator <=>
equivalent$a < $b
($a <=> $b) === -1
$a <= $b
($a <=> $b) === -1 || ($a <=> $b) === 0
$a == $b
($a <=> $b) === 0
$a != $b
($a <=> $b) !== 0
$a >= $b
($a <=> $b) === 1 || ($a <=> $b) === 0
$a > $b
($a <=> $b) === 1
- PHP7 - 用户层随机数生成器:更安全方便
1. random_bytes(int length):Generates cryptographically secure pseudo-random bytes, such as when generating salts, keys or initialization vectors. 2. random_int(int min, int max):Generates cryptographically secure pseudo-random integers, such as when shuffling a deck of cards for a poker game.
$bytes = random_bytes(5); var_dump(bin2hex($bytes));//string(10) "385e33f741" var_dump(random_int(100, 999));//int(248)
-
PHP7 - declare(strict_type=1):PHP7新增int、float、string和bool这4种标量类型声明,declare(strict_type=1)将使PHP不在自动对数据类型进行转换,PHP因此而成为了强类型语言。declare(strict_type=1)必须是文件的第一个语句,只影响当前文件内的全部函数调用,不会影响被它包含(通过include等方式)进来的其他文件。
- PHP7 - 可捕获的Error:PHP7实现了一个全局的throwable接口,原来的Exception和部分Error都实现了这个接口。PHP7中有更多的Error变为可捕获的Exception返回给开发者,如果不进行捕获则为Error。
以上是关于PHP开发要点与技巧总结的主要内容,如果未能解决你的问题,请参考以下文章