最近,因为项目需要我开始学习PHP从PHP 7.2开始也关注了即将发布的PHP 7.3(目前还是RC版本预计12月正式发布)。

说实话,之前,我对PHP的印象是"世界上最好的语言"这个梗大家都懂也觉得PHP是一门简单的语言容易上手适合快速开发结果真正学了一段时间发现坑还不少差点从入门到放弃。

今天想记录一下我学习PHP 7.2/7.3的经历包括遇到的坑踩过的雷以及,一些心得和体会希望能帮同样在学PHP的朋友少走弯路。

一、为什么学PHP

先说说我为什么要学PHP其实我之前,主要做前端和Node.js后端对PHP接触不多,但是最近公司有一个老项目是用PHP写的需要维护和二次开发,所以我不得不学PHP。

而且PHP在Web开发领域确实还是很流行的特别是在中小企业和内容管理系统领域WordPressLaravelThinkPHP等等都是,PHP的生态市场份额还是很大的学一下PHP也能拓宽自己的技术栈多一个技能。

另外PHP 7之后,性能提升很大比PHP 5快了很多也加入了很多现代语言的特性,比如标量类型声明返回值类型声明匿名类等等已经不是以前那个被黑的PHP了,所以我也想体验一下现代PHP的开发体验。

二、环境搭建的坑

学PHP的第一步是搭建开发环境本以为很简单结果就踩了不少坑。

坑1:版本选择

PHP的版本很多5.67.07.17.2还有即将发布的7.3不同版本之间,有一些不兼容的地方,比如PHP 7.2废弃了一些函数和特性PHP 7.3又有一些新的变化选哪个版本一开始让我很纠结。

后来我选了PHP 7.2因为是当前最新的稳定版兼容性也比较好大部分框架和项目都支持,同时也关注了PHP 7.3的新特性为后续升级做准备。

坑2:Windows环境搭建

我用的是Windows开发环境PHP在Windows上的环境搭建比Linux麻烦一些需要自己配置php.ini扩展等等一开始我下载了PHP的Windows二进制包解压后配置环境变量,但是运行的时候,报各种扩展找不到的错误,比如opensslpdo_mysqlmbstring等等扩展都需要手动开启还要注意扩展的版本和PHP版本匹配很折腾。

后来我发现用集成环境,比如phpEnvXAMPPWampServer等等会简单很多这些集成环境已经帮你配置好了PHPApache/NginxMySQL等等开箱即用省了很多麻烦我最后用了phpEnv感觉还不错。

坑3:扩展安装

PHP的扩展安装也是个坑特别是在Windows上很多扩展没有预编译的Windows版本需要自己编译,或者找第三方编译的版本很麻烦,比如我需要用redis扩展找了很久才找到和PHP 7.2匹配的Windows版本,而且还要注意线程安全(TS)和非线程安全(NTS)的区别VC版本的区别x86和x64的区别很容易搞错。

相比之下Linux上安装PHP扩展就简单很多用pecl或者源码编译都比较方便,所以,如果条件允许还是建议用Linux或者Mac开发PHP体验会好很多。

三、语法和特性的坑

环境搭好后开始学PHP的语法和特性本以为PHP语法简单结果也踩了不少坑。

坑1:弱类型的坑

PHP是弱类型语言变量不需要声明类型会自动转换类型这,虽然灵活,但是也容易出问题,比如比较运算符的坑=====的区别==会自动转换类型比较===会严格比较类型和值很多新手容易搞混导致bug。

比如0 == "abc"在PHP里是true因为字符串转成数字是0这很反直觉也很容易出bug还有null == false也是true"" == 0也是true这些弱类型的转换规则很复杂容易记错,所以建议尽量用===严格比较避免弱类型的坑。

PHP 7之后,加入了标量类型声明和返回值类型声明可以开启严格类型模式(declare(strict_types=1))这样就能避免很多弱类型的坑推荐在新项目中使用。

坑2:数组的坑

PHP的数组是一个很强大也很复杂的数据结构既是普通数组(列表)又是关联数组(字典)还是对象的替代功能很多,但是也有一些坑。

