@ProX
2020-07-22T01:11:33.000000Z
字数 3325
阅读 386
InfoQ
现在互联网上盛传“PHP已死” 的声音。虽然PHP确实有走下坡路的趋势,但是离淘汰还有一定的距离。本文介绍了作者所在的公司其核心业务上使用PHP的原因,希望大家可以结合自己实际需求场景,考虑在自己的项目中使用PHP。
与其他流行的编程语言相比,大家都普遍认为PHP是一个笨重且过时的编程语言。但是,接下来我会介绍一下为什么PHP在我们的需求场景下非常有用。
在Hologram,我们后端服务的搭建主要使用了两种的编程语言:PHP和Python。 其中PHP组件最接近用户层,它提供了所有服务的REST API接口。
确实,有人曾向我们提出这样的疑问:大家都在唱衰PHP,认为它笨重而且过时了,为什么你们还会重度使用PHP呢?在我看来,PHP被大家如此评价的原因有两个:
虽然上述问题客观存在,但是我仍然想为PHP辩护一下——PHP仍然是一门非常有用的编程语言,并且非常适合我们的需求。
我们都已经知道PHP具有一些不错的内置Web服务功能,例如可以获取HTTP Header信息、完整的session cookie的支持等。但是,可能很多人不知道,PHP在编程语言界仍占有一席之位,与它的一些其他功能特性有关。
下面我要讲述一下PHP的一些优点。
是的,PHP的早些版本不支持类对象,代码很快就会变得混乱起来。没有了面向对象,我们就需要写一大串的include来引用需要的一些方法函数,并且还必须不断地将大量的参数变量传递给名称很长的函数。
现在,你就不需要有上面这种担心。如今的PHP具有强大的面向对象的支持,包括了类,构造函数,析构函数,命名空间,继承等所有必须的功能。
但是,除此之外,PHP还具有它特有的一些强大功能:
PHP具有一个非常有用的功能特性,如果某个类尚未加载,它可以自动加载该类的文件。这意味着在所有文件的头部可以不再包含include / require语句块。如果你要使用一个类对象,那么它已经被自动加载了。
就其本身而言,这已经非常好了,但是更高级的使用场景是,在你的应用程序中可以完全自定义特定的自动加载逻辑,并且可以将多个自动加载器链接在一起。这意味着你所有的第三方库也将会被自动加载。
在你的代码中,只需创建类或调用它们的方法,那么一切都会为你自动加载。你无需通过编写代码加载或者像其他语言一样使用路径来加载特定内容。在测试代码之外的整个Hologram代码库中,我们可能仅有两次调用了include()或require()。
刚刚提到了第三方库,下面就说一下依赖管理。
PHP的软件包管理系统不输于其他的编程语言。我们在Hologram上使用的是Composer,它是最受欢迎的一个依赖管理工具。它使用起来非常简单,只需将配置参数保存在JSON文件中就可以了。你可以为每个软件包指定要使用的版本范围,并且它会生成一个锁定文件,将该锁定文件共享到代码库中,就可以确保所有开发者使用的第三方依赖版本完全相同。
将新的依赖包添加到JSON文件中并进行安装,操作起来非常简单,只需要在终端执行以下命令:
composer install somepackage
如今,PHP拥有一个强大的开发者社区,因此不仅有大量的工具库可供使用,而且拥有很多完整的框架可帮助简化应用程序的构建。在Hologram中,我们使用了Slim框架,该框架可以非常方便的定义API路由,还具有其他有用的功能,比如可以非常方便的添加用于身份验证以及速率限制的中间件等。
其他流行的框架还包括我们熟悉的Laravel和Symfony等。
PHP拥有我使用过的所有编程语言中最好用的数据库集成接口,而PDO是所有数据库接口的基础。PDO是PHP Database Objects的缩写,它是执行SQL查询的首选方式。
它包括用于查询以及对结果分页的所有常用功能。还可以按“行”将数据存储到PHP关联数组,这意味着所有“列”数据在数组里存在着键值,且支持通过键值访问数组数据。
最棒的就是它支持参数化查询并可以防止sql注入。这意味着你可以执行以下操作:
// define $database as a PDO object$stmt = $database->prepare("SELECT * FROM users WHERE id = ?;");$result = $stmt->execute([$idnumber]);$rows = $result->fetchAll();
PDO会自动将“?”替换为$ idnumber中的值,进行正确地转义以防止SQL注入攻击。
你还可以做一些更酷的事情,例如它还支持绑定命名参数:
// define $database as a PDO object$values = ['id' => 10, 'email' => 'someemail@hologram.io'];$stmt = $database->prepare('SELECT * FROM users WHERE id = :id AND email = :email;');$result = $stmt->execute($values);$rows = $result->fetchAll();
在这种情况下,PDO会在参数化查询的同时进行正确的参数替换。
无论什么类型的数据库引擎,PDO都会对外公开相同的接口。当然,数据库引擎之间偶尔也会有SQL语句的差异,但是大多数情况下,你只需在初次连接数据库时指定好数据库的类型,然后就可以调用一套函数方法对所有数据库进行相同的操作了。
说到数据库,我必须推荐一个非常好用的第三方库——Phinx,我们可以通过该工具来完成我们所有的数据库的迁移工作。每当我们需要进行数据库模式变更时,可以使用Phinx在数据库上进行数据迁移操作。迁移过程如下所示:
$orders = $this->table('orders');$orders->addColumn('invoice_text', 'string', ['length'=>256, 'default'=>''])->update();
你可以去Phinx官网查看详细的使用文档。
最后一个使PHP变得更便捷、好用的一方面是它拥有出色的内置工具函数库。
假设你有一个来自数据库的结果集,该结果集是一个以行数组为元素的数组。假设你要从每个数组元素中提取name列。当然,我们可以使用PHP支持的map函数来执行此操作,但是为什么不以更简单的方式执行此操作呢:
$names = array_column($rows, 'name');
看,就是这么简单,而且上面的方法运行速度非常快,因为PHP内核直接调用运行的C接口。
还有很多类似的内置函数,从数组操作到解析XML到处理上传的文件,你都可以从PHP官方文档中查到具体的使用方法。
在这里我列举一下我常用的一些PHP内置函数:
array_chunk —— 对数组进行截取操作
array_unique —— 移除数组中的重复元素
DateTime —— 用于处理日期的方法,还可以解析简单的英语日期描述,例如“midnight first day of next month”
fpassthru —— 读取文件内容,并输出结果给用户。
str_getcsv —— 解析 CSV 格式字段的字符串,并返回一个包含所读取字段的数组。
urlencode —— 对字符串进行URL编码
对了,不要忘记一些有用的符号运算符,例如?? ,它可以让你在对数组指定默认值的同时检查数组中索引是否存在。
$a = $some_array[$x] ?? 500;
所以,大家可以考虑将PHP用于自己的项目!它比你想像中的要好很多。
Reuben Balik
Hologram首席工程师