如何在 CLI 中加载 pthreads 扩展?

How Do I load pthreads extension in CLI?

我在 MAC OSX 10.11.

上从源代码构建了 php 和 Apache

我在 CLI 中加载 pthreads 扩展时遇到问题。我误解了如何加载它,现在我并不真正理解我应该做什么。

这是我到目前为止所做的。

我使用以下命令配置了 php:

'./configure' 
'--prefix=/Users/username/Terminal/WebServer'
'--with-apxs2=/Users/username/Terminal/WebServer/bin/apxs'
'--enable-maintainer-zts' 
'--enable-pthreads=shared' 
'--enable-debug' 
'--with-tsrm-pthreads' 
'--with-config-file-path=/Users/username/Terminal/WebServer/ini' 
'--enable-cli'

Apache 加载的模块:

Compiled in modules:
  core.c
  mod_so.c
  http_core.c
  worker.c

所以,在/Users/username/Terminal/WebServer/ini目录下我创建了php-cli.ini文件并添加了extension=pthreads.so行,然后我运行php -m命令,下面是输出:

[PHP Modules]
Core
ctype
date
dom
fileinfo
filter
hash
iconv
json
libxml
pcre
PDO
pdo_sqlite
Phar
posix
<strong>pthreads</strong>
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter

[Zend Modules]

我重新启动了 Apache 并打开了 index.php 文件,其中包含 phpinfo()
值得注意的信息

Configuration File (php.ini) Path => /Users/username/Terminal/WebServer/ini
Loaded Configuration File => /Users/username/Terminal/WebServer/ini/php.ini
Scan this dir for additional .ini files => (none)
Additional .ini files parsed => (none)
Thread Safety => Enabled

phpinfo() 不包括 pthreads 模块信息,我不知道是否应该。
此时我打开 test.php 文件,其中包含以下 pthreads 脚本:

<?php $thread = new class extends Thread {
    public function run() {
        echo "Hello World\n";
    }
};

$thread->start() && $thread->join();
?>

通过 apache 的输出是:

Fatal error: Class 'Thread' not found in /Users/username/Sites/test.php on line 1


当我 运行 在终端上执行以下命令时
$ php /Users/username/Sites/test.php

输出为:Hello World

所以问题是如何在 CLI 中正确加载 pthreads 扩展?

您已经有了想要的结果,但似乎不知道为什么...

配置的关键部分是:

configure 选项

如果PHP是用Apache DSO SAPI构建的,你必须使用--enable-pthreads=shared,这会导致构建过程创建一个DSO(共享对象,dll在windows讲)来自 pthreads 库,而不是将 pthreads 静态链接到 Apache DSO。

php.ini配置

来自PHP manual:

If php-SAPI.ini exists (where SAPI is the SAPI in use, so, for example, php-cli.ini or php-apache.ini), it is used instead of php.ini. The SAPI name can be determined with php_sapi_name().

构建了共享的 pthreads (pthreads.so),我们可以简单地在与 php.ini 相同的路径中创建 php-cli.ini 并向其添加 extension=pthreads.so


你有什么用,但是,它并不理想;您真的不希望 Apache 使用具有 ZTS 开销的 PHP 解释器。

理想情况下,您需要构建和安装 PHP 两次:

首次构建

configure --with-apxs=... --disable-pthreads --prefix=/system/prefix --with-config-file-path=/system/prefix/etc ...

/system/prefix/ 替换为合理的系统前缀,例如 /usr/ ...

当您 make install 此构建时,您将为 Apache 创建理想的安装,其中包括 /system/prefix/bin/php 的非线程安全 PHP 二进制文件,以及所有相关脚本(peclphpizephp-config 等)在 /system/prefix/bin.

第二次构建

在此构建之前,您需要 make clean(如果您使用的是发布压缩包),或 vcsclean(如果您使用的是本地 git 存储库)。

configure --enable-maintainer-zts --enable-pthreads=static --prefix=/special/prefix --with-config-file-path=/special/prefix/etc ...

/special/prefix/替换为合理的特殊前缀,如/opt/,不要使用与第一个构建相同的前缀...

当您 make install 未触及第一个安装时,将创建一个不支持 Apache 的新安装,但支持静态内置到二进制文件中的 pthreads(无配置)。

二进制文件位于 /special/prefix/bin/php,所有相关脚本位于 /special/prefix/bin

布线一起构建

如果两个构建都需要相同的 PECL 扩展(pthreads 除外),您可以对两个构建使用相同的 --with-config-file-scan-dir 配置开关。

如果你真的很勇敢,你也可以使用相同的 --with-config-file-path 开关,但这可能会产生意想不到的结果。

为两个版本编辑 include_path 也会有所帮助。