# 前言
本文是一篇讲座听后+后续研究的总结。
话说当年追时髦,php7一出就给电脑立马装上了,php5和php7共存,也是立马写了个超级耗时间的循环脚本测了一番,确实php7给力很多,然后也是注意了一些新增的特性与一些丢弃掉的用法。
由于php升级乃头等大事,公司近期才打算升级,所以之前一直只能私下欣赏php7带来的快感,负责升级的小伙伴搞了个分享,还挺全的,此处mark一下,当作笔记。
主要研究问题:
1.PHP7带来的好处
2.PHP7带来的新东西
3.PHP7带来的废弃
4.PHP7带来的变更
5.如何充分发挥PHP7的性能
6。如何更好的写代码来迎接PHP7?
7.如何升级当前项目代码来兼容PHP7?
# PHP7带来的好处
是的,性能上的大幅度提升,可以省机器,可以省钱。
![这里写图片描述](http://upload-images.jianshu.io/upload_images/6954572-0cf6eb0904a32f3d?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# PHP7带来的新东西
## 1.类型的声明。
可以使用字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool),来声明函数的参数类型与函数返回值。
```
declare(strict_types=1);
function add(int $a, int $b): int {
return $a+$b;
}
echo add(1, 2);
echo add(1.5, 2.6);
```
php5是无法执行上面代码的,php7执行的时候会先输出一个3和一个报错( Argument 1 passed to add() must be of the type integer, float given);
**标量类型声明 有两种模式: 强制 (默认) 和 严格模式。**
**declare(strict_types=1),必须放在文件的第一行执行代码,当前文件有效!**
## 2.set_exception_handler() 不再保证收到的一定是 Exception 对象
在 PHP 7 中,很多致命错误以及可恢复的**致命错误,都被转换为异常来处理了**。 这些异常继承自 Error 类,此类实现了 Throwable 接口 (所有异常都实现了这个基础接口)。
PHP7进一步方便开发者处理, 让开发者对程序的掌控能力更强. 因为在默认情况下, Error会直接导致程序中断, 而PHP7则提供捕获并且处理的能力, 让程序继续执行下去, 为程序员提供更灵活的选择。
## 3.新增操作符“<=>”
语法:**$c = $a <=> $b**
如果$a > $b, $c 的值为1
如果$a == $b, $c 的值为0
如果$a < $b, $c 的值为-1
## 4.新增操作符“??”
**如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。**
```
//原写法
$username = isset($_GET['user]) ? $_GET['user] : 'nobody';
//现在
$username = $_GET['user'] ?? 'nobody';
```
## 5.define() 定义常量数组
```
define('ARR',['a','b']);
echo ARR[1];// a
```
## 6.AST: Abstract Syntax Tree, 抽象语法树
AST在PHP编译过程作为一个中间件的角色, 替换原来直接从解释器吐出opcode的方式, 让解释器(parser)和编译器(compliler)解耦, 可以减少一些Hack代码, 同时, 让实现更容易理解和可维护.
PHP5 : PHP代码 -> Parser语法解析 -> OPCODE -> 执行
PHP7 : PHP代码 -> Parser语法解析 -> AST -> OPCODE -> 执行
参考: [https://wiki.php.net/rfc/abstract_syntax_tree](https://wiki.php.net/rfc/abstract_syntax_tree)
## 7.匿名函数
```
$anonymous_func = function(){return 'function';};
echo $anonymous_func(); // 输出function
```
## 8.Unicode字符格式支持(echo “\u{9999}”)
## 9.Unserialize 提供过滤特性
防止非法数据进行代码注入,提供了更安全的反序列化数据。
## 10.命名空间引用优化
```
// PHP7以前语法的写法
use FooLibrary\Bar\Baz\ClassA;
use FooLibrary\Bar\Baz\ClassB;
// PHP7新语法写法
use FooLibrary\Bar\Baz\{ ClassA, ClassB};
```
# PHP7带来的废弃
## 1.废弃扩展
Ereg 正则表达式
mssql
mysql
sybase_ct
## 2.废弃的特性
不能使用同名的构造函数
实例方法不能用静态方法的方式调用
## 3.废弃的函数
> 方法调用
> call_user_method()
> call_user_method_array()
应该采用call_user_func() 和 call_user_func_array()
> 加密相关函数
mcrypt_generic_end()
mcrypt_ecb()
mcrypt_cbc()
mcrypt_cfb()
mcrypt_ofb()
注意: **PHP7.1 以后mcrypt_*序列函数都将被移除。推荐使用:openssl 序列函数**
> 杂项
set_magic_quotes_runtime
set_socket_blocking
Split
imagepsbbox()
imagepsencodefont()
imagepsextendfont()
imagepsfreefont()
imagepsloadfont()
imagepsslantfont()
imagepstext()
## 4.废弃的用法
$HTTP_RAW_POST_DATA 变量被移除, 使用php://input来代
ini文件里面不再支持#开头的注释, 使用”;”
移除了ASP格式的支持和脚本语法的支持: <% 和 < script language=php >
# PHP7带来的变更
## 1.字符串处理机制修改
**含有十六进制字符的字符串不再视为数字, 也不再区别对待.**
```
var_dump("0x123" == "291"); // false
var_dump(is_numeric("0x123")); // false
var_dump("0xe" + "0x1"); // 0
var_dump(substr("f00", "0x1")) // foo
```
## 2.整型处理机制修改
**Int64支持, 统一不同平台下的整型长度, 字符串和文件上传都支持大于2GB. 64位PHP7字符串长度可以超过2^31次方字节.**
```
// 无效的八进制数字(包含大于7的数字)会报编译错误
$i = 0681; // 老版本php会把无效数字忽略。
// 位移负的位置会产生异常
var_dump(1 >> -1);
// 左位移超出位数则返回0
var_dump(1 << 64);// 0
// 右位移超出会返回0或者-1
var_dump(100 >> 32);// 0
var_dump(-100 >> 32);// -1
```
## 3.参数处理机制修改
> 不支持重复参数命名
function func(<nobr>a,</nobr>b, <nobr>c,</nobr>c) {} ;hui报错
> func_get_arg()和func_get_args()这两个方法返回参数当前的值, 而不是传入时的值, 当前的值有可能会被修改
所以需要注意,在函数第一行最好就给记录下来,否则后续有修改的话,再读取就不是传进来的初始值了。
```
function foo($x) {
$x++;
echo func_get_arg(0);
}
foo(1); //返回2
```
## 4.foreach修改
> foreach()循环对数组内部指针不再起作用
```
$arr = [1,2,3];
foreach ($arr as &$val) {
echo current($arr);// php7 全返回0
}
```
> 按照值进行循环的时候, foreach是对该数组的拷贝操作
```
$arr = [1,2,3];
foreach ($arr as $val) {
unset($arr[1]);
}
var_dump($arr);
```
最新的php7依旧会打印出[1,2,3]。(ps:7.0.0不行)
老的会打印出[1,3]
> 按照引用进行循环的时候, 对数组的修改会影响循环
```
$arr = [1];
foreach ($arr as $val) {
var_dump($val);
$arr[1]=2;
}
```
最新的php7依旧会追加新增元素的循环。(ps:7.0.0不行)
## 5\. list修改
> 不再按照相反的顺序赋值
```
//$arr将会是[1,2,3]而不是之前的[3,2,1]
list($arr[], $arr[], $arr[]) = [1,2,3];
```
> 不再支持字符串拆分功能
```
// $x = null 并且 $y = null
$str = 'xy';
list($x, $y) = $str;
```
> 空的list()赋值不再允许
```
list() = [123];
```
> list()现在也适用于数组对象
```
list($a, $b) = (object)new ArrayObject([0, 1]);
```
## 6.变量处理机制修改
> 对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析,而不是之前的混杂着几个特殊案例的情况。 下面这张表说明了这个解析顺序的变化。
![这里写图片描述](http://upload-images.jianshu.io/upload_images/6954572-77d965f19cefc735?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
> 引用赋值时自动创建的数组元素或者对象属性顺序和以前不同了
```
$arr = [];
$arr['a'] = &$arr['b'];
$arr['b'] = 1;
// php7: ['a' => 1, 'b' => 1]
// php5: ['b' => 1, 'a' => 1]
```
## 7.杂项
1.debug_zval_dump() 现在打印 “int” 替代 “long”, 打印 “float” 替代 “double”
2.dirname() 增加了可选的第二个参数, depth, 获取当前目录向上 depth 级父目录的名称。
3.getrusage() 现在支持 Windows.mktime() and gmmktime() 函数不再接受 is_dst 参数。
4.preg_replace() 函数不再支持 “\e” (PREG_REPLACE_EVAL). 应当使用 preg_replace_callback() 替代。
5.setlocale() 函数不再接受 category 传入字符串。 应当使用 LC_* 常量。
6.exec(), system() and passthru() 函数对 NULL 增加了保护.
7.shmop_open() 现在返回一个资源而非一个int, 这个资源可以传给shmop_size(), shmop_write(), shmop_read(), shmop_close() 和 shmop_delete().
8.为了避免内存泄露,xml_set_object() 现在在执行结束时需要手动清除 $parse。
9.curl_setopt 设置项CURLOPT_SAFE_UPLOAD变更
TRUE 禁用 @ 前缀在 CURLOPT_POSTFIELDS 中发送文件。 意味着 @ 可以在字段中安全得使用了。 可使用 CURLFile作为上传的代替。
PHP 5.5.0 中添加,默认值 FALSE。 PHP 5.6.0 改默认值为 TRUE。. PHP 7 删除了此选项, 必须使用 CURLFile interface 来上传文件。
# 如何充分发挥PHP7的性能
## 1.开启Opcache
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
## 2.使用GCC 4.8以上进行编译
只有GCC 4.8以上PHP才会开启Global Register for opline and execute_data支持, 这个会带来5%左右的性能提升(Wordpres的QPS角度衡量)
## 3.开启HugePage (根据系统内存决定)
![这里写图片描述](http://upload-images.jianshu.io/upload_images/6954572-2d7ee2c04e7528c5?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 4.PGO (Profile Guided Optimization)
第一次编译成功后,用项目代码去训练PHP,会产生一些profile信息,最后根据这些信息第二次gcc编译PHP就可以得到量身定做的PHP7
需要选择在你要优化的场景中: 访问量最大的, 耗时最多的, 资源消耗最重的一个页面.
参考: [http://www.laruence.com/2015/06/19/3063.html](http://www.laruence.com/2015/06/19/3063.html)
参考: [http://www.laruence.com/2015/12/04/3086.html](http://www.laruence.com/2015/12/04/3086.html)
# 如何更好的写代码来迎接PHP7?
1. 不使用php7废弃的方法,扩展
2. 使用2个版本都兼容的语法特性【 list ,foreach, func_get_arg 等】
# 如何升级当前项目代码来兼容PHP7?
**逐步剔除php7不支持的代码**
检测工具:[https://github.com/sstalle/php7cc](https://github.com/sstalle/php7cc)
![这里写图片描述](http://upload-images.jianshu.io/upload_images/6954572-d47ceac82d4878e0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 技能知识点
- 对死锁问题的理解
- 文件系统原理:如何用1分钟遍历一个100TB的文件?
- 数据库原理:为什么PrepareStatement性能更好更安全?
- Java Web程序的运行时环境到底是怎样的?
- 你真的知道自己要解决的问题是什么吗?
- 如何解决问题
- 经验分享
- GIT的HTTP方式免密pull、push
- 使用xhprof对php7程序进行性能分析
- 微信扫码登录和使用公众号方式进行扫码登录
- 关于curl跳转抓取
- Linux 下配置 Git 操作免登录 ssh 公钥
- Linux Memcached 安装
- php7安装3.4版本的phalcon扩展
- centos7下php7.0.x安装phalcon框架
- 将字符串按照指定长度分割
- 搜索html源码中标签包的纯文本
- 更换composer镜像源为阿里云
- mac 隐藏文件显示/隐藏
- 谷歌(google)世界各国网址大全
- 实战文档
- PHP7安装intl扩展和linux安装icu
- linux编译安装时常见错误解决办法
- linux删除文件后不释放磁盘空间解决方法
- PHP开启异步多线程执行脚本
- file_exists(): open_basedir restriction in effect. File完美解决方案
- PHP 7.1 安装 ssh2 扩展,用于PHP进行ssh连接
- php命令行加载的php.ini
- linux文件实时同步
- linux下php的psr.so扩展源码安装
- php将字符串中的\n变成真正的换行符?
- PHP7 下安装 memcache 和 memcached 扩展
- PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串
- PHP设置脚本最大执行时间的三种方法
- 升级Php 7.4带来的两个大坑
- 不同域名的iframe下,fckeditor在chrome下的SecurityError,解决办法~~
- Linux find+rm -rf 执行组合删除
- 从零搭建Prometheus监控报警系统
- Bug之group_concat默认长度限制
- PHP生成的XML显示无效的Char值27消息(PHP generated XML shows invalid Char value 27 message)
- XML 解析中,如何排除控制字符
- PHP各种时间获取
- nginx配置移动自适应跳转
- 已安装nginx动态添加模块
- auto_prepend_file与auto_append_file使用方法
- 利用nginx实现web页面插入统计代码
- Nginx中的rewrite指令(break,last,redirect,permanent)
- nginx 中 index try_files location 这三个配置项的作用
- linux安装git服务器
- PHP 中运用 elasticsearch
- PHP解析Mysql Binlog
- 好用的PHP学习网(持续更新中)
- 一篇写给准备升级PHP7的小伙伴的文章
- linux 安装php7 -系统centos7
- Linux 下多php 版本共存安装
- PHP编译安装时常见错误解决办法,php编译常见错误
- nginx upstream模块--负载均衡
- 如何解决Tomcat服务器打开不了HOST Manager的问题
- PHP的内存泄露问题与垃圾回收
- Redis数据结构 - string字符串
- PHP开发api接口安全验证
- 服务接口API限流 Rate Limit
- php内核分析---内存管理(一)
- PHP内存泄漏问题解析
- 【代码片-1】 MongoDB与PHP -- 高级查询
- 【代码片-1】 php7 mongoDB 简单封装
- php与mysql系统中出现大量数据库sleep的空连接问题分析
- 解决crond引发大量sendmail、postdrop进程问题
- PHP操作MongoDB GridFS 存储文件,如图片文件
- 浅谈php安全
- linux上keepalived+nginx实现高可用web负载均衡
- 整理php防注入和XSS攻击通用过滤