短短两年使用率下滑 40%!曾经风靡全球的 PHP 为何逐渐失去优势?

作者 | Richard MacManus

译者 | 核子可乐

策划 | Tina

根据 WordPress 联合创始人 Matt Mullenweg 的说法,PHP 的受众比例急剧下降,疑似受到 WordPress“JavaScript 优先”主张的影响。

TIOBE 编程语言人气指数发布更新,并提出“PHP 的魔力是否正在消散?”的灵魂拷问。今年 4 月,PHP 在 TIOBE 编程语言指数榜上仅位列第 17,“成为其有史以来的最低排位”。

暴露 PHP 人气急剧下滑的还不只是 TIOBE 榜单。在年度 Stack Overflow 开发者调查报告中,PHP 的市场占比也从 2018 年的 30.7%(即受访者当中使用 PHP 的百分比)下降至 2023 年的 18.58%。JetBrains 开发者生态系统调查同样观察到类似的趋势,PHP 占比从 2017 年的 30%下降至 2023 年的 18%。而且最后一项数据尤其值得关注,因为 JetBrains(以及 WordPress 托管厂商 Automattic)正是 PHP 的最大赞助方之一。

JetBrains 公布的开发者调查结果

这种下滑趋势在 BuiltWith 上体现得尤其明显,自 2020 年底以来 PHP 的流行度增长线开始断崖式跌落。

BuiltWith 公布的 PHP 趋势图

截至 2021 年 11 月的一项调查显示,PHP 在互联网前百万个网站中的占比仍在 3 万以上。但如今两年多过去,其占比已经下滑至 1.5 万左右。而且截至本文撰稿之时,BuiltWith Quotes 公布的实际占比数字为 18.19%。18%这个比例与 Stack Overflow 及 JetBrains 的调查发现高度吻合,因此我们可以基本确定,PHP 在开发者中的受欢迎程度已经从之前的约 30%萎缩至现在的 18%。换言之,在短短两年之间下降了 40%。

所以结论是什么?在过去几年里到底发生了什么样的变化,才导致 PHP 在 Web 编程语言的竞争当中迅速落败?

可以说,PHP 衰落的最大原因就是 WordPress(迄今为止最具人气的 Web 内容管理系统)正在从 PHP 转向 JavaScript。WordPress 联合创始人兼 Automattic 公司 CEO Matt Mullenweg 在上月于中国台湾召开的 WordCamp Asia 2024 大会上也就此做出论述。

他在回答观众提问时表示,“我觉得 WordPress 中的大部分新代码现在都是由 JavaScript 编写而成,而且这种趋势已经持续了一段时间。因此从方方面面来讲,如今的 Gutenberg 已经转化成了一个 JavaScript 优先的项目。”

大家绝没看错:Matt Mullenweg 直言现在的 WordPress 就是个“JavaScript 优先的项目”。而他所提到的 Gutenberg,其实是该公司备受争议的全新用户界面,同时也是推动 JavaScript 全面替代 PHP 的主要原因。当然,他也承认从 PHP 转向 JavaScript“并不容易”。

WordPress 联合创始人 Matt Mullenweg 在 WordCamp Asia 2024 大会上

这倒不是说 WordPress 不再依赖于 PHP。毕竟在撰写本文时,我恰好就是在 WordPress 中以“/wp-admin/post-new.php”结尾的 URL 输入这篇文章。但只能说目前如此,未来的 WordPress 已经确定要走向另一条道路。

Mullenweg 还谈到,他希望能在 WordPress 中看到进一步改进——令人惊讶的是,他已经开始从 JavaScript 的视角出发看待这些变化。比如说,PHP 是一种服务器端脚本语言(意味着代码通常在 Web 服务器上处理),而 Mullenweg 希望 WordPress 能使用 JavaScript 把更多操作交由客户端执行。

他意味深长地表示,“我真心觉得我们应该把更多处理任务留在客户端。比如对于正在编辑的内容,这部分处理就可以交给客户端。这种在浏览器运行 JavaScript 的速度可能会更快,因为现在虚拟机和性能极强的处理器已经相当普遍。”

在演讲即将结束之时,有观众向 Mullenweg 询问他对 Gutenberg 项目的感受,以及开发人员为其做出贡献时遭遇到哪些困难。提出这个问题的开发者还希望“降低 Gutenberg 的抽象级别”。

Mullenweg 回应称,“说实施,我觉得大家必须适应这种发展态势。我认为 Gutenberg 的开发方式和 JavaScript 优先理念才是大部分 Web 开发工作的未来方向。顺带一提,其实我也得重新学习,这些东西跟我当初熟悉的方式也有区别。也许我们可以把某些抽象调整得更简单一点,但总体而言,我会选择深入研究一下。”

