Update docs for FFI and dynamic loading extensions (#629)

This commit is contained in:
Jerry Ma 2025-03-13 11:56:40 +08:00 committed by GitHub
parent d643051759
commit a6b843f4dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 19 deletions

View File

@ -16,13 +16,29 @@ The directory can be changed using the manual build option `--with-config-file-s
## Can statically-compiled PHP install extensions? ## Can statically-compiled PHP install extensions?
Because the principle of installing extensions in PHP under the traditional architecture is to install new extensions using `.so` type dynamic link libraries, Because the principle of installing PHP extensions under the normal mode is to use `.so` type dynamic link library to install new extensions,
and statically linked PHP compiled using this project cannot **directly** install new extensions using dynamic link libraries. and we use the static link PHP compiled by this project. However, static linking has different definitions in different operating systems.
For the macOS platform, almost all binary files under macOS cannot be linked purely statically, First of all, for Linux systems, statically linked binaries will not link the system's dynamic link library.
and almost all binary files will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`. Purely statically linked binaries (`build with -all-static`) cannot load dynamic libraries, so new extensions cannot be added.
So under macOS system, statically compiled php binary files can be used under certain compilation conditions, At the same time, in pure static mode, you cannot use extensions such as `ffi` to load external `.so` modules.
and dynamic link extensions can be used at the same time:
You can use the command `ldd buildroot/bin/php` to check whether the binary you built under Linux is purely statically linked.
If you [build GNU libc based PHP](../guide/build-with-glibc), you can use the `ffi` extension to load external `.so` modules and load `.so` extensions with the same ABI.
For example, you can use the following command to build a static PHP binary dynamically linked with glibc,
supporting FFI extensions and loading the `xdebug.so` extension of the same PHP version and the same TS type:
```bash
bin/spc-gnu-docker download --for-extensions=ffi,xml --with-php=8.4
bin/spc-gnu-docker build --libc=glibc ffi,xml --build-cli --debug
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
```
For macOS platform, almost all binaries under macOS cannot be truly purely statically linked, and almost all binaries will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
So on macOS, you can use statically compiled PHP binaries under certain compilation conditions, and dynamically linked extensions:
1. Using the `--no-strip` parameter will not strip information such as debugging symbols from the binary file for use with external Zend extensions such as `Xdebug`. 1. Using the `--no-strip` parameter will not strip information such as debugging symbols from the binary file for use with external Zend extensions such as `Xdebug`.
2. If you want to compile some Zend extensions, use Homebrew, MacPorts, source code compilation, and install a normal version of PHP on your operating system. 2. If you want to compile some Zend extensions, use Homebrew, MacPorts, source code compilation, and install a normal version of PHP on your operating system.
@ -34,15 +50,12 @@ and dynamic link extensions can be used at the same time:
bin/spc build ffi --build-cli --no-strip bin/spc build ffi --build-cli --no-strip
``` ```
For the Linux platform, the current compilation result is a purely statically linked binary file,
and new extensions cannot be installed using a dynamic link library.
## Can it support Oracle database extension? ## Can it support Oracle database extension?
Some extensions that rely on closed source libraries, such as `oci8`, `sourceguardian`, etc., Some extensions that rely on closed source libraries, such as `oci8`, `sourceguardian`, etc.,
they do not provide purely statically compiled dependent library files (`.a`), only dynamic dependent library files (`.so`). they do not provide purely statically compiled dependent library files (`.a`), only dynamic dependent library files (`.so`).
These extensions cannot be compiled into static-php-cli from source, so this project may never support them. These extensions cannot be compiled into static-php-cli using source code, so this project may never support these extensions.
However, in theory, you can access and use such extensions under macOS according to the above questions. However, in theory you can access and use such extensions under macOS and Linux according to the above questions.
If you have a need for such extensions, or most people have needs for these closed-source extensions, If you have a need for such extensions, or most people have needs for these closed-source extensions,
see the discussion on [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58). Welcome to leave a message. see the discussion on [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58). Welcome to leave a message.
@ -75,6 +88,8 @@ such as Swoole Compiler, Source Guardian, etc.
## Unable to use ssl ## Unable to use ssl
**Update: This issue has been fixed in the latest version of static-php-cli, which now reads the system's certificate file by default. If you still have problems, try the solution below.**
When using curl, pgsql, etc. to request an HTTPS website or establish an SSL connection, there may be an `error:80000002:system library::No such file or directory` error. When using curl, pgsql, etc. to request an HTTPS website or establish an SSL connection, there may be an `error:80000002:system library::No such file or directory` error.
This error is caused by statically compiled PHP without specifying `openssl.cafile` via `php.ini`. This error is caused by statically compiled PHP without specifying `openssl.cafile` via `php.ini`.

View File

@ -123,8 +123,8 @@ For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use
## ffi ## ffi
1. Linux not supported yet: Due to limitations of the Linux system, although the ffi extension can be compiled successfully, it cannot be used to load other `so` extensions. 1. Due to the limitation of Linux system, you cannot use it to load other `so` extensions in the purely static compiled state (spc defaults to pure static compilation).
The prerequisite for Linux to support loading `so` extensions is dynamic compilation, but dynamic compilation conflicts with the purpose of this project. Linux supports loading so extensions only if they are non-statically compiled. If you need to use the ffi extension, see [Compile PHP with GNU libc](./build-with-glibc).
2. macOS supports the ffi extension, but errors will occur when some kernels do not contain debugging symbols. 2. macOS supports the ffi extension, but errors will occur when some kernels do not contain debugging symbols.
3. Windows x64 supports the ffi extension. 3. Windows x64 supports the ffi extension.

View File

@ -16,10 +16,26 @@ PHP 默认也会从 [其他标准位置](https://www.php.net/manual/zh/configura
## 静态编译的 PHP 可以安装扩展吗 ## 静态编译的 PHP 可以安装扩展吗
因为传统架构下的 PHP 安装扩展的原理是使用 `.so` 类型的动态链接的库方式安装新扩展,而使用本项目编译的静态链接的 PHP 无法**直接**使用动态链接库安装新扩展。 因为传统架构下的 PHP 安装扩展的原理是使用 `.so` 类型的动态链接的库方式安装新扩展,而使用本项目编译的静态链接的 PHP。但是静态链接在不同操作系统有不同的定义。
首先对于 Linux 系统来说,静态链接的二进制文件是不会链接系统的动态链接库的,纯静态链接的二进制无法加载动态库,所以无法添加新的扩展。
同时,在纯静态模式下你也不能使用 `ffi` 等扩展加载外部的 `.so` 模块。
你可以通过命令 `ldd buildroot/bin/php` 来查看你在 Linux 下构建的二进制是否为纯静态链接的。
如果你 [构建 GNU libc 兼容的 PHP](../guide/build-with-glibc),你可以使用 `ffi` 扩展加载外部的 `.so` 模块,并且加载具有相同 ABI 的 `.so` 扩展。
例如,你可以使用以下命令构建一个 glibc 动态链接的静态 PHP 二进制,同时支持 FFI 扩展和加载相同 PHP 版本和相同 TS 类型的 `xdebug.so` 扩展:
```bash
bin/spc-gnu-docker download --for-extensions=ffi,xml --with-php=8.4
bin/spc-gnu-docker build --libc=glibc ffi,xml --build-cli --debug
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
```
对于 macOS 平台来说macOS 下的几乎所有二进制文件都无法真正纯静态链接,几乎所有二进制文件都会链接 macOS 的系统库:`/usr/lib/libresolv.9.dylib``/usr/lib/libSystem.B.dylib` 对于 macOS 平台来说macOS 下的几乎所有二进制文件都无法真正纯静态链接,几乎所有二进制文件都会链接 macOS 的系统库:`/usr/lib/libresolv.9.dylib``/usr/lib/libSystem.B.dylib`
所以在 macOS 系统下,在特定的编译条件下可以使用静态编译的 php 二进制文件,同时使用动态链接的扩展: 所以在 macOS 系统下,在特定的编译条件下可以使用静态编译的 php 二进制文件,使用动态链接的扩展:
1. 使用 `--no-strip` 参数,将不会对二进制文件去除调试符号等信息,以供使用 `Xdebug` 等外部 Zend 扩展。 1. 使用 `--no-strip` 参数,将不会对二进制文件去除调试符号等信息,以供使用 `Xdebug` 等外部 Zend 扩展。
2. 如果要编译某些 Zend 扩展,使用 Homebrew、MacPorts、源码编译的形式在所在的操作系统安装一个普通版本的 PHP。 2. 如果要编译某些 Zend 扩展,使用 Homebrew、MacPorts、源码编译的形式在所在的操作系统安装一个普通版本的 PHP。
@ -31,12 +47,10 @@ PHP 默认也会从 [其他标准位置](https://www.php.net/manual/zh/configura
bin/spc build ffi --build-cli --no-strip bin/spc build ffi --build-cli --no-strip
``` ```
对于 Linux 平台来说,目前的编译结果为纯静态链接的二进制文件,无法使用动态链接库安装新扩展。
## 可以支持 Oracle 数据库扩展吗 ## 可以支持 Oracle 数据库扩展吗
部分依赖库闭源的扩展,如 `oci8``sourceguardian` 等,它们没有提供纯静态编译的依赖库文件(`.a`),仅提供了动态依赖库文件(`.so` 部分依赖库闭源的扩展,如 `oci8``sourceguardian` 等,它们没有提供纯静态编译的依赖库文件(`.a`),仅提供了动态依赖库文件(`.so`
这些扩展无法使用源码的形式编译到 static-php-cli 中,所以本项目可能永远也不会支持这些扩展。不过,理论上你可以根据上面的问题在 macOS 下接入和使用这类扩展。 这些扩展无法使用源码的形式编译到 static-php-cli 中,所以本项目可能永远也不会支持这些扩展。不过,理论上你可以根据上面的问题在 macOS 和 Linux 下接入和使用这类扩展。
如果你对此类扩展有需求,或者大部分人都对这些闭源扩展使用有需求, 如果你对此类扩展有需求,或者大部分人都对这些闭源扩展使用有需求,
可以看看有关 [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58) 的讨论。欢迎留言。 可以看看有关 [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58) 的讨论。欢迎留言。
@ -62,6 +76,8 @@ PHP 代码的编译器是完全不同的项目,因此不会考虑额外的情
## 无法使用 ssl ## 无法使用 ssl
**更新:该问题已在最新版本的 static-php-cli 中修复,现在默认读取系统的证书文件。如果你仍然遇到问题,再尝试下方的解决方案。**
使用 curl、pgsql 等 请求 HTTPS 网站或建立 SSL 连接时,可能存在 `error:80000002:system library::No such file or directory` 错误, 使用 curl、pgsql 等 请求 HTTPS 网站或建立 SSL 连接时,可能存在 `error:80000002:system library::No such file or directory` 错误,
这个错误是由于静态编译的 PHP 未通过 `php.ini` 指定 `openssl.cafile` 导致的。 这个错误是由于静态编译的 PHP 未通过 `php.ini` 指定 `openssl.cafile` 导致的。

View File

@ -113,7 +113,7 @@ pgsql 16.2 修复了这个 Bug现在正常工作了。
## ffi ## ffi
1. 因为 Linux 系统的限制,虽然可以成功编译 ffi 扩展,但无法使用它加载其他 `so` 扩展。Linux 支持加载 so 扩展的前提是非静态编译,但动态编译和本项目的目的冲突 1. 因为 Linux 系统的限制,纯静态编译的状态下spc 默认编译结果为纯静态)无法使用它加载其他 `so` 扩展。Linux 支持加载 so 扩展的前提是非静态编译。如果你需要使用 ffi 扩展,请参见 [编译 GNU libc 的 PHP](./build-with-glibc)
2. macOS 支持 ffi 扩展,但是部分内核下不包含调试符号时会出现错误。 2. macOS 支持 ffi 扩展,但是部分内核下不包含调试符号时会出现错误。
3. Windows 支持 ffi 扩展。 3. Windows 支持 ffi 扩展。