micro 自执行 SAPI 提供了 php“自执行文件”的可能性
你只需要将构建的 micro.sfx 文件与任意 php 文件或者 phar 包拼接(cat 或者 copy /b)为一个文件就可以直接执行这个 php 文件
目前兼容 PHP7.4 与 8.0;兼容 Windows、Linux、macOS。
1.将本仓库clone到php源码的sapi/micro下
# 在php源码目录下 git clone <url for this repo> sapi/micro
2.打patch
patch文件在patches目录下,选择patch文件:
patch文件 | 平台/PHP版本 | 是否必须 | 作用 |
---|---|---|---|
disable_huge_page.patch | Linux | 可选 | 禁用linux构建的max-page-size选项,缩减sfx体积(典型的, 10M+ -> 5M) |
vcruntime140_<php version>.patch | Windows | 必选 | 禁用sfx启动时GetModuleHandle(vcruntime140(d).dll) |
win32_<php version>.patch | Windows | 必选 | 修改构建系统以静态构建 |
zend_stream.patch | Windows | 必选 | 修改构建系统以静态构建 |
phar.patch | * | 可选 | 实现phar的支持 |
并分别进行patch:
# 在php源码目录下 patch -p1 < sapi/micro/patches/<name of patch>
0.参考官方构建说明准备PHP构建环境
1.buildconf
# 在php源码目录下 ./buildconf --force
2.configure
# 在php源码目录下 ./configure <options>
参考的选项:
--disable-phpdbg --disable-cgi --disable-cli --disable-all --enable-micro --enable-phar --with-ffi --enable-zlib
3.make
# 在php源码目录下 make micro
(make all
(或者make
) 或许也可以,但建议还是只构建micro SAPI
生成的文件在 sapi/micro/micro.sfx
0.参考官方构建说明准备PHP构建环境
1.buildconf
# 在php源码目录下 buildconf
2.configure
# 在php源码目录下 configure <options>
参考的选项:
--disable-all --disable-zts --enable-micro --enable-phar --with-ffi --enable-zlib
3.make 由于构建系统的实现问题, Windows下不能使用nmake命令直接构建,使用nmake sfx来构建
# 在php源码目录下 nmake sfx
生成的文件在 <架构名>\<配置名>\micro.sfx
将micro.sfx和php文件拼接即可
例如:myawesomeapp.php内容为
<?php echo "hello, this is my awesome app." . PHP_EOL;
linux下
cat /path/to/micro.sfx myawesomeapp.php > myawesomeapp chmod 0755 ./myawesomeapp ./myawesomeapp # 回显 "hello, this is my awesome app."
或者Windows下
COPY /b \path\to\micro.sfx + myawesomeapp.php myawesomeapp.exe myawesomeapp.exe REM 回显 "hello, this is my awesome app."
linux下php对于hugepages优化导致了生成的文件很大,如果不考虑对hugepages的优化,使用disable_huge_page.patch来来减小文件尺寸
linux下静态构建需要包含c标准库,常见的glibc较大,推荐使用musl,手动安装的musl或者某些发行版会提供gcc(或clang)的musl wrapper:musl-gcc或者musl-clang。在进行configure之前,通过指定CC和CXX变量来使用这些wrapper
例如
# ./buildconf things... export CC=musl-gcc export CXX=musl-gcc # ./configure balabala # make balabala
linux下构建时一般希望是纯静态的,但构建使用的发行版不一定提供依赖的库(zlib libffi等)的静态库版本,这时考虑自行构建依赖库
以libffi为例:
# 通过git获取源码 git clone https://github.com/libffi/libffi cd libffi git checkout <version you like, v3.3 for example> autoreconf -i # 或者直接下载tarball解压 wget <url> tar xf <tar name> cd <extracted name> # 如果使用musl的话 export CC=musl-gcc export CXX=musl-gcc # 构建安装 ./configure --prefix=/my/prefered/path && make -j`nproc` && make install
然后使用以下export命令来构建micro:
# ./buildconf things... # export CC=musl-xxx things... export PKG_CONFIG_PATH=/my/prefered/path/lib/pkgconfig # ./configure balabala # make balabala
microphp 自执行 SAPI micro 自执行 SAPI 提供了 php“自执行文件”的可能性 你只需要将构建的 micro.sfx 文件与任意 php 文件或者 phar 包拼接(cat 或者 copy /b)为一个文件就可以直接执行这个 php 文件 兼容性 目前兼容 PHP7.4 与 8.0;兼容 Windows、Linux、macOS。 构建 准备源码 1.将本仓库clone到ph
在JavaScript中,可以编写这样的自动执行函数: 我希望在Java中实现这一点。例如: 有这样的事吗?
问题内容: 我尝试创建一个eclipse插件,当Eclipse工作台关闭时,该插件会删除一些文件。我从插件项目开始,并添加了一个在此Eclipse关闭钩子中提到的类似符号,它可以终止终止。当我按下Eclipse菜单栏中的特殊按钮(此插件添加)时,将添加侦听器。 如何自动添加它,而无需单击任何菜单项? 问题答案: 使用扩展点来指定要实现的类。这将在Eclipse初始化期间的早期调用。 所以在: 类:
问题内容: 在JavaScript中,可以编写如下的自执行函数: 我正在寻找用Java做到这一点。因此,例如: 有这样的事吗? 问题答案: 该javascript并没有真正创建“自执行”功能。它定义了一个函数,然后立即执行它。 Java不允许您定义独立的函数,因此您无法在Java中执行此操作。但是,您可以声明一个匿名类并立即执行其方法之一: 有时这是通过新线程完成的。就像是: (尽管在很多情况下,
问题内容: 一直在网上搜寻诸如firewatir之类的东西,但搜索python。我正在尝试在Linux上自动执行Firefox。有什么建议么? 问题答案: 该PyXPCOM扩展是一种可能性。 但是,看看firewatir提供的内容,我必须将斜纹的建议换成第二种。它基于mechanize,在这种情况下也可能有用。
本文向大家介绍在Python中自动执行PDF,包括了在Python中自动执行PDF的使用技巧和注意事项,需要的朋友参考一下 使用的模块: 在此脚本中,我们将使用PyPDF2模块,该模块将为我们提供各种功能,例如提取数据,读取pdf文件,拆分文件并写入新文件。 下载PyPDF2: 通用方式:pip安装PyPDF2 Pycharm用户:转到python项目解释器并从那里安装它。 PyPDF2提供的各种
我试图找出CDI和适合我需要的最佳方法。我有一个与普通tcp通信交互的服务()。现在这个服务有一些地方需要通知某人发生了什么事情。对于这些信息,我有接口,需要将其CDI注入到正确的实现中。另一个问题是服务本身被注入一个作业()中,该作业定期执行并调用服务来完成任务。这意味着服务将多次存在。每个都有它处理的另一个tcp连接,并且有另一个需要在接口中注入另一个驱动程序/协议的设备。 让我展示参与此场景
我有一个应用程序在Laravel与.env.local文件(a和我做了下一个docker-comment文件: 还有我的Dockerfile: 我希望克隆存储库,并在docker compose构建时在dockerfile中执行以下操作: 重命名.env.local. env 给存储文件夹权限。我有一个错误在这一行
我正在编写一个定制的ThreadPoolExecutor,具有以下额外功能:- > 如果有理想的线程,并且随着任务的到来,将该任务分配到队列中,而不是将其添加到队列中。 如果所有线程(最大池大小)都忙,则在新任务到来时,使用RejectionHandler的reject方法将它们添加到队列中 我已经重写了线程池执行程序的java 1.5版本的执行方法。 新守则如下:- 遗留代码如下所示:- 现在正