他还补充称,Gutenberg 项目、包括向 JavaScript 语言的转变,目前还远未完成。“在启动 Gutenberg 项目时,我们就知道这可能是个为期 10 年的项目。目前我们才刚刚完成 60%到 70%的工作。”

不得不承认,WordPress 项目(也是 PHP 能够在 Web 领域保持流行的最大动因)正坚定向着 JavaScript 世界迈进。这几乎必然会阻止更多年轻开发者选择 PHP,同时迫使其他开发人员(例如那些致力于服务 WordPress 客户的开发人员)从 PHP 转向 JavaScript。

但好消息是,仍然有相当一部分开发者群体会继续使用 PHP——毕竟两轮大规模开发者调查中的这 18%对应着相当体量的从业受众。而 PHP 基金会将继续为他们提供支持。

PHP 基金会于 2021 年 11 月正式成立,希望以非营利组织的身份承担起 PHP 项目的管理职责。PHP 基金会是由 JetBrains 领导的企业联盟所建立,其中包括 Automattic、Zend、Laravel 以及 Acquia(Drupal 的托管商)等。JetBrains 工程师 Roman Pronskiy 则出任项目负责人,目前在基金会网站上的头衔为“运营主管”。

在今年 2 月的 Laravel 会议上,Pronskiy 主要探讨了技术问题,同时也承认“PHP 基金会目前最艰巨的任务,就是扭转 PHP 在公众心目中的形象。”虽然他没有具体说明是哪些原因导致 PHP 的公众形象下降,但 Matt Mullenweg 在解释 WordPress 转向“JavaScript 优先”的理由时已经基本给出了答案。无论如何,Pronskiy 正快速投身于 PHP 项目的后续开发,并为其组织起由 10 名有偿开发者组成的全职团队。

PHP 基金会团队

总而言之,2024 年的 PHP 几乎成了 Web 开发领域爹不疼、娘不爱的“孤儿”,而 JavaScript 则是在家、在校都备受关注的宠儿。对 PHP 来说更加可悲的是,目前的这种人气下滑趋势短时间内恐怕无法停止——毕竟 WordPress 那边的开发团队还在积极适应新的 JavaScript 规范。但至少 PHP 基金会还在为此而努力,也许这股颓势能够逐渐迎来转机。

原文链接:

PHP 8:函数和方法

作者 | Deepak Vohra

译者 | 刘雅梦

策划 | 丁晓昀

本文属于专题文章《深入浅出 PHP 8》。 根据w3tech的数据,PHP 仍然是 Web 上使用最广泛的脚本语言之一,77.3%的网站使用 PHP 进行服务器端编程。PHP 8 带来了许多新特性和其他改进,我们将在本系列文章中进行探讨。PHP 8.0 添加了对多个函数和方法相关特性的支持,其中一些是对现有特性的改进,而另一些则是全新的特性。PHP 8.1 中增强的可调用语法可用于通过可调用对象创建匿名函数。命名函数参数可以与位置参数一起使用,另外还有一个好处,即命名参数没有顺序,可以通过它们的名称来传达含义。纤程(Fiber)是可中断的函数,增加了对多任务的支持。

对象继承是大多数面向对象语言(包括 PHP)所使用的编程范式。它可以从任何扩展类中重写公共和受保护的方法,以及在类中定义的类属性和常量。在 PHP 中,公共方法不能通过更严格的访问来重新实现,例如将 public 方法设为 private 。为了演示这一点,考虑一个扩展了类 A 的类 B,它重新实现了类 A 中一个公共方法。

运行时,脚本会生成如下的一条错误信息:

相反,在类中定义的私有方法不是继承的,可以在扩展它的类中重新实现。例如,类 B 在下面的脚本中扩展了类 A,并重新实现了类 A 中一个私有方法。

在 PHP 8.0 之前,对扩展类中私有方法的重新声明应用了两个限制:不允许更改 finalstatic 修饰符。如果 private 方法被声明为 final ,则不允许扩展类重新声明该方法。如果私有方法被声明为静态的,那么它将在扩展类中保持静态。而且,如果私有方法没有static 修饰符,则不允许扩展类添加static 修饰符。在 PHP 8 中,这两个限制都被取消了。以下脚本在 PHP 8 中能正常运行。

PHP 8 中唯一的私有方法限制是强制使用 private final 构造函数,当使用静态工厂方法作为替代时,有时会使用private final来禁用构造函数。

该脚本生成如下的错误信息:

