Perl和PHP之间的区别[关闭]


101

我打算学习Perl 5,因为直到现在我都只使用PHP,所以我想对两种语言之间的差异有所了解。

当PHP作为一组“ Perl hacks”开始时,它显然克隆了一些Perls功能。

  • 语法的主要区别是什么?真的,有了Perl,您就有更多的选择和表达方式的方式了吗?

  • 为什么Perl不再经常用于动态网站?是什么使PHP越来越受欢迎?


2
出于好奇,我不得不问:如果您可以自由选择PHP之后的第二语言,为什么选择Perl而不是更现代的Python或Ruby?
jholster 2010年

37
Python和Ruby变得更现代的基础是什么?
约书亚·帕托吉

2
我认为人们不应该尝试比较语言。这只会导致混乱。
本·谢洛克

11
@本:比较语法具有有限的实用程序。比较功能可以帮助学习新语言。
2010年

1
我相信每种语言的力量都是基于设计师的设想; 特别是基于一组用例。因此,比较语言通常会
让人

Answers:


284

Perl和PHP完全不同。让我们考虑一下Perl 5,因为Perl 6仍在开发中。一些差异,大致按主题分组:

  • Perl具有本机正则表达式支持,包括regexp文字。PHP使用Perl的regexp函数作为扩展。
  • Perl有相当多的更多操作符,包括匹配=~!~),报价状qwqx& C),求幂**),串重复x)和范围.....)。PHP有Perl所没有的一些运算符,例如错误抑制运算符@),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具有三个类型,类型说明符是名称的一部分(称为“ 符号 ”),因此$foo@fooor 不同的变量也是如此%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有特殊代码块BEGINUNITCHECKCHECKINITEND),其被执行。与PHP auto_prepend_file和不同auto_append_file,每种类型的代码块的数量没有限制。另外,代码块是在脚本中定义的,而PHP选项是在服务器和每个目录的配置文件中设置的。
  • 在Perl中,分号分隔语句。在PHP中,它会终止它们,但PHP close标记(“?>”)也可以终止一条语句。
  • 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函数)提供了可怕的支持,而对闭包不提供任何支持。
  • PHP直到5.3版才引入了Perl的软件包,后者引入了namespaces
  • 可以说,Perl对异常的内置支持几乎与其他语言中的异常完全不同,以至于它们几乎不像是异常。评价一个块,检查的价值$@eval而不是trydie代替throw)。该错误 尝试::微小的,你发现他们在其他语言模块支持异常(以及在列出的一些其他模块错误的另请参见部分)。

PHP受到Perl的启发,就像《天堂魅影》受到歌剧魅影的启发,或者《怪异啤酒》受到Hamlet的启发一样。在学习Perl时,最好不要考虑PHP的行为细节,否则您会被绊倒。

我的大脑现在很痛,所以我要停下来。


21
这是一个绝妙的答案,我很难在上面做这么细的事情,但是您对Perl数组的看法正确。当你@array = qw(a b c)做的时候$array[4] = 'e',数组的内容并不准确('a', 'b', 'c', undef, 'e'); 他们是('a', 'b', 'c', 不存在的'e')。也就是说,[3]插槽不包含指向undef的标量的指针。它什么也没有容纳(exists操作员对此进行测试)。差异不大,但有所不同。:)
霍布斯

9
伙计,这是我见过的最好的答案之一。特别是关于灵感的部分。简单:很酷,很真实。;)
jm666

2
设置值($foo如果尚未设置)的最短方法可能是isset($foo) || $foo='default';
alexbusu

45

当PHP出现时,每个人都对Perl的主要区别印象深刻:

  1. 输入变量已经在全局范围内,没有无聊的解析。
  2. HTML嵌入。只是<?php ... ?>任何地方。没有无聊的模板。
  3. 屏幕错误消息。没有无聊的错误日志偷看。
  4. 简单易学。没有无聊的书阅读。

随着时间的流逝,每个人都知道他们没有好处,呵呵...


21

我注意到,大多数PHP与Perl页面似乎都是

PHP比Perl更好,因为<在这里插入la脚原因>

之类的,很少进行合理的比较。

在语法方面,您会发现PHP通常比Perl更容易理解,特别是在您经验不足的情况下。例如,在PHP中修剪字符串前后的空格很简单

$string = trim($string);

在Perl中,它有些神秘

$string =~ s/^\s+//;
$string =~ s/\s+$//;

(我相信这比单行捕获和替换要有效得多,并且也更容易理解。)但是,尽管PHP通常更像英语,但它有时仍然可以作为低级C的包装的根源,例如,strpbrk并且strspn可能很少使用,因为大多数PHP涉水者为太深奥的东西编写了自己的等效函数,而不是花时间探索手册。我还想知道那些英语是第二语言的程序员,因为每个人都与Perl等事物并驾齐驱,不得不从头开始学习。

