我打算学习Perl 5,因为到目前为止我只使用过PHP,我想知道语言之间的差异.
由于PHP最初是一组"Perl hacks",它显然克隆了一些Perls功能.
语法有哪些主要区别?用Perl你有更多的选择和表达方式吗?
为什么Perl不再常用于动态网站?是什么让PHP更受欢迎?
outis.. 282
Perl和PHP更不同.让我们考虑Perl 5,因为Perl 6仍处于开发阶段.一些差异,大致按主题分组:
Perl具有本机正则表达式支持,包括regexp文字.PHP使用Perl的regexp函数作为扩展.
Perl有很多运算符,包括匹配(=~
,!~
),类似引号(qw
,qx
&c.),exponentiation(**
),字符串重复(x
)和范围(..
和...
).PHP有一些运算符Perl没有,比如错误抑制operator(@
),instanceof
(虽然Perl确实有这个Universal::isa
方法)和clone
.
在PHP中,new
是一个运算符.在Perl中,它是包中定义的对象创建子例程的常规名称,就语言而言,没有什么特别之处.
Perl逻辑运算符返回它们的参数,而它们在PHP中返回布尔值.尝试:
$foo = '' || 'bar';
在每种语言.在Perl中,$foo ||= 'default'
如果尚未设置$ foo ,您甚至可以将其设置为值.在PHP中执行此操作的最短方法是$foo = isset($foo) ? $foo : 'default';
(更新,在PHP 7.0+中可以执行$foo = $foo ?? 'default'
)
Perl 变量名称表示内置类型,其中Perl有三个,类型说明符是名称的一部分(称为" sigil "),因此$foo
是一个与@foo
or 不同的变量%foo
.
(与前一点相关)Perl 为标量,数组,散列,代码,文件/目录句柄和格式分别设置了符号表条目.每个都有自己的命名空间.
Perl可以访问符号表,虽然操纵它不适合胆小的人.在PHP中,符号表操作仅限于创建引用和extract
函数.
请注意,"引用"在PHP和Perl中具有不同的含义.在PHP中,引用是符号表别名.在Perl中,引用是智能指针.
Perl对整数索引集合(数组)和字符串索引集合(散列)有不同的类型.在PHP中,它们是相同的类型:关联数组/有序映射.
Perl数组不稀疏:设置索引大于数组当前大小的元素将设置所有中间元素undefined
(参见perldata).PHP数组很稀疏; 设置元素不会设置干预元素.
Perl原生支持散列和数组切片,切片是可分配的,具有各种用途.在PHP中,您用于array_slice
提取切片并array_splice
分配给切片.
您可以将参数遗漏给 PHP中的下标运算符,以获得一些魔力.在Perl中,你不能省略下标.
Perl哈希是无序的.
Perl有大量的预定义和魔术变量.PHP的预定义变量具有完全不同的用途.
Perl有语句修饰符:一些控制语句可以放在语句的末尾.
Perl 通过关键字支持动态范围local
.
此外,Perl还具有全局,词汇(块)和包范围.PHP具有全局,函数,对象,类和命名空间范围.
在Perl中,默认情况下变量是全局变量.在PHP中,函数中的变量默认是本地的.
Perl 通过该函数支持显式尾调用goto
.
与PHP的类型提示相比,Perl的原型为函数参数提供了更有限的类型检查.因此,原型比类型提示更有限.
在Perl中,如果语句是表达式(即它有一个值),则最后一个计算语句将作为子例程的值返回,即使未使用return语句也是如此.如果最后一个语句不是表达式(即没有值),例如循环,则返回值未指定(请参阅perlsub).在PHP中,如果没有显式返回,则返回值为NULL.
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不会压缩数组.
Perl有特殊代码块(BEGIN
,UNITCHECK
,CHECK
,INIT
和END
被执行的).不像PHP的auto_prepend_file
和auto_append_file
,没有限制到每种类型的码块的数目.此外,代码块在脚本中定义,而PHP选项在服务器和每个目录的配置文件中设置.
在Perl中,分号分隔语句.在PHP中,它终止它们,除了PHP关闭标记("?>")也可以终止语句.
Perl中表达式的值是上下文敏感的.
Perl中的否定下标是相对于数组的结尾.$bam[-1]
是数组的最后一个元素.PHP中的否定下标是与其他任何内容相同的下标.
在Perl 5中,类基于包,看起来与PHP(或大多数其他语言)中的类完全不同.Perl 6类更接近PHP类,但仍然完全不同.(Perl 6的是不同的在其他许多方面,从Perl 5中,但是这是题外话.)许多的Perl 5和PHP之间的差异的事实,大多数OO功能没有内置于Perl的,但基于黑客引起.例如,$obj->method(@args)
被翻译成类似的东西(ref $obj)::method($obj, @args)
.非详尽清单:
PHP自动$this
在方法中提供特殊变量.Perl将对象的引用作为方法的第一个参数传递.
Perl的要求引用被祝福创建一个对象.任何引用都可以作为给定类的实例进行祝福.
在Perl中,您可以通过packages @ISA
变量动态更改继承.
Perl支持运算符重载.
严格来说,Perl没有多行注释,但POD系统可以用于相同的效果.
在Perl中,//
是一个运营商.在PHP中,它是单行注释的开始.
在PHP 5.3之前,PHP对匿名函数(create_function
函数)提供了糟糕的支持,并且不支持闭包.
在版本5.3之前,PHP没有像Perl的软件包那样,它引入了名称空间.
可以说,Perl对异常的内置支持看起来几乎与其他语言中的异常一样,以至于它们几乎不像异常.评价一个块,检查的价值$@
(eval
而不是try
,die
代替throw
).该错误 尝试::微型模块支持例外,你在其他语言中找到他们(以及在列出的一些其他模块错误的另请参见部分).
PHP的灵感来自Perl,就像天堂幻影的灵感来自歌剧魅影,或者Strange Brew的灵感来自哈姆雷特.在学习Perl时,最好将PHP的行为细节放在脑海中,否则你会被绊倒.
我的大脑现在疼,所以我要停下来.
Perl和PHP更不同.让我们考虑Perl 5,因为Perl 6仍处于开发阶段.一些差异,大致按主题分组:
Perl具有本机正则表达式支持,包括regexp文字.PHP使用Perl的regexp函数作为扩展.
Perl有很多运算符,包括匹配(=~
,!~
),类似引号(qw
,qx
&c.),exponentiation(**
),字符串重复(x
)和范围(..
和...
).PHP有一些运算符Perl没有,比如错误抑制operator(@
),instanceof
(虽然Perl确实有这个Universal::isa
方法)和clone
.
在PHP中,new
是一个运算符.在Perl中,它是包中定义的对象创建子例程的常规名称,就语言而言,没有什么特别之处.
Perl逻辑运算符返回它们的参数,而它们在PHP中返回布尔值.尝试:
$foo = '' || 'bar';
在每种语言.在Perl中,$foo ||= 'default'
如果尚未设置$ foo ,您甚至可以将其设置为值.在PHP中执行此操作的最短方法是$foo = isset($foo) ? $foo : 'default';
(更新,在PHP 7.0+中可以执行$foo = $foo ?? 'default'
)
Perl 变量名称表示内置类型,其中Perl有三个,类型说明符是名称的一部分(称为" sigil "),因此$foo
是一个与@foo
or 不同的变量%foo
.
(与前一点相关)Perl 为标量,数组,散列,代码,文件/目录句柄和格式分别设置了符号表条目.每个都有自己的命名空间.
Perl可以访问符号表,虽然操纵它不适合胆小的人.在PHP中,符号表操作仅限于创建引用和extract
函数.
请注意,"引用"在PHP和Perl中具有不同的含义.在PHP中,引用是符号表别名.在Perl中,引用是智能指针.
Perl对整数索引集合(数组)和字符串索引集合(散列)有不同的类型.在PHP中,它们是相同的类型:关联数组/有序映射.
Perl数组不稀疏:设置索引大于数组当前大小的元素将设置所有中间元素undefined
(参见perldata).PHP数组很稀疏; 设置元素不会设置干预元素.
Perl原生支持散列和数组切片,切片是可分配的,具有各种用途.在PHP中,您用于array_slice
提取切片并array_splice
分配给切片.
您可以将参数遗漏给 PHP中的下标运算符,以获得一些魔力.在Perl中,你不能省略下标.
Perl哈希是无序的.
Perl有大量的预定义和魔术变量.PHP的预定义变量具有完全不同的用途.
Perl有语句修饰符:一些控制语句可以放在语句的末尾.
Perl 通过关键字支持动态范围local
.
此外,Perl还具有全局,词汇(块)和包范围.PHP具有全局,函数,对象,类和命名空间范围.
在Perl中,默认情况下变量是全局变量.在PHP中,函数中的变量默认是本地的.
Perl 通过该函数支持显式尾调用goto
.
与PHP的类型提示相比,Perl的原型为函数参数提供了更有限的类型检查.因此,原型比类型提示更有限.
在Perl中,如果语句是表达式(即它有一个值),则最后一个计算语句将作为子例程的值返回,即使未使用return语句也是如此.如果最后一个语句不是表达式(即没有值),例如循环,则返回值未指定(请参阅perlsub).在PHP中,如果没有显式返回,则返回值为NULL.
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不会压缩数组.
Perl有特殊代码块(BEGIN
,UNITCHECK
,CHECK
,INIT
和END
被执行的).不像PHP的auto_prepend_file
和auto_append_file
,没有限制到每种类型的码块的数目.此外,代码块在脚本中定义,而PHP选项在服务器和每个目录的配置文件中设置.
在Perl中,分号分隔语句.在PHP中,它终止它们,除了PHP关闭标记("?>")也可以终止语句.
Perl中表达式的值是上下文敏感的.
Perl中的否定下标是相对于数组的结尾.$bam[-1]
是数组的最后一个元素.PHP中的否定下标是与其他任何内容相同的下标.
在Perl 5中,类基于包,看起来与PHP(或大多数其他语言)中的类完全不同.Perl 6类更接近PHP类,但仍然完全不同.(Perl 6的是不同的在其他许多方面,从Perl 5中,但是这是题外话.)许多的Perl 5和PHP之间的差异的事实,大多数OO功能没有内置于Perl的,但基于黑客引起.例如,$obj->method(@args)
被翻译成类似的东西(ref $obj)::method($obj, @args)
.非详尽清单:
PHP自动$this
在方法中提供特殊变量.Perl将对象的引用作为方法的第一个参数传递.
Perl的要求引用被祝福创建一个对象.任何引用都可以作为给定类的实例进行祝福.
在Perl中,您可以通过packages @ISA
变量动态更改继承.
Perl支持运算符重载.
严格来说,Perl没有多行注释,但POD系统可以用于相同的效果.
在Perl中,//
是一个运营商.在PHP中,它是单行注释的开始.
在PHP 5.3之前,PHP对匿名函数(create_function
函数)提供了糟糕的支持,并且不支持闭包.
在版本5.3之前,PHP没有像Perl的软件包那样,它引入了名称空间.
可以说,Perl对异常的内置支持看起来几乎与其他语言中的异常一样,以至于它们几乎不像异常.评价一个块,检查的价值$@
(eval
而不是try
,die
代替throw
).该错误 尝试::微型模块支持例外,你在其他语言中找到他们(以及在列出的一些其他模块错误的另请参见部分).
PHP的灵感来自Perl,就像天堂幻影的灵感来自歌剧魅影,或者Strange Brew的灵感来自哈姆雷特.在学习Perl时,最好将PHP的行为细节放在脑海中,否则你会被绊倒.
我的大脑现在疼,所以我要停下来.
当PHP出现在场景中时,每个人都对Perl的主要区别印象深刻:
输入变量已经在全局范围内,没有无聊的解析.
HTML嵌入.在任何地方.没有无聊的模板.
屏幕上的错误消息.没有无聊的错误日志偷看.
简单易学.没有无聊的书阅读.
随着时间的流逝,每个人都知道他们不是一个好处,呵呵......
我注意到大多数PHP与Perl页面似乎属于
PHP优于Perl,因为
之类,很少进行合理的比较.
语法方面,你会发现PHP通常比Perl更容易理解,特别是当你没有经验时.例如,在PHP中修剪一串前导和尾随空格就是这么简单
$string = trim($string);
在Perl中,它更加神秘
$string =~ s/^\s+//; $string =~ s/\s+$//;
(我相信这比单线捕获和替换更有效,也更容易理解.)然而,即使PHP通常更像英语,它有时仍然显示其根源作为低级别C的包装,例如,strpbrk
并且strspn
可能很少使用,因为大多数PHP dabblers为任何太深奥的东西编写自己的等效函数,而不是花时间探索手册.我也想知道英语是第二语言的程序员,因为每个人都和Perl这样的东西平起平坐,不得不从头开始学习.
我已经提到了手册.PHP有一个很好的在线手册,不幸的是它需要它.对于应该简单的事情,例如参数顺序或函数命名约定,我仍然不时地引用它.使用Perl,你可能会发现在你开始使用手册的时候很多,然后有一天你会有一个ha- moment时刻再也不需要了.好吧,至少直到你更先进,并意识到不仅有不止一种方式,可能有更好的方法,其他人可能已经做得更好的方式,也许你应该只访问CPAN.
Perl确实有很多选择和表达方式.这不一定是好事,尽管如果明智地使用代码并且至少有一种您可能熟悉的方式,它允许代码更易读.有些风格和习惯你会发现自己陷入其中,我可以衷心地推荐阅读Perl最佳实践 (早点而不是晚点),以及Perl Cookbook,第二版 ,以便快速解决常见问题.
我相信Perl在共享托管环境中使用较少的原因是,历史上CGI的感知缓慢以及主机由于安全性和配置问题而不愿意安装mod_perl使得PHP成为更具吸引力的选择.然后循环继续,更多的人学习使用PHP,因为更多的主机提供它,更多的主机提供它,因为这是人们想要使用的.FastCGI最近出现了速度差异和安全问题,而且在大多数情况下,PHP也会用尽FastCGI,而不是将其留在Web服务器的核心.
无论是否是这种情况或有其他原因,PHP变得流行,并且已经编写了无数的应用程序.对于大多数只想要一个带有简单博客或照片库的入门级网站的人来说,PHP就是他们所需要的,这就是主机推广的内容.如果你愿意,应该没有什么能阻止你使用Perl(或你选择的任何其他东西).
在企业层面,我怀疑你会在生产中找到太多的PHP(请在Facebook上没有一点作为反例,我说企业级别).
Perl用于网站,例如Python和Ruby.也就是说,PHP的使用方式比任何方式都要多.我认为最重要的因素是PHP的易部署性和易用性.
语法上的差异太多,无法在此总结,但通常它有更多的方式表达自己(这被称为TIMTWOTDI,有多种方法可以做到这一点).
关于Perl我最喜欢的是它处理数组/列表的方式.这是一个如何制作和使用Perl函数(或"子例程")的示例,它将此用于参数:
sub multiply { my ($arg1, $arg2) = @_; # @_ is the array of arguments return $arg1 * $arg2; }
在PHP中你可以做类似的事情list()
,但它并不完全相同; 在Perl列表和数组实际上处理相同(通常).你也可以这样做:
$week_day_name = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")[$week_day_index];
你必须知道的另一个不同之处是数字/字符串比较运算符.在Perl中,如果使用<
,>
,==
,!=
,<=>
,等,Perl的转换两个操作数为数字.如果你想为字符串转换代替,你必须使用lt
,gt
,eq
,ne
,cmp
(运营商各自的等价物前面列出).这将真正让你的例子:
if ("a" == "b") { ... } # This is true. if ("a" == 0) { ... } # This is also true, for the same reason.