在 PHP 8 中,单个可变参数可以替换任意数量的函数参数。考虑下面的脚本,其中类 B 扩展了类 A,并用一个可变参数替换函数 sortArray 的三个参数。

可以使用多个参数调用类 B 中的 sortArray 函数。

输出结果如下所示:

可调用(callable)是可以被调用的 PHP 表达式,例如实例方法、静态方法或可调用对象。例如,可调用可用于为方法调用创建简短的表达式。在 PHP 8.1 中,可以用新的可调用语法:

AVariableCallableExpression(…)

AVariableCallableExpression 表示一个变量可调用表达式。省略号…包含在语法中。

这有两个问题:

  1. 语法涉及字符串和数组
  2. 在创建可调用时,作用域不会被维护。为了演示这一点,请考虑如下用于对数组进行排序的脚本,其中 getSortArrayMethod() 方法返回 sortArray() 方法的可调用项,[$this,\’sortArray\’]

该脚本会生成如下的错误信息:

使用 Closure::fromCallable([$this, \’sortArray\’]) 而不是 [$this, \’sortArray\’] 可以解决作用域问题,但使用 Closure::fromCallable 方法会使调用变得冗长。新的可调用语法解决了作用域和语法冗长的问题。使用新的可调用语法,函数变为:

数组根据输出进行排序:

新语法可以与涉及字符串和数组的传统语法结合使用,以解决作用域问题。创建可调用的作用域将保持不变。

新的可调用语法也可以与静态方法一起使用,如下面的脚本所示,该脚本包含一个静态函数。

输出结果与之前的相同:

以下是调用方法的等效方法:

以下是调用静态方法的等效方法:

即使函数声明了形参,也可以使用新的可调用语法。

如果一个方法声明了任意参数,则必须使用它的参数来调用可调用对象。

简化的可调用语法可以用于任意的 PHP 可调用表达式。用于对象创建的 new 运算符不支持可调用语法,因为可调用语法 AVariableCallableExpression(…) 没有指定构造函数参数的规定,这可能是必需的。以下是不支持的示例:

生成的错误信息为:

以下的脚本演示了受支持的所有可调用表达式。

PHP 8.0 的另一个新特性是支持在函数的参数列表末尾添加一个尾逗号,以提高可读性。任何尾逗号都将被忽略。尾逗号可能并不总是有用的,但如果参数列表很长,或者参数名称很长,则可能会有用,因此可以垂直列出它们。闭包使用列表也支持尾逗号。

PHP 8.0 不支持在必选参数之前声明可选参数。在必选参数之前声明的可选参数都是隐式的必选参数。

下面的脚本演示了必选参数的隐式顺序,以及尾逗号的使用。

输出如下所示:

可空参数不会被视为可选参数,可以使用 $param=null 形式或显式可空类型在必选参数之前声明,脚本如下所示:

PHP 8.0 除了已经支持的位置形参和实参之外,还增加了对命名函数形参和实参的支持。命名参数在函数调用中的传递语法如下所示:

命名参数的一些好处如下所示:

  • 可以为函数参数指定一个有意义的名称,使它们能够自我记录
  • 按名称传递时,参数与顺序无关
  • 可以任意跳过默认值。在下面的脚本中, array_hashtable 函数声明了命名参数。 该函数传递的实参值可以带参数名,也可以不带参数名。当传递位置实参时,使用函数形参声明顺序。但传递命名实参时,可以使用任意顺序。

输出结果为:

命名实参和位置实参可以在同一函数调用中使用。对相同的示例函数 array_hashtable 一起使用混合参数调用。

输出结果为:

请注意,命名参数只能用于位置参数之后。下面的脚本颠倒了顺序,在命名参数之后使用位置参数:

该脚本生成的错误信息为:

即使使用命名参数,也不推荐在必选参数之前声明可选参数,脚本如下所示:

输出将包括已弃用(不推荐)信息:

当在必选命名形参之后使用可选命名形参时,命名实参可用于跳过函数调用中的一个或多个可选形参,脚本如下所示:

输出结果为:

你可以只使用可选参数的子集来调用函数,而不用考虑它们的顺序。

输出结果如下所示:

即使使用可选参数的子集调用函数,也不能在命名参数之后使用位置参数,脚本如下所示:

生成的错误信息以下所示:

PHP 8.1 改进了命名实参特性,在解包实参后支持命名实参,脚本如下所示:

输出如下所示:

但是,命名的参数不能盖前面的参数,脚本如下所示:

输出如下所示:

