Perl 和 PHP 之间的差异 [已关闭]
我打算学习Perl 5,因为我只使用PHP到现在,我想知道一些关于语言彼此之间的差异。
由于PHP最初是一组“Perl hacks”,它显然克隆了一些Perls功能。
语法的主要区别是什么?使用Perl,你真的有更多的选择和方式来表达一些东西吗?
为什么Perl不再经常用于动态网站?是什么让PHP越来越受欢迎?
我打算学习Perl 5,因为我只使用PHP到现在,我想知道一些关于语言彼此之间的差异。
由于PHP最初是一组“Perl hacks”,它显然克隆了一些Perls功能。
语法的主要区别是什么?使用Perl,你真的有更多的选择和方式来表达一些东西吗?
为什么Perl不再经常用于动态网站?是什么让PHP越来越受欢迎?
Perl和PHP比同类产品更不同。让我们考虑一下Perl 5,因为Perl 6已经成为它自己的语言(Raku),而不是Perl的新版本。每种语言都在不断发展,因此此列表中的某些项目可能会过时;读者应该依靠官方文档来学习每种语言的当前功能。
一些差异,大致按主题分组:
Perl具有原生正则表达式支持,包括正则表达式文本。PHP使用Perl的正则表达式函数作为扩展。
PHP中的语言级别支持许多语言功能,但在Perl中作为包实现(例如生成器和一些OOP运算符)。下面将提到其中一些。
两者都支持字符串中的转义序列,并支持一些相同的序列,但是Perl和PHP对于相同的功能(例如Unicode代码点)也有一些不同的转义序列,并且转义序列根本不共享。
Perl 有相当多的运算符,包括匹配 (, )、类似引号 (, &c.)、字符串重复 () 和 range ( 和 )。PHP有一些Perl没有的运算符,例如错误抑制运算符(),instanceof
和clone
(尽管Perl通过模块提供了其中一些运算符,例如Universal::isa
)。=~
!~
qw
qx
x
..
...
@
在 PHP 中,new
是一个运算符。在Perl中,它是包中定义的对象创建子例程的传统名称,就语言而言,没有什么特别的。
Perl 逻辑运算符返回其参数,而它们在 PHP 中返回布尔值。尝试:
$foo = '' || 'bar';
在每种语言中。在Perl中,如果尚未设置,您甚至可以将其设置为值。$foo ||= 'default'
$foo
PHP 7.0 添加了一个 NULL 合并运算符 ??
,7.4 添加了 NULL 合并赋值。这些与 Perl 类似,但比 Perl 更有限,因为它们只在左边是 时返回右边,而不是任何 falsey 值。Perl 5.10 添加了它自己的 NULL 合并运算符 //
。(不相关的是,“//”在 PHP 中以单行注释开头。??=
||
NULL
Perl 变量名称表示内置类型,其中 Perl 有三个,类型说明符是名称的一部分(称为“sigil”),因此是与 或 不同的变量。$foo
@foo
%foo
(与上一点相关)Perl具有用于标量,数组,哈希,代码,文件/目录句柄和格式的单独符号表条目。每个都有自己的命名空间。
请注意,“引用”在PHP和Perl中具有不同的含义。在 PHP 中,引用是符号表别名。在 Perl 中,引用是智能指针。
Perl对整数索引集合(数组)和字符串索引集合(哈希)有不同的类型。在PHP中,它们是相同的类型:关联数组/有序映射。
Perl数组不是稀疏的:设置索引大于数组当前大小的元素将创建所有干预元素,尽管没有初始化它们(请参阅perldata和存在
)。PHP数组是稀疏的;设置元素不会创建干预元素。
Perl本身支持哈希和数组切片,切片是可分配的,它有各种各样的用途。在 PHP 中,使用array_slice
提取切片,并使用array_splice
分配给切片。
Perl 通过将所有元素与 .PHP 通过首先将数组转换为字符串来将数组插入到字符串中,这始终导致值“Array”。$"
Perl 自动平展列表(参见 perlsub);对于未平展的数据结构,请使用引用。
@foo = qw(bar baz);
@qux = ('qux', @foo, 'quux'); # @qux is an array containing 4 strings
@bam = ('bug-AWWK!', \@foo, 'fum'); # @bam contains 3 elements: two strings and a array ref
PHP 从 5.6 开始增加了对参数列表(称为“参数解包”)扩展的支持,这必须使用 显式完成。在 7.4 中,添加了一个 spread 运算符(在“数组解包”这个绰号下),尽管仅适用于整数索引。在 8.1 中,此操作扩展到字符串索引。...
你可以省略PHP中下标运算符的参数,以获得一些魔力。在Perl中,你不能省略下标。
Perl 哈希是无序的。
Perl有语句修饰符:一些控制语句可以放在语句的末尾。
Perl 支持通过关键字进行动态作用域。local
在 Perl 中,变量默认为全局变量。在 PHP 中,函数中的变量默认为局部变量。
PHP使用更常见的参数列表来声明函数参数,Perl有原型。
Perl 使用按引用传递(即使数组参数在参数列表中是扁平的,元素也是通过引用传递的)。请注意,部分由于 Perl 中“引用”的特殊含义(如上所述),“逐个引用传递”在 Perl 文档中用于表示其他含义(“传递引用”会更准确),并且是一种避免在参数列表中数组和哈希扁平化的方法。默认情况下,PHP 使用按值传递,但可以为单个参数和可变参数(如果使用)显式指定按引用传递。请注意,存储对象的变量的值是它的句柄,这意味着当按值传递对象时,对象仍然可以被突变,尽管原始变量本身不能被改变以保存不同的值。
当涉及到类型提示时,PHP提供了Perl中没有的各种静态类型功能:参数,变量,返回(包括一些仅返回)和可为 null 的类型声明,以及联合(从8.0开始)和交集(从8.1开始)类型声明。这些功能中的大多数都是从 7.0 开始添加的。
在 Perl 中,如果子例程是表达式(即它具有值),则最后计算的语句将作为子例程的值返回,即使未使用 return 语句也是如此。如果最后一个语句不是表达式(即没有值),例如循环,则返回值未指定(请参阅 perlsub)。在 PHP 中,如果没有显式返回,则返回值为 NULL。
Perl 具有执行的特殊代码块 (、 、 和 )。与PHP auto_prepend_file
和auto_append_file
不同,每种类型的代码块的数量没有限制。此外,代码块是在脚本中定义的,而 PHP 选项是在服务器和每个目录的配置文件中设置的。BEGIN
UNITCHECK
CHECK
INIT
END
Perl 中表达式的值是上下文相关的。
Perl 中的负下标是相对于数组末尾的。 是数组的最后一个元素。PHP中的负下标与其他任何下标一样是下标。$bam[-1]
在Perl 5中,类是基于包的,看起来与PHP(或大多数其他语言)中的类完全不同。Perl 6类更接近PHP类,但仍然有很大的不同。(Perl 6 在许多其他方面与 Perl 5 不同,但这偏离了主题。Perl 5和PHP之间的许多差异源于这样一个事实,即大多数OO功能不是Perl内置的,而是基于黑客攻击的。例如,被翻译成类似 .非详尽列表:$obj->method(@args)
(ref $obj)::method($obj, @args)
PHP 8.1 添加了枚举。虽然一些Perl模块提供了类似的功能,但它没有适当的枚举(考虑到类型的处理方式,它们也没有那么有用)。
Perl 支持运算符重载。
两者都用于开始单行注释,但PHP也使用(如前所述,这是Perl中的NULL合并运算符)。#
//
严格来说,Perl没有多行注释,但POD系统可以用于相同的效果。
在 PHP 5.3 之前,PHP 对匿名函数(函数)的支持很糟糕,而对闭包的支持却没有。create_function
PHP在5.3版本之前一直没有像Perl的软件包那样的东西,它引入了命名空间。
Perl 通过定义常量、将它们存储在变量中、操作符号表或使用执行其中一个操作的包来创建包别名。PHP 使用 创建命名空间别名。use
可以说,Perl对异常的原始内置支持看起来几乎与其他语言中的异常完全不同,以至于它们看起来几乎不像例外。计算块并检查 的值 ( 而不是 , die
而不是 )。TryCatch 和 Try::Tiny 模块支持异常,因为您可以在其他语言中找到它们(以及 Error 的“另请参阅”部分中列出的其他一些模块)。Perl 5.34.0 添加了更标准的 try
/catch
语法作为实验,默认情况下不启用。$@
eval
try
throw
一件有趣的事情是,这些语言在一些方面变得更加相似,尽管这不是任何一种语言影响另一种语言的结果,而是许多现代编程语言中引入的新功能。
PHP受到Perl的启发,就像《天堂魅影》受到歌剧魅影的启发一样,或者《奇怪的酿造》受到哈姆雷特的启发。在学习Perl时,最好把PHP的行为细节放在你的脑海中,否则你会被绊倒。
我的大脑现在很痛,所以我要停下来。
当PHP出现时,每个人都对Perl的主要区别印象深刻:
<?php ... ?>
随着时间的流逝,每个人都知道这些不是好处......