【问题标题】:Is PHP compiled or interpreted?PHP 是编译的还是解释的?
【发布时间】:2010-12-03 15:14:15
【问题描述】:

PHP 是编译还是解释?

【问题讨论】:

    标签: php


    【解决方案1】:

    PHP 是一种解释型语言。让您解释 PHP 的二进制文件已编译,但您编写的内容已被解释。

    你可以看到更多on the Wikipedia page for Interpreted languages

    【讨论】:

    • 他的意思是编译了名为php(或windows上的php.exe)的实用程序。
    • @nicky 表示编译了用于解释PHP的程序,但是解释了PHP本身。
    • 但是为什么它在维基百科中这样提到呢? goo.gl/YOwZ 自 PHP 4 起,PHP 解析器编译输入以生成字节码以供 Zend 引擎处理,从而提高了其前身解释器的性能。
    • @kiranvj 它确实是为了提高性能而编译的,但在运行时。将“编译语言”视为“预编译”,将解释语言视为“运行时编译”。这是两者之间的区别: - JIT(“及时”),仅在需要时编译需要的代码(但请注意,在解释器退出后,编译的代码很多) - AOT(“提前”),其中所有代码在运行之前被编译。
    • @kiranvj:我相信 OP 想知道 PHP 是否被编译为本机代码。将其编译为字节码,然后再由 Zend 解释,在编译成本和运行时性能方面处于中间位置。大声笑,这是一个相当老的线程,刚刚意识到它。
    【解决方案2】:

    两者兼而有之。 PHP 被编译成中间字节码,然后由运行时引擎解释。

    PHP 编译器的工作是解析您的 PHP 代码并将其转换为适合运行时引擎的形式。其任务包括:

    • 忽略 cmets
    • 解析变量、函数名等并创建符号表
    • 构建程序的抽象语法树
    • 写入字节码

    根据您的 PHP 设置,此步骤通常只执行一次,即第一次调用脚本时。编译器输出被缓存以加快后续使用的访问。但是,如果修改了脚本,则会再次完成编译步骤。

    在调用脚本时,运行时引擎会遍历 AST 和字节码。符号表用于存储变量的值,并为函数提供字节码地址。

    这种编译成字节码并在运行时解释它的过程对于在某种虚拟运行时机器上运行的语言来说是典型的,包括 Perl、Java、Ruby、Smalltalk 等。

    【讨论】:

    • 变量绑定发生在运行时,而不是编译时。
    • PHP 甚至不尝试在编译时解析哪些名称在范围内?
    • 据我所知,只有 PHP 解释器,也称为运行时。你指的编译器叫什么名字,哪里可以罚款?
    【解决方案3】:

    编译后的代码可以直接由计算机的 CPU 执行。也就是说,可执行代码以 CPU 的本机语言指定。

    解释语言的代码必须在运行时从任何格式翻译成 CPU 机器指令。此翻译由口译员完成。

    说一种语言被解释或编译是不恰当的,因为解释和编译都是该特定语言的实现的属性,而不是该语言的属性 一样。因此,任何语言都可以被编译或解释——它只取决于您使用的特定实现是做什么的。

    使用最广泛的 PHP 实现由 Zend 引擎 提供支持,简称为 PHP。 Zend 引擎将 PHP 源代码编译成它可以执行的格式,因此 Zend 引擎 可以作为 解释器

    【讨论】:

    • "即用CPU的本机语言指定可执行代码" .. 可执行代码不是用CPU的本机语言指定,而是在二进制格式,CPU的本机语言可以是任何东西,当软件二进制文件不像这个CPU或那个CPU那样出现时..完全编译和可执行的代码将是二进制格式..
    • 这是我遇到过的对此事最好的解释之一。当我开始计算机编程时,使用的是解释器 HP BASIC,而且速度相对较慢。多年后,我了解到达特茅斯 BASIC(所有 BASIC 的后续版本都源自于此)总是从一开始就编译,并且在当时的小型计算机系统上运行速度快得多
    【解决方案4】:

    通常它是被解释的,但有些时候可以将它用作编译的,它确实提高了性能。 执行此操作的开源工具: hhvm.com

    【讨论】:

      【解决方案5】:

      PHP 是一种解释型语言。不过,它可以通过第三方工具编译成字节码。

      【讨论】:

      • “字节码”是用于虚拟机特定伪指令的术语,它不是本机的,因此在这种情况下不能被视为“编译”。
      • "object code" 只是 CPU 指令解码器的字节码。 (你不会认为 CPU 实际上有像“CMPSB”这样的本机指令吧?)
      【解决方案6】:

      我知道这个问题很老,但它到处都有联系,我认为这里的所有答案都是不正确的(可能是因为它们太老了)。

      没有解释语言或编译语言之类的东西。任何编程语言都可以被解释和/或编译。

      首先,一种语言只是一组规则,所以当我们谈论编译时,我们指的是该语言的特定实现

      例如,

      HHVM 是 PHP 的一种实现。它使用 JIT 编译将代码转换为中间 HipHop 字节码,然后再翻译成机器码。说它是编译的就足够了吗?一些 Java 实现(不是全部)也使用 JIT。 Google 的 V8 也使用 JIT。

      现在使用编译与解释的旧定义没有意义。

      "PHP 编译了吗?"是一个无意义的问题,因为没有 在什么是编译语言与一个 解释一个。

      一种可能的分隔方式是(我在这种二分法中找不到任何意义):

      编译语言使用 Ahead of Time 编译(C、C++);

      解释型语言使用即时编译或根本不编译(Python、Ruby、PHP、Java)。

      【讨论】:

      • 在大多数情况下,Java 不使用提前编译吗?我是一个相当新的 Java 开发人员,我们通常在运行时之前编译我们的代码。
      • @aCarella in most cases,是的。在所有情况下,不。所以你不能画一条在语义上有意义且同意的线。
      【解决方案7】:

      这是一个毫无意义的问题。 PHP 使用 yacc (bison),就像 GCC。 yacc 是一个“编译器编译器”。 yacc 的输出是一个编译器。编译器的输出是“编译的”。 PHP 由 yacc 的输出解析。因此,根据定义,它是编译的。

      如果不满足,请考虑以下内容。 php(二进制文件)和 gcc 都读取您的源代码并生成抽象语法树。在版本 4 和 5 下,php 然后遍历树将程序转换为字节码(编译步骤)。您可以使用Vulcan Logic Dumper 将字节码转换为操作码(类似于汇编)。最后,php(特别是 Zend 引擎)解释字节码。相比之下,gcc 遍历树并输出程序集;它还可以运行汇编器和链接器来完成该过程。调用由一个“解释”处理的程序和另一个由另一个“编译”处理的程序是没有意义的。毕竟,程序都是通过一个“编译器”运行的。

      您实际上应该问您想问的问题。 (“我是否会因为 PHP 为每个请求重新编译我的源代码而付出性能损失?”等)

      【讨论】:

      • 标记源代码不会编译。甚至 VBScript 也可以被你定义为一种编译语言。
      • 我支持 jrockway,尽管它并没有真正回答 OP 的问题。创建一种语言分类法是很诱人的,在这种分类法中,每种语言都清晰地归入每个类别。但现实并不那么整洁。几乎每一种语言都是各种特征的混合体。此外,当您深入了解它时,甚至本机机器代码也会被处理器“解释”。
      • 您的高级断言是正确的,这一个毫无意义的问题。但是,您的论点不是很有帮助,您所做的只是模糊定义并将它们推向了极端。编译是将源代码转换为目标代码。是的,您可以考虑将源代码转换为具体/抽象语法树的编译,但这不是大多数人的意思吗?无论如何,这是一个毫无意义的问题,因为语言不是固有编译或解释的,语言的实现是编译或解释的。
      • 我们不要忽视这家伙是初学者。这让我将这个问题解释为“Zend 实现是否从 PHP 源代码中生成本机代码?”。看看我的回答。我认为您对提问的方式过于严格。你知道,我们正在努力提供帮助,而不是抨击一些新手。
      • 我完全同意 Sedat。您可以分享您的知识,而不会成为提问者的混蛋
      【解决方案8】:

      至少它不会像人们想要的那样编​​译(或者我应该说优化)代码。

      这段代码...

      for($i=0;$i<100000000;$i++);
      echo $i;
      

      ...每次运行都会延迟程序。

      它可能已经检测到这是一个只需要在第一次完成的计算。

      【讨论】:

      • 现在我们有了一个名为 generators 的选项。
      【解决方案9】:

      请记住,如果每次运行程序都需要源代码,则意味着它正在使用解释器。所以它是一种解释型语言。

      另一方面,如果您编译了源代码并生成了可以执行的编译代码,那么它正在使用编译器。在这里,您不需要源代码。喜欢C、JAVA

      【讨论】:

        【解决方案10】:

        接受的答案是公然错误的。 PHP 已编译。故事结局。也许不是针对本机指令,而是针对解释的字节码。

        【讨论】:

          猜你喜欢
          • 2011-08-05
          • 1970-01-01
          • 1970-01-01
          • 2016-11-19
          • 1970-01-01
          • 2011-07-01
          • 1970-01-01
          • 2020-10-27
          • 2012-08-28
          相关资源
          最近更新 更多