Runtime Hooks allow Swoole to listen for internal PHP API calls, take control and execute your code in a non-blocking way, allowing us to use well known and tested libraries like the PDO extension or the CURL library. The benefit of using hooks is it allows us to use existing PHP ecosystem tools and libraries and not force us to use any coroutine specific clients, instead Swoole aims to support the existing ecosystem. Even native blocking PHP functions like sleep
or file_get_contents
are supported, so it is easy to adopt coroutine throughout your application without much change to your existing codebase.
When hooks are enabled, Swoole will take care of the coroutine scheduling for you under the hood, you don't need to write any additional logic with runtime hooks once they are setup and enabled. Hooks are required to run inside a coroutine context, this means you must use enabled hook functionality within a Co\run
or inside a Swoole Server request where the coroutine context is created for you for each request.
Version: Swoole: 4.1.0+
Since Swoole v4.1.0, you can use any IO libraries based on php_stream
within a coroutine context.
Libraries with coroutine support:
phpredis
) or (predis
)mysqlnd
) PDO and MySQLifile_get_contents
, fopen
and many more file I/O operationsstream_socket_client
functionsfsockopen
libcurl
Libraries without coroutine support:
libmysqlclient
mongo-c-client
pdo_pgsql
, pdo_ori
, pdo_odbc
, pdo_firebird
, php-amqp
You can enable coroutine support with HOOK Flags:
SWOOLE_HOOK_ALL
SWOOLE_HOOK_SLEEP
SWOOLE_HOOK_FILE
SWOOLE_HOOK_CURL
SWOOLE_HOOK_NATIVE_CURL
SWOOLE_HOOK_TCP
SWOOLE_HOOK_UDP
SWOOLE_HOOK_UNIX
SWOOLE_HOOK_UDG
SWOOLE_HOOK_PROC
SWOOLE_HOOK_SSL
SWOOLE_HOOK_TLS
SWOOLE_HOOK_STREAM_FUNCTION
SWOOLE_HOOK_BLOCKING_FUNCTION
SWOOLE_HOOK_SOCKETS
SWOOLE_HOOK_STDIO
<?php
Swoole\Runtime::enableCoroutine(bool $enable = true, int $flags = SWOOLE_HOOK_ALL);
The code above will enable coroutine support for all Swoole Hooks, you can change which hooks you want to enable but it is likely better for performance to enable them all and take advantage of coroutines.
The enableCoroutine
call should be placed at the start of your script or at least before any Co\run
or server is used, this so that you can obtain 100% coverage.
<?php
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL | SWOOLE_HOOK_CURL);
SWOOLE_HOOK_ALL
containsSWOOLE_HOOK_CURL
from version v4.5.4
<?php
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_SLEEP);
<?php
$sch = new Swoole\Coroutine\Scheduler();
$sch->set(['hook_flags' => SWOOLE_HOOK_ALL]);
If you are inside a coroutine context or a Swoole server, you can change hooks dynamically once they have been enabled:
<?php
// Enable all Swoole hooks at the beginning
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
// Only use the TCP hook...
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_TCP);
<?php
Swoole\Runtime::getHookFlags();
Returns the currently set hook flags.
<?php
// Enable all hooks
Swoole\Runtime::setHookFlags(SWOOLE_HOOK_ALL);
// Disable all hooks
Swoole\Runtime::setHookFlags(0);
<?php
Swoole\Runtime::enableCoroutine(FALSE);