在 PHP 8.0 之前,如果在静态上下文中调用非静态方法,或者静态调用,则只会收到一条已弃用(不推荐)的信息。使用 8.0,你现在会收到一条错误信息。此外, $this 在静态上下文中是未定义的。为了演示这一点,请考虑如下的脚本,其中使用静态语法 A::aNonStaticMethod() 调用了非静态方法 aNonStaticMethod()

如果你运行这个脚本,将会得到如下的错误信息:

PHP 8.1 添加了对纤程(Fiber)多任务的支持。纤程是一个可中断的函数,它具有自己的堆栈。纤程可以从调用堆栈中的任何位置挂起,然后再恢复。新的 Fiber 类是一个 final 类,它支持以下的公共方法:

纤程只能启动一次,但可以挂起并恢复多次。下面的脚本通过使用纤程在数组上执行不同类型的排序来演示多任务处理。纤程在每次排序后都会挂起,然后再恢复执行不同类型的排序。

输出如下所示:

如果纤程在第一次挂起后没有再恢复,则只进行一种类型的排序,这可以通过注释掉对 resume() 的两次调用来实现。

输出的是第一次排序的结果:

PHP 8.0 引入了一个名为 Stringable 的新接口,它只提供一个方法 __toString()__toString() 方法如果在类中提供,将隐式实现 Stringable 接口。考虑提供 __toString() 方法的类 A。

该脚本从 Stringable 的类型检查中返回 1。

然而,反之则不然。如果类实现了 Stringable 接口,则必须显式提供 __toString() 方法,因为该方法不会自动添加,比如:

PHP 8 引入了许多属于其标准库的新函数。

str_contains 函数返回一个 bool 值,用于指示作为第一个参数的字符串是否包含作为第二个参数的字符串。以下脚本将返回 false

下面的脚本返回 1,或 true:

str_starts_with 函数返回一个bool 值 ,指示作为第一个参数的字符串是否以作为第二个参数的字符串开头。以下脚本将返回 false

下面的脚本将返回 1,或 true。

str_ends_with 函数返回一个bool 值 ,指示作为第一个参数的字符串是否以作为第二个参数的字符串结尾。以下脚本将返回 false

下面的脚本将返回 1,或 true。

fdiv 函数将两个数字相除并返回一个 float 值,脚本如下所示:

输出为:

fdatasync 函数在 Windows 上的别名为 fsync ,用于将数据同步到文件上的流中。为了演示它的用法,在包含要运行的 PHP 脚本的脚本目录中创建一个空文件 test.txt 。运行脚本:

随后,打开 test.txt 文件会发现包含如下的文本:

array_is_list 函数返回布尔值,用于指示给定的数组是否为列表。数组必须从 0 开始,键必须是连续的整数,并且顺序正确。下面的脚本演示了 array_is_list 函数:

输出为:

魔术方法是 PHP 中用于覆盖默认操作的特殊方法。它们包括如下的方法,其中构造函数 __construct() 可能是大家最熟悉的:

从 PHP 8.0 开始,魔术方法定义的签名必须要是正确的,这意味着如果在方法参数或返回类型中使用类型声明,则它们必须与文档中的声明相同。新的 __toString() 方法的返回类型必须要声明为 string 。下面的演示将返回类型声明为 int

将生成如下的错误信息:

但是,未通过定义声明返回类型的函数(如构造函数)不能声明返回类型,即使是 void 返回类型也不行。示例如下脚本所示:

该脚本将返回如下的错误信息:

所有魔术方法,除了少数例外(例如 __construct() )外,都必须声明为具有公共可见性。为了演示这一点,声明了一个带有 private 可见性的 __callStatic

输出的警告信息为:

尽管可以省略混合返回类型,但方法签名也必须相同。例如,在下面的脚本中,类 A 声明了 __callStatic 而没有指定其返回类型,而类 B 将其第一个参数定义为int

输出的错误信息如下所示:

在 PHP 8.1 中,大多数内部方法,即内部类中的方法,都已经“试探性地”开始声明返回类型。试探性地暗示,虽然在 8.1 中只会引发不推荐(Deprecation)通知,但在 9.0 版中,则会输出错误条件信息。因此,任何扩展类都必须声明与内部类相兼容的返回类型,否则将会引发已弃用(不推荐)通知。为了演示这一点,扩展内部类 Directory 并重新声明没有返回类型的函数 read()

该脚本将生成已弃用(不推荐)通知:

但是,以下脚本是可以的:

添加 #[\\ReturnTypeWillChange] 属性能抑制已弃用(不推荐)通知:

