PHPackages                             sj-i/ffi-zts - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sj-i/ffi-zts

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

sj-i/ffi-zts
============

Embed a ZTS PHP interpreter inside an NTS PHP process via FFI and run ZTS-only extensions (e.g. pecl/parallel) from a plain NTS CLI.

v2.0.2(1mo ago)049[1 PRs](https://github.com/sj-i/ffi-zts/pulls)1MITPHPPHP &gt;=8.5,&lt;8.6CI passing

Since Apr 20Pushed 1mo agoCompare

[ Source](https://github.com/sj-i/ffi-zts)[ Packagist](https://packagist.org/packages/sj-i/ffi-zts)[ RSS](/packages/sj-i-ffi-zts/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (7)Dependencies (3)Versions (17)Used By (1)

ffi-zts
=======

[](#ffi-zts)

Add-on ZTS VM for an NTS PHP: a plain non-thread-safe PHP CLI loads `libphp.so` from a thread-safe PHP build through FFI and executes scripts inside that embedded ZTS interpreter -- including scripts that use ZTS-only extensions such as [`pecl/parallel`](https://www.php.net/manual/en/book.parallel.php).

Originally prompted by [adsr/php-meta-sapi#1](https://github.com/adsr/php-meta-sapi/issues/1), which asked whether [adsr/php-meta-sapi](https://github.com/adsr/php-meta-sapi)'s "PHP embedded in PHP" trick can be pushed one step further: use the embedded PHP to pick up ZTS extensions while the outer PHP stays NTS.

The short answer is **yes**, with two small pieces of glue.

Install
-------

[](#install)

```
composer require sj-i/ffi-zts
```

`sj-i/ffi-zts` ships as a **Composer plugin**: on install it downloads the pre-built `libphp.so` matching your host's PHP minor / CPU arch / libc into `vendor/sj-i/ffi-zts/bin/libphp.so`.

Major tracks the host PHP minor: **1.x = PHP 8.4**, **2.x = PHP 8.5**. Composer resolves the right major automatically from your host's `php -v`; the 2.x line picks up upstream's static opcache, which makes `opcache.preload` under the embed work out of the box (see [`docs/PERFORMANCE.md`](docs/PERFORMANCE.md) for measured numbers).

### Trusting the plugin

[](#trusting-the-plugin)

Composer 2.2+ asks you to trust a new plugin before running it. In interactive shells you get a `(y/N)` prompt on first install. In CI / non-interactive environments, whitelist it up front:

```
composer config allow-plugins.sj-i/ffi-zts true
composer require sj-i/ffi-zts
```

If you also install the `sj-i/ffi-zts-parallel` satellite, allow it too:

```
composer config allow-plugins.sj-i/ffi-zts true
composer config allow-plugins.sj-i/ffi-zts-parallel true
composer require sj-i/ffi-zts-parallel
```

### Manual install / retry

[](#manual-install--retry)

If the plugin was skipped (`--no-plugins`, network outage, binary not yet published for a new PHP minor, ...), retry the binary fetch on demand:

```
vendor/bin/ffi-zts install
```

`vendor/bin/ffi-zts info` reports the resolved host profile and tells you whether the binary is in place.

Usage
-----

[](#usage)

```