我已经提到了手册。PHP有很好的在线手册,很不幸,它需要它。我仍然会不时提及它,因为它们应该很简单,例如参数顺序或函数命名约定。用Perl,你可能会发现你指的是手动一个不少,你上手,然后有一天,你将有一公顷的时刻,再也不需要它。好吧,至少直到您变得更高级并且意识到不仅有不止一种方法,而且可能还有更好的方法,别人可能已经以这种更好的方法完成了,也许您应该只访问CPAN。

Perl确实有很多选择和表达方式。这不一定是一件好事,尽管如果明智地使用它以及至少一种您可能熟悉的方式,它可使代码更具可读性。您会发现有些样式和习惯用法,我可以衷心推荐阅读Perl Best Practices (较早而不是以后)以及Perl Cookbook,第二版 ,以加快解决常见问题的速度。

我相信Perl在共享主机环境中使用较少的原因是,从历史上看,CGI的速度很慢,并且由于安全和配置问题,主机不愿意安装mod_perl使得PHP成为更具吸引力的选择。然后,这种循环继续进行,更多的人开始学习使用PHP,因为更多的主机提供了PHP,而更多的主机提供了PHP,因为这就是人们想要使用的。如今,FastCGI提出了速度差异和安全性问题,在大多数情况下,PHP也会用尽FastCGI,而不是将其保留在Web服务器的核心中。

不管是这种情况还是其他原因,PHP变得流行起来,并且已经编写了无数的应用程序。对于大多数只希望拥有带有简单博客或图片库的入门级网站的人们来说,PHP就是他们所需要的,因此这就是主机推广的对象。如果需要,没有什么可以阻止您使用Perl(或其他任何选择)。

在企业级别,我怀疑您会在生产中发现太多的PHP(请问,在企业级别上,Facebook只是一个反例)。


2
令人高兴的是,使用FastCGI托管获得托管变得越来越容易,这种托管提供了不错的性能而又没有mod_perl的复杂性。
昆汀2010年

@David Dorward:好的。我讲的是历史意义,因为FastCGI还比mod_php提供更好的性能/安全性。我将对其进行编辑,以使其更加清晰。
邓肯

3
您的修剪示例没有任何意义。什么更好的运营商4或记住所有的所有PHP功能,如额日格ereg_replace eregi eregi_replace mb_ereg mb_ereg_replace mb_eregi mb_eregi_replace的preg_match preg_match_all的preg_replace str_replace函数str_ireplace的strstr stristr strrchr strpos stripos函数strrpos strripos mb_strpos mb_strrpos不一致的参数和返回值的
Myforwik

3
您的Perl修剪示例可能更简单:$str =~ s/^\s+|\s+$//g;
Francisco Zarabozo 2014年

1
@Myforwik,我的修饰示例旨在证明Perl缺乏明显的功能,这可能会使初学者感到困惑。一旦学会了语法,是的,它比处理所有不一致要容易得多-我也指出了不断需要手册的意义。
Duncan

9

Perl在网站上使用很多,例如Python和Ruby。也就是说,PHP的使用方式比其他任何一种都多。我认为其中最重要的因素是PHP的易于部署以及从入门开始的难易程度。

语法上的差异太多了,在这里不能一概而论,但是总的来说,它有更多表达自己的方式(这被称为TIMTWOTDI,有多种方法可以实现)。


9

关于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的转换两个操作数为数字。如果你想为字符串转换代替,你必须使用ltgteqnecmp(运营商各自的等价物前面列出)。可以真正帮助您的示例:

if ("a" == "b") { ... } # This is true.
if ("a" == 0) { ... } # This is also true, for the same reason.

数组和列表通常被视为相同。
布拉德·吉尔伯特

是的,没错。我想我会这么说,但是忘了。编辑以反映这一点。
crimson_penguin 2010年

4

我不需要在outis出色的答案中添加任何内容,我只想为您显示答案即可:

为什么Perl不再经常用于动态网站?是什么使PHP变得比它更受欢迎?

请首先检查一些“工作趋势”网站-您可以独自做出判断。

如您所见,perl仍然是领导者-但对于实际应用而非玩具更可取。:)


1
我认为这种比较也很有趣:www.simplyhired.com/a/jobtrends/trend/q-Perl,+Python,+PHP,+Ruby,+Java,+C%23,+C
Sorin Postelnicu 2012年

1
固定的链路中断,请使用:simplyhired.com/...
R4。

SH.com/a/jobtrends似乎不存在。请使用:simplyhired.com/search?q=Perl%2C%2BPython%2C%2BPHP%2C%2BRuby
r4。

@ r4。您的链接与原始(现已断开)链接不同。原始显示的是图表(如上图),而不是一些工作清单。职位列表链接不在范围内。
jm666
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.