虽然包含有关方法参数的详细信息的异常堆栈跟踪对调试非常有用,但你可能不希望输出某些敏感参数的参数值,例如与密码和凭据关联的参数值。PHP 8.2 引入了一个名为 \\SensitiveParameter 的新属性,这样,如果使用 \\SensitivyParameter 属性注解方法的参数,则该参数的值不会在异常堆栈跟踪中输出。

为了演示这一点,考虑下面的脚本,其中函数 f1 具有与 \\SensitiveParameter 属性关联的参数 $password

为了演示 \\SensitiveParameter 特性,该函数只是抛出一个异常。调用函数:

请注意,异常堆栈跟踪不包含 $password 参数的值,而是列出了 Object(SensitiveParameterValue)

内置函数 utf8_encode()utf8_decode() 经常被误解,因为它们的名称意味着对任何字符串进行编码/解码。实际上,这些函数仅用于编码/解码 ISO8859-1,即“Latin-1”字符串。此外,它们生成的错误信息对于调试来说描述性不够。PHP 8.2 已经弃用了这些函数。下面的脚本使用了它们:

对于 PHP 8.2,会输出已弃用(不推荐)通知:

在 PHP 8.2 中,函数 iterator_countiterator_to_array 接受所有可迭代的对象。 iterator_to_array() 函数将迭代器的元素复制到数组中。 iterator_count() 函数对数组的元素进行计数。这些函数接受一个 $iterator 作为第一个参数。在 PHP 8.2 中,$iterator 参数的类型已从 Traversable 扩展为 Traversable|array ,以便接受任意的可迭代值。

下面的脚本演示了它们在 arraysTraversables 中的使用。

输出如下所示:

在这篇 PHP 8 系列文章中,我们讨论了与函数和方法相关的新特性,其中最突出的是命名函数的形参/实参、简化的可调用语法和被称为纤程(Fiber)的可中断函数。

在本系列的下一篇文章中,我们将介绍 PHP 类型系统的新特性。

原文链接:

https://www.infoq.com/articles/php8-functions-methods/

相关阅读:

PHP 8:注解、match 表达式及其他改进

PHP 8:类和枚

只需要四步,就能完成PHP搭建

搭建php的方法主要分为独立安装和集成安装两种,独立安装需要分别下载apache,mysql和php,而集成只需要下载一个软件安装包,比较简单,很适合新手。集成安装包有WampServer、appserv、easyphp等,下面我们以WampServer为例教大家搭建php开发环境。

一. 确定自己的电脑系统位数

右击桌面上的电脑图标,打开属性界面,在系统—>系统类型中查看操作系统的位数。如图,笔者的为64位。

二.根据系统位数下载对应版本的wampserver并安装(安装过程比较简单,这里不做说明)

所需软件已打包到网盘,链接: http://pan.baidu.com/s/1eQ2iYoa 密码: 7qng

注:如果安装wampserver过程中提示缺少msvcr110.dll,此时需要根据系统平台环境安装相应的visual c++或者vc++(见网盘)

安装完成后打开应用桌面右下角会出现一个小图标,小图标显示绿色则安装正常。

三. 语言切换

用鼠标左击小图标会发现菜单栏都是英文,这里只需要右击图标->Language->chinese,即可切换到中文版。

WampServer中php版本的切换(选看,对新手不做要求)

由于做项目经常要用到不同版本的php,这里简单给大家演示一下版本的切换,这里以5.6.6版本为例。

1、查看默认版本

2、将php5.6.6的文件夹拷贝到C:\\wamp\\bin\\php\\下

3、去C:\\wamp\\bin\\php\\php5.5.12目录下拷贝两个文件,一个是wampserver.conf。另一个是phpForApache.ini,复制到php5.6.6目录下。

4、修改php5.6.6目录下的phpForApache.ini,修改一处内容,如下图所示:

修改完成之后,记得保存文件!然后重新启动Wampserver,这时候就可以进行版本切换了。

四. Php环境变量的设置

1、打开我的电脑->属性->高级

2、点击环境变量,进入环境变量配置界面

3、点击Administrator的用户变量下面的新建按钮:

变量名:path

变量值:php.exe的文件路径

4、然后下面的系统变量中:

选中path,点击编辑

在变量值一栏的最后输入英文的分号加上php.exe的路径

5、开始->运行 输入cmd,在命令行窗口中输入php –h; 若显示结果如下图,则配置成功。

对编程感兴趣的同学,可以先学习下高手对做过项目的总结或者平时写的一些知识点总结,请大家关注老码农搞的微信公众号:程序员互动联盟或者coder_online,可以直接在里面看技术文章,找技术讨论群,也可以问技术问题,找编程导师。

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。