比如数组的键名会自动转换数字字符串键名会被转成整数,比如$arr["1"]$arr[1]是一样的这有时候会导致意想不到的结果,还有数组的排序函数(sortrsortasortksort等等)很多参数和行为容易搞混,而且这些函数是直接修改原数组的不是返回新数组和很多其他语言不一样容易搞错。

还有数组的遍历foreach引用的坑,比如foreach ($arr as &$val)遍历完后$val还是引用最后一个元素的引用,如果后面再用$val会修改数组的最后一个元素导致bug这个坑很多人都踩过,所以foreach用引用后记得unset($val)解除引用。

坑3:字符串处理的坑

PHP的字符串处理函数很多,但是也有一些坑,比如多字节字符串的处理PHP默认的字符串函数(strlensubstrstrpos等等)是按字节处理的对于中文等多字节字符会出问题需要用mbstring扩展的多字节函数(mbstrlenmbsubstrmb_strpos等等)很多新手不知道这个导致中文处理出问题。

还有字符串的编码问题PHP的字符串本身不包含编码信息就是一串字节,所以编码转换需要自己处理用mbconvertencoding或者iconv函数很容易出现乱码问题特别是在处理不同编码的输入时需要特别注意。

坑4:错误处理的坑

PHP的错误处理也比较特别有错误(error)警告(warning)通知(notice)等等不同级别的错误默认情况下notice和warning不会终止脚本执行只是输出错误信息这,虽然让程序能继续跑,但是也容易隐藏bug很多问题被忽略了直到造成更大的问题。

比如访问一个不存在的数组键会报notice但是程序继续执行返回null这很容易导致后续逻辑出问题,而且notice信息可能被忽略了很难排查,所以建议在开发环境把错误级别调到最高(errorreporting(EALL))显示所有错误包括notice这样能尽早发现问题。

PHP 7之后,很多致命错误变成了异常(Error)可以用try-catch捕获这比以前好很多,但是还是有一些错误不是异常需要用seterrorhandler处理,所以错误处理还是需要注意。

四、PHP 7.2的新特性和变化

学PHP的过程中我也重点关注了PHP 7.2的新特性和变化这里总结一下。

1. 新的对象类型

PHP 7.2加入了新的对象类型(object)可以用于参数类型声明和,返回值类型声明表示任何对象类型这在一些通用的函数中很有用。

function foo(object $obj): object {
    return $obj;
}

2. 通过名称加载扩展

PHP 7.2之前,加载扩展需要写完整的文件名,比如extension=php_mbstring.dllPHP 7.2之后,可以只写扩展名称,比如extension=mbstring更简洁也跨平台,因为不同平台的扩展文件名不一样(.dll.so等等)只写名称就不用管平台差异了。

3. 允许重写抽象方法

PHP 7.2之前,抽象类继承另一个抽象类时不能重写父类的抽象方法PHP 7.2之后,允许了这在一些复杂的抽象层次中很有用。

4. 密码哈希算法扩展

PHP 7.2加入了对Argon2密码哈希算法的支持(需要编译时开启)比之前,的bcrypt更安全这是一个很好的安全增强。

5. 废弃的特性

PHP 7.2废弃了一些老旧的特性,比如:

  • __autoload()函数被废弃建议用splautoloadregister()
  • create_function()函数被废弃建议用匿名函数
  • each()函数被废弃建议用foreach
  • parse_str()不带第二个参数的用法被废弃
  • 未使用的use导入会报warning

这些废弃的特性在PHP 7.2会报deprecated警告在后续版本会被移除,所以升级到PHP 7.2时需要检查代码中有没有用这些废弃的特性及时替换。

五、PHP 7.3的新特性(展望)

PHP 7.3目前还是RC版本预计2018年12月正式发布我也关注了一下PHP 7.3的新特性这里简单介绍一下。

1. 更灵活的Heredoc和Nowdoc语法

PHP 7.3改进了Heredoc和Nowdoc的语法允许闭合标记缩进也允许在闭合标记后加逗号这让Heredoc/Nowdoc在数组和函数参数中使用更方便也更美观。

2. JSONTHROWON_ERROR

PHP 7.3给jsonencode和jsondecode加入了JSONTHROWONERROR选项开启后JSON解析错误会抛出异常而不是,返回null需要用jsonlast_error()检查这让JSON错误处理更方便也更符合现代编程习惯。

