Releases: true-async/php-src
Releases · true-async/php-src
PHP 8.6.0 TrueAsync 0.6.7
TrueAsync PHP 0.6.7 (php 8.6)
Highlights
- FrankenPHP on Windows — both Release and Debug builds of FrankenPHP are now produced and shipped alongside the regular PHP artifacts.
- Installer: optional FrankenPHP install — the Windows PowerShell installer now asks (or reads
INSTALL_FRANKENPHP=true) whether to also install FrankenPHP next tophp.exe.
Async extension
Added
- PDO Pool:
getAttribute()support for pool attributes.$pdo->getAttribute(PDO::ATTR_POOL_ENABLED)now returnstrue/falsedepending on whether the connection pool is active.PDO::ATTR_POOL_MINandPDO::ATTR_POOL_MAXreturn the configured pool size limits (orfalsewhen pooling is disabled).PDO::ATTR_POOL_HEALTHCHECK_INTERVALis a construction-only attribute and raises an error if read at runtime.
Fixed
- Heap-use-after-free in
await_all()/await_*()with string keys. When anyawait_*function received an array with non-interned string keys (e.g. fromjson_decode()orstr_repeat()), the returned results/errors arrays had incorrect refcount on those keys. Root cause:async_waiting_callback_disposewas called twice per callback (once fromzend_async_callbacks_removeduringdel_callback, once fromZEND_ASYNC_EVENT_CALLBACK_RELEASE), but did not checkref_count— it unconditionally calledzval_ptr_dtoron the key each time, decrementing the string refcount twice instead of once. When the calling function's local variables were freed (i_free_compiled_variables), the already-freed string was accessed again. Fixed by adding aref_countguard toasync_waiting_callback_dispose: whenref_count > 1, decrement and return without touching resources; cleanup happens only on the final dispose (ref_count == 1).
Windows build
Added
- FrankenPHP support for Windows (Release and Debug). Both build types now produce a slim
*-frankenphp.zipaddon archive containing only FrankenPHP-specific files:frankenphp.exe,libwatcher-c.dll,brotli*.dllandpthreadVC3.dll. The PHP runtime DLL and extensions are not duplicated — extract this archive on top of the main PHP package. - Debug FrankenPHP linkage. FrankenPHP's cgo configuration was split into
cgo_windows.go/cgo_windows_debug.gogated by thezend_debugGo build tag. When building against a debug devel pack, the workflow passes-tags zend_debugso clang sees-DZEND_DEBUG=1, matching the signatures of_emalloc/_efree/_estrdupinphp8ts_debug.lib(which gainZEND_FILE_LINE_DCarguments in debug mode). - Installer: optional FrankenPHP install.
installer/install.ps1now exposes anINSTALL_FRANKENPHPenvironment variable and an interactive "Install FrankenPHP?" prompt. When enabled, the installer downloads the matching slim frankenphp addon archive (respecting the Release/Debug choice), verifies its checksum against the samesha256sums.txt, and extracts it on top of the main install —frankenphp.exelands next tophp.exe.
Fixed
- Clang/MSVC ABI mismatch in
frankenphp_extension.c. Calls toemalloc(sizeof(zval))were routed throughzend_alloc.h's__builtin_constant_pspecialization to_emalloc_16, which MSVC-builtphp8ts.libdoes not export. Replaced withsafe_emalloc(1, sizeof(zval), 0)to hit the exported_safe_emallocentry point. strtok_runresolved on Windows. The Windows CRT has nostrtok_r. Replaced all four call sites infrankenphp_extension.cwithphp_strtok_r(portable wrapper frommain/php_reentrancy.h).- Debug packaging hardcoded release DLL names. The Package FrankenPHP step tried to copy
php8ts.dll, but debug builds shipphp8ts_debug.dll(seewin32/build/confutils.jsPHPLIB). Packaging now globsphp*ts*.dllandphp*ts*.libso both release and debug names work.
Installation
Windows (PowerShell)
irm https://raw.githubusercontent.com/true-async/releases/master/installer/install.ps1 | iexTo also install FrankenPHP non-interactively:
$env:INSTALL_FRANKENPHP="true"; irm https://raw.githubusercontent.com/true-async/releases/master/installer/install.ps1 | iexDocker
docker pull trueasync/php-true-async:0.6.7-php8.6
docker pull trueasync/php-true-async:latestPHP 8.6.0 TrueAsync 0.6.2
What's Changed
Zend Async API
zend_async_new_task_tfactory: New API function type for creating thread pool tasks, registered through the reactor.void *datafield onzend_async_task_t: Generic user data pointer for passing context to thread pool task callbacks.ZEND_ASYNC_NEW_TASK()/ZEND_ASYNC_NEW_TASK_EX()macros: Convenience macros for task creation.zend_async_thread_pool_is_enabled(): Check if thread pool is available.
Streams
- Non-blocking
flock(): Inside coroutines, blocking lock operations (LOCK_SH,LOCK_EX) are offloaded to the libuv thread pool, allowing other coroutines to continue executing while waiting for a file lock.
Full Changelog: php-8.6.0-trueasync-0.6.1...php-8.6.0-trueasync-0.6.2
PHP 8.6.0 TrueAsync 0.6.0 — 2026-03-14
PHP 8.6.0 with TrueAsync 0.6.0 support. This release includes the following changes to the PHP core (Zend engine, streams, and async API).
Added
\Cancellationroot class: New PHP core root class implementing\Throwable(alongside\Exceptionand\Error), added per the True Async RFC. Prevents cancellation exceptions from being accidentally caught bycatch(\Exception)orcatch(\Error)blocks.- Acting coroutine for error context (
zend_async_globals_t.acting_coroutine): When set,zend_get_executed_filename_ex(),zend_get_executed_lineno(), andget_active_function_name()inZend/zend_execute_API.cfall back to the coroutine's suspendedexecute_datafor file, line, and function name. Zero-cost: only read when an error actually occurs. - Async File and Pipe I/O: Non-blocking I/O for plain files and pipes via
php_stdiop_read/php_stdiop_writeasync path. Supported functions:fread,fwrite,fseek,ftell,rewind,fgets,fgetc,fgetcsv,fputcsv,ftruncate,fflush,fscanf,file_get_contents,file_put_contents,file(),copy,tmpfile,readfile,fpassthru,stream_get_contents,stream_copy_to_stream. - Pipe/Stream Read Timeout:
stream_set_timeout()now works for pipe streams (proc_openpipes, TTY). In async mode, timeout is enforced via waker timer competing with IO event — whoever fires first wins.stream_get_meta_data()['timed_out']correctly reports timeout state. - Async IO Seek API:
ZEND_ASYNC_IO_SEEKfor syncing libuv file offset afterfseek/rewind. - Async IO Append Flag:
ZEND_ASYNC_IO_APPENDflag for correct append-mode file offset initialization.
Fixed
- Generator segfault in fiber-coroutine mode: Generators inside fiber coroutines were not marked with
ZEND_GENERATOR_IN_FIBERbecauseEG(active_fiber)is not set in coroutine mode. This caused shutdown destructors to close generators while the coroutine was still suspended, leading to a NULLexecute_datadereference inzend_generator_resume. Fixed by also checkingZEND_ASYNC_CURRENT_COROUTINEwithZEND_COROUTINE_IS_FIBER. stream_select()ignoring PHP-buffered data in async context: Whenfgets()/fread()pulled more data into PHP's internal stream buffer than returned, a subsequentstream_select()would not detect the buffered data because the async path only checks OS-level file descriptors. Fixed by checkingstream_array_emulate_read_fd_set()before entering the async poll path. Resolved hangs inrun-tests.php -jparallel workers on macOS.- Async file IO position tracking: Replaced bare
lseek/_lseeki64withzend_lseekacross the reactor. Fixed append-mode offset init and fseek behavior. On Windows, append writes now query real EOF vialseek(SEEK_END)before dispatch to avoid stale cached offsets.
PHP 8.6.0 TrueAsync alpha.1
PHP 8.6.0 TrueAsync alpha.1
First alpha release of TrueAsync PHP 8.6.0.
This is a pre-release intended for testing. Do not use in production.
Changed
- New
\Cancellationroot class — added to PHP core per the True Async RFC. Implements\Throwablealongside\Exceptionand\Error.Async\AsyncCancellationnow extends\Cancellationinstead of\Error, preventing cancellation exceptions from being accidentally caught bycatch(\Exception)orcatch(\Error)blocks.- Migration: Replace
catch(Async\CancellationError $e)withcatch(Async\AsyncCancellation $e)orcatch(\Cancellation $e).
- Migration: Replace
Fixed
stream_select()ignoring PHP-buffered data in async context — whenfgets()/fread()pulled more data into PHP's internal buffer than returned, a subsequentstream_select()did not detect buffered data because the async path only checks OS-level file descriptors. Caused hangs inrun-tests.php -jparallel workers on macOS. Fixed by checkingstream_array_emulate_read_fd_set()before entering the async poll path.- Waker events not cleaned when coroutine is resumed outside scheduler context — stale event references could accumulate when a coroutine was resumed directly. Now
ZEND_ASYNC_WAKER_CLEAN_EVENTSis called on resume outside the scheduler.
Related repositories
- true-async/php-async — async extension (see its changelog for full 0.6.0 feature list)
- true-async/releases — binary releases and Docker images
True Async 0.2.1 PHP Core
- Compiler warnings for G++ version 11 and above have been fixed.
- A configuration error has also been corrected.