你能“编译”PHP 代码并上传一个二进制文件,它只会由字节码解释器运行吗?
Posted
技术标签:
【中文标题】你能“编译”PHP 代码并上传一个二进制文件,它只会由字节码解释器运行吗?【英文标题】:Can you "compile" PHP code and upload a binary-ish file, which will just be run by the byte code interpreter? 【发布时间】:2010-11-27 08:42:15 【问题描述】:我知道 php 在服务器上运行之前会被编译为字节码,然后可以缓存该字节码,这样就不必在每次 Web 访问时重新解释整个脚本。
但是
【问题讨论】:
相关问题:PHP compiler for Windows 请不要使用hhvm 或hiphop 标记此内容。 HHVM 不是问题的固有部分,只是一个可能的答案。 meta.stackexchange.com/a/149347/238706 @HalayemAnis 我认为您提到了错误的链接。您能否提供该教程的正确链接?或任何最新的更新家伙? @CJRamki 抱歉,请使用此链接COMPILE_PHP 这个问题其实比较模糊。您可以“简单地”构建一个 PHP 编译器,将您的源代码和 PHP 解释器编译(最完整的含义)成 ELF、EXE 或其他。 【参考方案1】:在提出这个问题后,Facebook 推出了 HipHop for PHP,这可能是迄今为止经过最佳测试的 PHP 编译器(因为它运行着全球 10 大网站之一)。然而,Facebook 停止使用它,转而支持 HHVM,它是一种虚拟机,而不是编译器。
除此之外,谷歌搜索 PHP compiler
会发现许多第三方解决方案。
PeachPie
PeachPie GitHub 将 PHP 编译为 .NET 和 .NET Core 可以编译成独立的二进制文件 在 Mac、Linux、Windows、Windows Core、ARM 上运行...Phalanger
GitHub(下载),Wikipedia 编译为 .NET (CIL) 看起来已于 2017 年 7 月停止,并且似乎不支持 PHP 7。phc
编译为本机二进制文件 现在不太活跃(2014 年 2 月)- 2011 年的最后一个版本,2013 年夏季的最后一次更改Roadsend PHP Compiler
GitHub, GitHub of a rewrite 带有编译器的 PHP 的免费开源实现 编译为本机二进制文件(Windows、Linux) discontinued since 2010 till contributors found – 网站关闭,留在 GitHub 上,最后一次更改是从 2012 年初开始bcompiler
PHP 的 PECL 扩展 实验性 编译为 PHP 字节码,但可以将其包装在加载 PHP 解释器的 Windows 二进制文件中(参见bcompiler_write_exe_footer()
manual)
现在看起来已停产(2014 年 2 月)- 2011 年的最后一次更改
Project Zero
Wikipedia, IBM WebSphere sMash 变更的孵化器 受 IBM 支持 编译成 Java 字节码 现在看起来已停产(2014 年 2 月)- 网站关闭,看起来像是 2008 年和 2009 年的大肆宣传Bambalam
编译为独立的 Windows 二进制文件 二进制文件包含字节码和启动器 现在看起来已停产(2014 年 2 月)- 2006 年的最后一次更改BinaryPHP
编译为 C++ 现在看起来已停产(2014 年 2 月)- 2003 年的最后一次更改【讨论】:
共享虚拟主机怎么样?我可以用其中一种编译器编译我的 PHP 脚本,然后上传到基于 linux 的网络主机吗? @sємsєм 这取决于您的主机,但如果我不得不猜测,我猜很多主机不会允许它。 以上这些项目似乎都不再维护了。自过去 2 年以来是否存在普遍接受的编译器,或者为什么所有这些项目都被忽视/放弃? nice list of PHP compilers 位于 thefreecountry.com。此处提到的所有工具现在都包含在此答案中。 既然这些似乎都死了,答案似乎是“不”。【参考方案2】:简短的回答是“不”。
PHP 的当前实现是一种解释性语言。您可以争论任何语言在技术上都可以解释或编译这一事实的理论方面,但就目前而言,当前的实现是 PHP 代码需要解释器才能运行,而解释器管理执行环境。
要回答有关上传预编译 PHP 字节码的问题,这可能是可行的,但您必须实现一种方法,让 PHP 解释器读取此类文件并使用它。有了现有的操作码缓存,这似乎不是一项能获得太多回报的任务。
【讨论】:
通常情况下,您确实需要一个解释器才能正确运行 PHP 程序,但这并不意味着编译器不能在编译后的代码中提供它。 phc (phpcompiler.org) 处理您描述的所有问题。据我所知,Roadsend (roadsend.com) 也是如此。 此答案已过时 - HipHop 于 2010 年 2 月发布 6 个月后发布。 @FrankFarmer 你有玩 HipHop 的经验吗? HipHop 能否与include
和require
一起正常工作?例如,如果 PHP 脚本通常包含在 include( 'controller/' . $controller_name . '.php' )
中,这会自动与 HipHop 一起使用吗?干杯
实际上您可以使用常规的 PHP 编译器编译 PHP 代码。它只取决于目标平台;您可以编译成 Zend 操作码、C 语言或 .NET 程序集(使用 Phalanger php-compiler.net)
The short answer is "no". The current implementation of PHP is that of an interpreted language. You can argue the theoretical aspects…
没有什么理论依据,很多解释语言都有编译器;即 AutoIt/AutoHotkey,甚至可以追溯到 BASIC。有很多程序是用其中编写的,然后编译供公众作为独立程序使用。 PHP 并没有什么特别之处可以防止它被编译,这就是为什么存在一堆编译器的原因,但与 AHK 不同的是,没有经过测试的官方编译器——Zend Guard 不算。【参考方案3】:
自从第一次提出这个问题以来,这个答案已经从一个完全“不”变成了“有点”
http://github.com/facebook/hiphop-php/wiki
Hip Hop for PHP 是一个编译器,它将 PHP 代码转化为高度优化的 C++ 显然,不支持某些功能(例如'explode')
我在寻找有关如何实施 HipHop 的更多信息时发现了这个问题,并认为我会说出来 :)
然而,自 2013 年以来,Facebook 不再使用它,并且已经停止使用它,支持 HHVM,它不是编译器:https://en.wikipedia.org/wiki/HipHop_for_PHP
【讨论】:
我相信这是 facebook 使用的 “那种”现在已经落后了几年,并且由于 HHVM (HipHop Php) 每天都在变得越来越好,最终有一种方法(我认为)。使用 HHVM 现在可以pre-analyze
php 代码。结果你得到一个二进制缓存文件。有了这个文件和正确的 HHVM 配置,就可以只用字节码运行网页,不再需要源文件;)我希望我做对了。
@Andrea,HHVM 被弃用是什么意思?它看起来像一个项目一样被维护和活着。还是您的意思是名称从 PHP 的 Hip Hop 更改为 HHVM?然后谈论弃用是误导。
@Palec HipHop for PHP 已停产。它是 Facebook 使用的 PHP-to-C++ 编译器,但它产生的输出很笨重(多 GB 的二进制文件)并且不支持完整的语言。 HHVM 是一个后继项目,它共享一些相同的代码,但不是编译器。 HHVM 是一个虚拟机。 Facebook 不再支持 HipHop。【参考方案4】:
还有
PHP's (experimental) bcompiler extension,目标
在专有的 PHP 应用程序中编码整个脚本 在专有的 PHP 应用程序中编码某些类和/或函数 启用可在客户端桌面上使用的 php-gtk 应用程序的生产,而无需 php.exe。 进行 PHP 到 C 转换器的可行性研究
扩展程序可从 PECL 获得。
【讨论】:
【参考方案5】:phc允许您将PHP程序编译成共享库,可以上传到服务器。 PHP 程序被编译成二进制文件。它以支持eval
s、include
s 和整个 PHP 标准库的方式完成。
【讨论】:
【参考方案6】:嗯,任何人都听说过Zend Guard,这正是这个人所要求的。它将 PHP 代码编码/混淆为“机器代码”。
【讨论】:
我认为他们不希望混淆,而是希望通过字节码而不是源代码来实现加速。 @Stephen Zend Guard 也打算这样做。 Zend Guard 决定不支持 PHP 7,这是一个缺点 - blog.zend.com/2016/10/10/zend-guard-and-php-7/#.W7YISnszaM8【参考方案7】:如果您只是想从 PHP 脚本生成二进制可执行文件,那么请避免试图让您的问题非常精确,因为这会让您看起来很清楚自己需要什么。此外,大多数 PHP 开发人员对字节码是什么一无所知。
话虽如此,答案是YES。我刚刚将 PHP 脚本编译成二进制文件。而不仅仅是任何二进制文件。我使用了CDE application(链接到 Wayback Machine,original link 现在已损坏)将其转换为可移植的二进制文件,可以与所有依赖项一起分发并毫无问题地执行……它运行良好。
您只需使用phc。
【讨论】:
【参考方案8】:有几个 PHP 代码的“编译器”。它们中的大多数不支持所有 PHP 特性,因为这些特性必须在运行时进行解释。
我们正在使用 Phalanger - http://www.php-compiler.net/ - 它甚至支持那些肮脏的 PHP 动态特性,并且仍然能够将它们编译为 .NET 程序集,可以作为独立的 DLL 分发。
【讨论】:
【参考方案9】:查看 5.5.x 与集成的 OPcache 模块,在共享内存中易失性,更多的性能和 php 的动态原理保持不变。
http://www.php.net/manual/en/opcache.installation.php
【讨论】:
【参考方案10】:在 php 7 中有一个 php ini 选项 opcache.file_cache 将字节码保存在特定文件夹中。 In 可能对“编译”并保存在特定文件夹中以优化重用的 php cli 脚本很有用。
Opcache 它没有编译,但类似。
【讨论】:
“在 php 7 中”它不仅仅是 PHP7,它是 PHP 5.5.0 及更高版本【参考方案11】:如果允许您运行真正的本机二进制文件,那么这就是您的编译器:
https://github.com/ircmaxell/php-compiler
这是一个 PHP 编译器用 PHP 编写!
它将 PHP 代码编译为自己的 VM 代码。然后,这个 VM 代码可以由它自己的解释器解释(也是用 PHP 编写的,不是很疯狂吗?),或者它可以被翻译成 Bitcode。并且使用LLVM compiler framework(clang
和 co),可以将此 Bitcode 编译为 LLVM 支持的任何平台(几乎是当今重要的任何平台)的本机二进制文件。您可以选择静态执行此操作,也可以选择每次在代码执行之前执行此操作(JIT 样式)。所以这个编译器在你的系统上工作的唯一两个要求是一个安装的 PHP 解释器和一个安装的 clang
编译器。
如果您不允许运行本机二进制文件,您可以使用上面的编译器作为解释器并让它解释自己的 VM 代码,但这会很慢,因为您正在运行一个本身在 PHP 上运行的 PHP 解释器引擎,所以你有一个“双重解释”。
【讨论】:
【参考方案12】:PHP 并没有像许多程序那样真正被编译。不过,您可以使用 Zend 的编码器使其不可读。
【讨论】:
它的编译方式和 perl 的编译方式不同吗? 我相信 PHP 是在服务器上即时编译的。不过,我使用了编码器来隐藏源代码。如果这就是你所担心的。他们工作得很好。 不,我只是对它的理论方面感兴趣 PHP 没有被编译,它是一种解释性语言。缓存包含 php 解释的“操作码”(不必读取文本),php 代码不能像使用 c 那样直接“运行”【参考方案13】:还有 bcgen(bcompiler 的 PHP7 端口):
https://github.com/vjardin/bcgen/
(仅限 PHP7.2)
【讨论】:
【参考方案14】:实际上,PHP 8 中引入的 Just-In-Time 编译器确实可以编译 PHP。奇怪的是,它并没有真正加速基于 CMS 的网站(例如 WordPress),但是,它确实为 PHP 与 C++ 等竞争打开了大门。有关更多信息,请参阅此处的 JIT 实现背后的 RFC:https://wiki.php.net/rfc/jit。此外,Matthew Weir O'Phinney 发布了许多有见地的博客,阐明了其功能。从这里开始阅读:https://www.zend.com/blog/exploring-new-php-jit-compiler。
【讨论】:
以上是关于你能“编译”PHP 代码并上传一个二进制文件,它只会由字节码解释器运行吗?的主要内容,如果未能解决你的问题,请参考以下文章