3. is_countable函数

PHP 7.3加入了iscountable()函数用来检查变量是否是可计数的(数组,或者实现了Countable接口的对象)因为PHP 7.2开始对不可计数的变量调用count()会报warning所以iscountable()函数能帮你先检查再计数避免warning。

4. arraykeyfirst和arraykeylast

PHP 7.3加入了arraykeyfirst()和arraykeylast()函数用来获取数组的第一个和最后一个键名之前,要获取第一个键名需要用reset()和key()比较麻烦现在有了专门的函数方便很多。

5. 性能提升

PHP 7.3也有一些性能提升,比如改进了垃圾回收(GC)的性能优化了一些常用函数的性能等等,虽然没有PHP 7对比PHP 5那么大的提升,但是也有一定的进步。

六、我的心得和体会

学了一段时间PHP我有一些心得和体会分享给大家。

心得1:PHP没有想象中,那么差

之前,受各种黑PHP的梗影响觉得PHP很差很烂,但是真正学了之后,发现PHP没有想象中,那么差特别是PHP 7之后,性能很好语法也加入了很多现代特性开发体验还不错,而且PHP的生态很完善文档很全社区很活跃遇到问题很容易找到解决方案对于Web开发来说PHP还是很高效的选择。

当然PHP也有一些历史遗留问题,比如函数命名不一致参数顺序不统一弱类型的坑等等这些是事实,但是也不是不能接受,只要了解了这些坑注意规避PHP开发还是很顺畅的。

心得2:选对框架很重要

PHP开发选对框架很重要好的框架能帮你规避很多PHP的坑提供更好的开发体验,比如Laravel是目前最流行的PHP框架设计很优雅功能很完善开发体验很好用Laravel开发PHP项目和用其他现代框架(比如RailsDjango)体验差不多甚至更好。

如果是国内项目ThinkPHP也是不错的选择文档全中文社区活跃容易上手,还有SlimSilex等微框架适合小项目和API开发,总之,不要裸写PHP选一个好的框架能大大提升开发效率和代码质量。

心得3:注意编码规范

PHP的灵活性也意味着容易写出很烂的代码,所以注意编码规范很重要推荐遵循PSR规范(PSR-1PSR-2PSR-4等等)这些是PHP社区的编码标准遵循这些规范能让代码更清晰更易读也方便团队协作。

另外建议用严格类型模式(declare(strict_types=1))开启标量类型声明和返回值类型声明这样能避免很多弱类型的坑让代码更健壮也用Composer做依赖管理和自动加载不要手动require文件这些都能提升代码质量和开发效率。

心得4:不要放弃坚持下去

学任何新语言都会遇到困难和坑PHP也不例外一开始可能会觉得PHP的语法很怪坑很多想放弃,但是,只要坚持下去慢慢熟悉了就会发现PHP其实还挺好用的特别是做Web开发效率很高。

我一开始也差点从入门到放弃,但是坚持了下来现在已经能比较熟练地用PHP开发了也体会到了PHP的优点和乐趣,所以,如果你也在学PHP遇到了困难不要放弃坚持下去会有收获的。

七、写在最后

以上就是我学习PHP 7.2/7.3的经历和心得包括环境搭建的坑语法特性的坑PHP 7.2的新特性PHP 7.3的展望以及一些心得和体会。

PHP是一门有争议的语言有人黑它有人爱它,但是不可否认,它在Web开发领域的地位和影响力特别是PHP 7之后,进步很大已经不是以前那个被黑的PHP了值得学一下。

当然PHP也有一些历史遗留问题和坑需要注意规避,但是,只要了解了这些坑选对框架遵循规范PHP开发还是很高效很愉快的。

如果你也在学PHP或者打算学PHP希望我的经历和心得能帮你少走弯路更快上手PHP享受PHP开发的乐趣。

最后用一句话结束这篇文章:"PHP是世界上最好的语言(梗)但是,只要你了解它用好它它确实能帮你高效地完成Web开发任务。"

愿大家都能享受编程的乐趣,不管用什么语言写出好的代码做出好的产品。