add
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class_alias(Swoole\Coroutine\Channel::class, Co\Channel::class);
|
||||
class_alias(Swoole\Coroutine\Client::class, Co\Client::class);
|
||||
class_alias(Swoole\Coroutine\Context::class, Co\Context::class);
|
||||
class_alias(Swoole\Coroutine\Http2\Client::class, Co\Http2\Client::class);
|
||||
class_alias(Swoole\Coroutine\Http2\Client\Exception::class, Co\Http2\Client\Exception::class);
|
||||
class_alias(Swoole\Coroutine\Http\Client::class, Co\Http\Client::class);
|
||||
class_alias(Swoole\Coroutine\Http\Client\Exception::class, Co\Http\Client\Exception::class);
|
||||
class_alias(Swoole\Coroutine\Http\Server::class, Co\Http\Server::class);
|
||||
class_alias(Swoole\Coroutine\Iterator::class, Co\Iterator::class);
|
||||
class_alias(Swoole\Coroutine\MySQL::class, Co\MySQL::class);
|
||||
class_alias(Swoole\Coroutine\MySQL\Exception::class, Co\MySQL\Exception::class);
|
||||
class_alias(Swoole\Coroutine\MySQL\Statement::class, Co\MySQL\Statement::class);
|
||||
class_alias(Swoole\Coroutine\Redis::class, Co\Redis::class);
|
||||
class_alias(Swoole\Coroutine\Scheduler::class, Co\Scheduler::class);
|
||||
class_alias(Swoole\Coroutine\Socket::class, Co\Socket::class);
|
||||
class_alias(Swoole\Coroutine\Socket\Exception::class, Co\Socket\Exception::class);
|
||||
class_alias(Swoole\Coroutine\System::class, Co\System::class);
|
||||
|
||||
class_alias(Swoole\Atomic::class, swoole_atomic::class);
|
||||
class_alias(Swoole\Atomic\Long::class, swoole_atomic_long::class);
|
||||
class_alias(Swoole\Client::class, swoole_client::class);
|
||||
class_alias(Swoole\Connection\Iterator::class, swoole_connection_iterator::class);
|
||||
class_alias(Swoole\Coroutine::class, co::class);
|
||||
class_alias(Swoole\Coroutine\Channel::class, chan::class);
|
||||
class_alias(Swoole\Error::class, swoole_error::class);
|
||||
class_alias(Swoole\Event::class, swoole_event::class);
|
||||
class_alias(Swoole\Exception::class, swoole_exception::class);
|
||||
class_alias(Swoole\Http2\Request::class, swoole_http2_request::class);
|
||||
class_alias(Swoole\Http2\Response::class, swoole_http2_response::class);
|
||||
class_alias(Swoole\Http\Request::class, swoole_http_request::class);
|
||||
class_alias(Swoole\Http\Response::class, swoole_http_response::class);
|
||||
class_alias(Swoole\Http\Server::class, swoole_http_server::class);
|
||||
class_alias(Swoole\Lock::class, swoole_lock::class);
|
||||
class_alias(Swoole\Process::class, swoole_process::class);
|
||||
class_alias(Swoole\Process\Pool::class, swoole_process_pool::class);
|
||||
class_alias(Swoole\Redis\Server::class, swoole_redis_server::class);
|
||||
class_alias(Swoole\Runtime::class, swoole_runtime::class);
|
||||
class_alias(Swoole\Server::class, swoole_server::class);
|
||||
class_alias(Swoole\Server\Port::class, swoole_server_port::class);
|
||||
class_alias(Swoole\Server\Task::class, swoole_server_task::class);
|
||||
class_alias(Swoole\Table::class, swoole_table::class);
|
||||
class_alias(Swoole\Table\Row::class, swoole_table_row::class);
|
||||
class_alias(Swoole\Timer::class, swoole_timer::class);
|
||||
class_alias(Swoole\Timer\Iterator::class, swoole_timer_iterator::class);
|
||||
class_alias(Swoole\Websocket\Closeframe::class, swoole_websocket_closeframe::class);
|
||||
class_alias(Swoole\Websocket\Frame::class, swoole_websocket_frame::class);
|
||||
class_alias(Swoole\Websocket\Server::class, swoole_websocket_server::class);
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
|
||||
define('SWOOLE_VERSION', '4.5.6');
|
||||
define('SWOOLE_VERSION_ID', 40506);
|
||||
define('SWOOLE_MAJOR_VERSION', 4);
|
||||
define('SWOOLE_MINOR_VERSION', 5);
|
||||
define('SWOOLE_RELEASE_VERSION', 6);
|
||||
define('SWOOLE_EXTRA_VERSION', '');
|
||||
define('SWOOLE_DEBUG', '');
|
||||
define('SWOOLE_HAVE_COMPRESSION', '1');
|
||||
define('SWOOLE_HAVE_ZLIB', '1');
|
||||
define('SWOOLE_USE_HTTP2', '1');
|
||||
define('SWOOLE_USE_SHORTNAME', '1');
|
||||
define('SWOOLE_BASE', 1);
|
||||
define('SWOOLE_PROCESS', 2);
|
||||
define('SWOOLE_IPC_UNSOCK', 1);
|
||||
define('SWOOLE_IPC_MSGQUEUE', 2);
|
||||
define('SWOOLE_IPC_PREEMPTIVE', 3);
|
||||
define('SWOOLE_SOCK_TCP', 1);
|
||||
define('SWOOLE_SOCK_TCP6', 3);
|
||||
define('SWOOLE_SOCK_UDP', 2);
|
||||
define('SWOOLE_SOCK_UDP6', 4);
|
||||
define('SWOOLE_SOCK_UNIX_DGRAM', 6);
|
||||
define('SWOOLE_SOCK_UNIX_STREAM', 5);
|
||||
define('SWOOLE_TCP', 1);
|
||||
define('SWOOLE_TCP6', 3);
|
||||
define('SWOOLE_UDP', 2);
|
||||
define('SWOOLE_UDP6', 4);
|
||||
define('SWOOLE_UNIX_DGRAM', 6);
|
||||
define('SWOOLE_UNIX_STREAM', 5);
|
||||
define('SWOOLE_SOCK_SYNC', '');
|
||||
define('SWOOLE_SOCK_ASYNC', '1');
|
||||
define('SWOOLE_SYNC', 2048);
|
||||
define('SWOOLE_ASYNC', 1024);
|
||||
define('SWOOLE_KEEP', 4096);
|
||||
define('SWOOLE_SSL', 512);
|
||||
define('SWOOLE_SSLv3_METHOD', 1);
|
||||
define('SWOOLE_SSLv3_SERVER_METHOD', 2);
|
||||
define('SWOOLE_SSLv3_CLIENT_METHOD', 3);
|
||||
define('SWOOLE_TLSv1_METHOD', 6);
|
||||
define('SWOOLE_TLSv1_SERVER_METHOD', 7);
|
||||
define('SWOOLE_TLSv1_CLIENT_METHOD', 8);
|
||||
define('SWOOLE_TLSv1_1_METHOD', 9);
|
||||
define('SWOOLE_TLSv1_1_SERVER_METHOD', 10);
|
||||
define('SWOOLE_TLSv1_1_CLIENT_METHOD', 11);
|
||||
define('SWOOLE_TLSv1_2_METHOD', 12);
|
||||
define('SWOOLE_TLSv1_2_SERVER_METHOD', 13);
|
||||
define('SWOOLE_TLSv1_2_CLIENT_METHOD', 14);
|
||||
define('SWOOLE_DTLS_SERVER_METHOD', 16);
|
||||
define('SWOOLE_DTLS_CLIENT_METHOD', 15);
|
||||
define('SWOOLE_SSLv23_METHOD', 0);
|
||||
define('SWOOLE_SSLv23_SERVER_METHOD', 4);
|
||||
define('SWOOLE_SSLv23_CLIENT_METHOD', 5);
|
||||
define('SWOOLE_TLS_METHOD', 0);
|
||||
define('SWOOLE_TLS_SERVER_METHOD', 4);
|
||||
define('SWOOLE_TLS_CLIENT_METHOD', 5);
|
||||
define('SWOOLE_SSL_TLSv1', 8);
|
||||
define('SWOOLE_SSL_TLSv1_1', 16);
|
||||
define('SWOOLE_SSL_TLSv1_2', 32);
|
||||
define('SWOOLE_SSL_TLSv1_3', 64);
|
||||
define('SWOOLE_SSL_DTLS', 128);
|
||||
define('SWOOLE_SSL_SSLv2', 2);
|
||||
define('SWOOLE_EVENT_READ', 512);
|
||||
define('SWOOLE_EVENT_WRITE', 1024);
|
||||
define('SWOOLE_STRERROR_SYSTEM', 0);
|
||||
define('SWOOLE_STRERROR_GAI', 1);
|
||||
define('SWOOLE_STRERROR_DNS', 2);
|
||||
define('SWOOLE_STRERROR_SWOOLE', 9);
|
||||
define('SWOOLE_ERROR_MALLOC_FAIL', 501);
|
||||
define('SWOOLE_ERROR_SYSTEM_CALL_FAIL', 502);
|
||||
define('SWOOLE_ERROR_PHP_FATAL_ERROR', 503);
|
||||
define('SWOOLE_ERROR_NAME_TOO_LONG', 504);
|
||||
define('SWOOLE_ERROR_INVALID_PARAMS', 505);
|
||||
define('SWOOLE_ERROR_QUEUE_FULL', 506);
|
||||
define('SWOOLE_ERROR_OPERATION_NOT_SUPPORT', 507);
|
||||
define('SWOOLE_ERROR_PROTOCOL_ERROR', 508);
|
||||
define('SWOOLE_ERROR_WRONG_OPERATION', 509);
|
||||
define('SWOOLE_ERROR_FILE_NOT_EXIST', 700);
|
||||
define('SWOOLE_ERROR_FILE_TOO_LARGE', 701);
|
||||
define('SWOOLE_ERROR_FILE_EMPTY', 702);
|
||||
define('SWOOLE_ERROR_DNSLOOKUP_DUPLICATE_REQUEST', 703);
|
||||
define('SWOOLE_ERROR_DNSLOOKUP_RESOLVE_FAILED', 704);
|
||||
define('SWOOLE_ERROR_DNSLOOKUP_RESOLVE_TIMEOUT', 705);
|
||||
define('SWOOLE_ERROR_BAD_IPV6_ADDRESS', 706);
|
||||
define('SWOOLE_ERROR_UNREGISTERED_SIGNAL', 707);
|
||||
define('SWOOLE_ERROR_EVENT_SOCKET_REMOVED', 800);
|
||||
define('SWOOLE_ERROR_SESSION_CLOSED_BY_SERVER', 1001);
|
||||
define('SWOOLE_ERROR_SESSION_CLOSED_BY_CLIENT', 1002);
|
||||
define('SWOOLE_ERROR_SESSION_CLOSING', 1003);
|
||||
define('SWOOLE_ERROR_SESSION_CLOSED', 1004);
|
||||
define('SWOOLE_ERROR_SESSION_NOT_EXIST', 1005);
|
||||
define('SWOOLE_ERROR_SESSION_INVALID_ID', 1006);
|
||||
define('SWOOLE_ERROR_SESSION_DISCARD_TIMEOUT_DATA', 1007);
|
||||
define('SWOOLE_ERROR_SESSION_DISCARD_DATA', 1008);
|
||||
define('SWOOLE_ERROR_OUTPUT_BUFFER_OVERFLOW', 1009);
|
||||
define('SWOOLE_ERROR_OUTPUT_SEND_YIELD', 1010);
|
||||
define('SWOOLE_ERROR_SSL_NOT_READY', 1011);
|
||||
define('SWOOLE_ERROR_SSL_CANNOT_USE_SENFILE', 1012);
|
||||
define('SWOOLE_ERROR_SSL_EMPTY_PEER_CERTIFICATE', 1013);
|
||||
define('SWOOLE_ERROR_SSL_VERIFY_FAILED', 1014);
|
||||
define('SWOOLE_ERROR_SSL_BAD_CLIENT', 1015);
|
||||
define('SWOOLE_ERROR_SSL_BAD_PROTOCOL', 1016);
|
||||
define('SWOOLE_ERROR_SSL_RESET', 1017);
|
||||
define('SWOOLE_ERROR_SSL_HANDSHAKE_FAILED', 1018);
|
||||
define('SWOOLE_ERROR_PACKAGE_LENGTH_TOO_LARGE', 1201);
|
||||
define('SWOOLE_ERROR_PACKAGE_LENGTH_NOT_FOUND', 1202);
|
||||
define('SWOOLE_ERROR_DATA_LENGTH_TOO_LARGE', 1203);
|
||||
define('SWOOLE_ERROR_TASK_PACKAGE_TOO_BIG', 2001);
|
||||
define('SWOOLE_ERROR_TASK_DISPATCH_FAIL', 2002);
|
||||
define('SWOOLE_ERROR_TASK_TIMEOUT', 2003);
|
||||
define('SWOOLE_ERROR_HTTP2_STREAM_ID_TOO_BIG', 3001);
|
||||
define('SWOOLE_ERROR_HTTP2_STREAM_NO_HEADER', 3002);
|
||||
define('SWOOLE_ERROR_HTTP2_STREAM_NOT_FOUND', 3003);
|
||||
define('SWOOLE_ERROR_HTTP2_STREAM_IGNORE', 3004);
|
||||
define('SWOOLE_ERROR_AIO_BAD_REQUEST', 4001);
|
||||
define('SWOOLE_ERROR_AIO_CANCELED', 4002);
|
||||
define('SWOOLE_ERROR_AIO_TIMEOUT', 4003);
|
||||
define('SWOOLE_ERROR_CLIENT_NO_CONNECTION', 5001);
|
||||
define('SWOOLE_ERROR_SOCKET_CLOSED', 6001);
|
||||
define('SWOOLE_ERROR_SOCKET_POLL_TIMEOUT', 6002);
|
||||
define('SWOOLE_ERROR_SOCKS5_UNSUPPORT_VERSION', 7001);
|
||||
define('SWOOLE_ERROR_SOCKS5_UNSUPPORT_METHOD', 7002);
|
||||
define('SWOOLE_ERROR_SOCKS5_AUTH_FAILED', 7003);
|
||||
define('SWOOLE_ERROR_SOCKS5_SERVER_ERROR', 7004);
|
||||
define('SWOOLE_ERROR_SOCKS5_HANDSHAKE_FAILED', 7005);
|
||||
define('SWOOLE_ERROR_HTTP_PROXY_HANDSHAKE_ERROR', 7101);
|
||||
define('SWOOLE_ERROR_HTTP_INVALID_PROTOCOL', 7102);
|
||||
define('SWOOLE_ERROR_HTTP_PROXY_HANDSHAKE_FAILED', 7103);
|
||||
define('SWOOLE_ERROR_HTTP_PROXY_BAD_RESPONSE', 7104);
|
||||
define('SWOOLE_ERROR_WEBSOCKET_BAD_CLIENT', 8501);
|
||||
define('SWOOLE_ERROR_WEBSOCKET_BAD_OPCODE', 8502);
|
||||
define('SWOOLE_ERROR_WEBSOCKET_UNCONNECTED', 8503);
|
||||
define('SWOOLE_ERROR_WEBSOCKET_HANDSHAKE_FAILED', 8504);
|
||||
define('SWOOLE_ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT', 9001);
|
||||
define('SWOOLE_ERROR_SERVER_TOO_MANY_SOCKET', 9002);
|
||||
define('SWOOLE_ERROR_SERVER_WORKER_TERMINATED', 9003);
|
||||
define('SWOOLE_ERROR_SERVER_INVALID_LISTEN_PORT', 9004);
|
||||
define('SWOOLE_ERROR_SERVER_TOO_MANY_LISTEN_PORT', 9005);
|
||||
define('SWOOLE_ERROR_SERVER_PIPE_BUFFER_FULL', 9006);
|
||||
define('SWOOLE_ERROR_SERVER_NO_IDLE_WORKER', 9007);
|
||||
define('SWOOLE_ERROR_SERVER_ONLY_START_ONE', 9008);
|
||||
define('SWOOLE_ERROR_SERVER_SEND_IN_MASTER', 9009);
|
||||
define('SWOOLE_ERROR_SERVER_INVALID_REQUEST', 9010);
|
||||
define('SWOOLE_ERROR_SERVER_CONNECT_FAIL', 9011);
|
||||
define('SWOOLE_ERROR_SERVER_WORKER_EXIT_TIMEOUT', 9012);
|
||||
define('SWOOLE_ERROR_CO_OUT_OF_COROUTINE', 10001);
|
||||
define('SWOOLE_ERROR_CO_HAS_BEEN_BOUND', 10002);
|
||||
define('SWOOLE_ERROR_CO_HAS_BEEN_DISCARDED', 10003);
|
||||
define('SWOOLE_ERROR_CO_MUTEX_DOUBLE_UNLOCK', 10004);
|
||||
define('SWOOLE_ERROR_CO_BLOCK_OBJECT_LOCKED', 10005);
|
||||
define('SWOOLE_ERROR_CO_BLOCK_OBJECT_WAITING', 10006);
|
||||
define('SWOOLE_ERROR_CO_YIELD_FAILED', 10007);
|
||||
define('SWOOLE_ERROR_CO_GETCONTEXT_FAILED', 10008);
|
||||
define('SWOOLE_ERROR_CO_SWAPCONTEXT_FAILED', 10009);
|
||||
define('SWOOLE_ERROR_CO_MAKECONTEXT_FAILED', 10010);
|
||||
define('SWOOLE_ERROR_CO_IOCPINIT_FAILED', 10011);
|
||||
define('SWOOLE_ERROR_CO_PROTECT_STACK_FAILED', 10012);
|
||||
define('SWOOLE_ERROR_CO_STD_THREAD_LINK_ERROR', 10013);
|
||||
define('SWOOLE_ERROR_CO_DISABLED_MULTI_THREAD', 10014);
|
||||
define('SWOOLE_TRACE_SERVER', 2);
|
||||
define('SWOOLE_TRACE_CLIENT', 4);
|
||||
define('SWOOLE_TRACE_BUFFER', 8);
|
||||
define('SWOOLE_TRACE_CONN', 16);
|
||||
define('SWOOLE_TRACE_EVENT', 32);
|
||||
define('SWOOLE_TRACE_WORKER', 64);
|
||||
define('SWOOLE_TRACE_MEMORY', 128);
|
||||
define('SWOOLE_TRACE_REACTOR', 256);
|
||||
define('SWOOLE_TRACE_PHP', 512);
|
||||
define('SWOOLE_TRACE_HTTP', 1024);
|
||||
define('SWOOLE_TRACE_HTTP2', 2048);
|
||||
define('SWOOLE_TRACE_EOF_PROTOCOL', 4096);
|
||||
define('SWOOLE_TRACE_LENGTH_PROTOCOL', 8192);
|
||||
define('SWOOLE_TRACE_CLOSE', 16384);
|
||||
define('SWOOLE_TRACE_WEBSOCEKT', 32768);
|
||||
define('SWOOLE_TRACE_REDIS_CLIENT', 65536);
|
||||
define('SWOOLE_TRACE_MYSQL_CLIENT', 131072);
|
||||
define('SWOOLE_TRACE_HTTP_CLIENT', 262144);
|
||||
define('SWOOLE_TRACE_AIO', 524288);
|
||||
define('SWOOLE_TRACE_SSL', 1048576);
|
||||
define('SWOOLE_TRACE_NORMAL', 2097152);
|
||||
define('SWOOLE_TRACE_CHANNEL', 4194304);
|
||||
define('SWOOLE_TRACE_TIMER', 8388608);
|
||||
define('SWOOLE_TRACE_SOCKET', 16777216);
|
||||
define('SWOOLE_TRACE_COROUTINE', 33554432);
|
||||
define('SWOOLE_TRACE_CONTEXT', 67108864);
|
||||
define('SWOOLE_TRACE_CO_HTTP_SERVER', 134217728);
|
||||
define('SWOOLE_TRACE_TABLE', 268435456);
|
||||
define('SWOOLE_TRACE_ALL', 4294967295);
|
||||
define('SWOOLE_LOG_DEBUG', 0);
|
||||
define('SWOOLE_LOG_TRACE', 1);
|
||||
define('SWOOLE_LOG_INFO', 2);
|
||||
define('SWOOLE_LOG_NOTICE', 3);
|
||||
define('SWOOLE_LOG_WARNING', 4);
|
||||
define('SWOOLE_LOG_ERROR', 5);
|
||||
define('SWOOLE_LOG_NONE', 6);
|
||||
define('SWOOLE_LOG_ROTATION_SINGLE', 0);
|
||||
define('SWOOLE_LOG_ROTATION_DAILY', 1);
|
||||
define('SWOOLE_IPC_NONE', 0);
|
||||
define('SWOOLE_IPC_UNIXSOCK', 1);
|
||||
define('SWOOLE_IPC_SOCKET', 3);
|
||||
define('SWOOLE_FILELOCK', 2);
|
||||
define('SWOOLE_MUTEX', 3);
|
||||
define('SWOOLE_SEM', 4);
|
||||
define('SWOOLE_RWLOCK', 1);
|
||||
define('SWOOLE_SPINLOCK', 5);
|
||||
define('SIGHUP', 1);
|
||||
define('SIGINT', 2);
|
||||
define('SIGQUIT', 3);
|
||||
define('SIGILL', 4);
|
||||
define('SIGTRAP', 5);
|
||||
define('SIGABRT', 6);
|
||||
define('SIGBUS', 7);
|
||||
define('SIGFPE', 8);
|
||||
define('SIGKILL', 9);
|
||||
define('SIGUSR1', 10);
|
||||
define('SIGSEGV', 11);
|
||||
define('SIGUSR2', 12);
|
||||
define('SIGPIPE', 13);
|
||||
define('SIGALRM', 14);
|
||||
define('SIGTERM', 15);
|
||||
define('SIGSTKFLT', 16);
|
||||
define('SIGCHLD', 17);
|
||||
define('SIGCONT', 18);
|
||||
define('SIGSTOP', 19);
|
||||
define('SIGTSTP', 20);
|
||||
define('SIGTTIN', 21);
|
||||
define('SIGTTOU', 22);
|
||||
define('SIGURG', 23);
|
||||
define('SIGXCPU', 24);
|
||||
define('SIGXFSZ', 25);
|
||||
define('SIGVTALRM', 26);
|
||||
define('SIGPROF', 27);
|
||||
define('SIGWINCH', 28);
|
||||
define('SIGIO', 29);
|
||||
define('SIGPWR', 30);
|
||||
define('SIGSYS', 31);
|
||||
define('SIG_IGN', 1);
|
||||
define('SWOOLE_TIMER_MIN_MS', 1);
|
||||
define('SWOOLE_TIMER_MIN_SEC', 0.001);
|
||||
define('SWOOLE_TIMER_MAX_MS', 9223372036854775807);
|
||||
define('SWOOLE_TIMER_MAX_SEC', 9.2233720368548E+15);
|
||||
define('SWOOLE_DEFAULT_MAX_CORO_NUM', 100000);
|
||||
define('SWOOLE_CORO_MAX_NUM_LIMIT', 9223372036854775807);
|
||||
define('SWOOLE_CORO_INIT', 0);
|
||||
define('SWOOLE_CORO_WAITING', 1);
|
||||
define('SWOOLE_CORO_RUNNING', 2);
|
||||
define('SWOOLE_CORO_END', 3);
|
||||
define('SWOOLE_EXIT_IN_COROUTINE', 2);
|
||||
define('SWOOLE_EXIT_IN_SERVER', 4);
|
||||
define('SWOOLE_CHANNEL_OK', 0);
|
||||
define('SWOOLE_CHANNEL_TIMEOUT', -1);
|
||||
define('SWOOLE_CHANNEL_CLOSED', -2);
|
||||
define('SWOOLE_HOOK_TCP', 2);
|
||||
define('SWOOLE_HOOK_UDP', 4);
|
||||
define('SWOOLE_HOOK_UNIX', 8);
|
||||
define('SWOOLE_HOOK_UDG', 16);
|
||||
define('SWOOLE_HOOK_SSL', 32);
|
||||
define('SWOOLE_HOOK_TLS', 64);
|
||||
define('SWOOLE_HOOK_STREAM_FUNCTION', 128);
|
||||
define('SWOOLE_HOOK_STREAM_SELECT', 128);
|
||||
define('SWOOLE_HOOK_FILE', 256);
|
||||
define('SWOOLE_HOOK_SLEEP', 512);
|
||||
define('SWOOLE_HOOK_PROC', 1024);
|
||||
define('SWOOLE_HOOK_CURL', 268435456);
|
||||
define('SWOOLE_HOOK_BLOCKING_FUNCTION', 1073741824);
|
||||
define('SWOOLE_HOOK_ALL', 2147483647);
|
||||
define('SOCKET_ECANCELED', 125);
|
||||
define('SWOOLE_HTTP_CLIENT_ESTATUS_CONNECT_FAILED', -1);
|
||||
define('SWOOLE_HTTP_CLIENT_ESTATUS_REQUEST_TIMEOUT', -2);
|
||||
define('SWOOLE_HTTP_CLIENT_ESTATUS_SERVER_RESET', -3);
|
||||
define('SWOOLE_MYSQLND_CR_UNKNOWN_ERROR', 2000);
|
||||
define('SWOOLE_MYSQLND_CR_CONNECTION_ERROR', 2002);
|
||||
define('SWOOLE_MYSQLND_CR_SERVER_GONE_ERROR', 2006);
|
||||
define('SWOOLE_MYSQLND_CR_OUT_OF_MEMORY', 2008);
|
||||
define('SWOOLE_MYSQLND_CR_SERVER_LOST', 2013);
|
||||
define('SWOOLE_MYSQLND_CR_COMMANDS_OUT_OF_SYNC', 2014);
|
||||
define('SWOOLE_MYSQLND_CR_CANT_FIND_CHARSET', 2019);
|
||||
define('SWOOLE_MYSQLND_CR_MALFORMED_PACKET', 2027);
|
||||
define('SWOOLE_MYSQLND_CR_NOT_IMPLEMENTED', 2054);
|
||||
define('SWOOLE_MYSQLND_CR_NO_PREPARE_STMT', 2030);
|
||||
define('SWOOLE_MYSQLND_CR_PARAMS_NOT_BOUND', 2031);
|
||||
define('SWOOLE_MYSQLND_CR_INVALID_PARAMETER_NO', 2034);
|
||||
define('SWOOLE_MYSQLND_CR_INVALID_BUFFER_USE', 2035);
|
||||
define('SWOOLE_REDIS_MODE_MULTI', 0);
|
||||
define('SWOOLE_REDIS_MODE_PIPELINE', 1);
|
||||
define('SWOOLE_REDIS_TYPE_NOT_FOUND', 0);
|
||||
define('SWOOLE_REDIS_TYPE_STRING', 1);
|
||||
define('SWOOLE_REDIS_TYPE_SET', 2);
|
||||
define('SWOOLE_REDIS_TYPE_LIST', 3);
|
||||
define('SWOOLE_REDIS_TYPE_ZSET', 4);
|
||||
define('SWOOLE_REDIS_TYPE_HASH', 5);
|
||||
define('SWOOLE_REDIS_ERR_IO', 1);
|
||||
define('SWOOLE_REDIS_ERR_OTHER', 2);
|
||||
define('SWOOLE_REDIS_ERR_EOF', 3);
|
||||
define('SWOOLE_REDIS_ERR_PROTOCOL', 4);
|
||||
define('SWOOLE_REDIS_ERR_OOM', 5);
|
||||
define('SWOOLE_REDIS_ERR_CLOSED', 6);
|
||||
define('SWOOLE_REDIS_ERR_NOAUTH', 7);
|
||||
define('SWOOLE_REDIS_ERR_ALLOC', 8);
|
||||
define('SWOOLE_HTTP2_TYPE_DATA', 0);
|
||||
define('SWOOLE_HTTP2_TYPE_HEADERS', 1);
|
||||
define('SWOOLE_HTTP2_TYPE_PRIORITY', 2);
|
||||
define('SWOOLE_HTTP2_TYPE_RST_STREAM', 3);
|
||||
define('SWOOLE_HTTP2_TYPE_SETTINGS', 4);
|
||||
define('SWOOLE_HTTP2_TYPE_PUSH_PROMISE', 5);
|
||||
define('SWOOLE_HTTP2_TYPE_PING', 6);
|
||||
define('SWOOLE_HTTP2_TYPE_GOAWAY', 7);
|
||||
define('SWOOLE_HTTP2_TYPE_WINDOW_UPDATE', 8);
|
||||
define('SWOOLE_HTTP2_TYPE_CONTINUATION', 9);
|
||||
define('SWOOLE_HTTP2_ERROR_NO_ERROR', 0);
|
||||
define('SWOOLE_HTTP2_ERROR_PROTOCOL_ERROR', 1);
|
||||
define('SWOOLE_HTTP2_ERROR_INTERNAL_ERROR', 2);
|
||||
define('SWOOLE_HTTP2_ERROR_FLOW_CONTROL_ERROR', 3);
|
||||
define('SWOOLE_HTTP2_ERROR_SETTINGS_TIMEOUT', 4);
|
||||
define('SWOOLE_HTTP2_ERROR_STREAM_CLOSED', 5);
|
||||
define('SWOOLE_HTTP2_ERROR_FRAME_SIZE_ERROR', 6);
|
||||
define('SWOOLE_HTTP2_ERROR_REFUSED_STREAM', 7);
|
||||
define('SWOOLE_HTTP2_ERROR_CANCEL', 8);
|
||||
define('SWOOLE_HTTP2_ERROR_COMPRESSION_ERROR', 9);
|
||||
define('SWOOLE_HTTP2_ERROR_CONNECT_ERROR', 10);
|
||||
define('SWOOLE_HTTP2_ERROR_ENHANCE_YOUR_CALM', 11);
|
||||
define('SWOOLE_HTTP2_ERROR_INADEQUATE_SECURITY', 12);
|
||||
define('SWOOLE_DISPATCH_RESULT_DISCARD_PACKET', -1);
|
||||
define('SWOOLE_DISPATCH_RESULT_CLOSE_CONNECTION', -2);
|
||||
define('SWOOLE_DISPATCH_RESULT_USERFUNC_FALLBACK', -3);
|
||||
define('SWOOLE_TASK_TMPFILE', 1);
|
||||
define('SWOOLE_TASK_SERIALIZE', 2);
|
||||
define('SWOOLE_TASK_NONBLOCK', 4);
|
||||
define('SWOOLE_TASK_CALLBACK', 8);
|
||||
define('SWOOLE_TASK_WAITALL', 16);
|
||||
define('SWOOLE_TASK_COROUTINE', 32);
|
||||
define('SWOOLE_TASK_PEEK', 64);
|
||||
define('SWOOLE_TASK_NOREPLY', 128);
|
||||
define('SWOOLE_WORKER_BUSY', 1);
|
||||
define('SWOOLE_WORKER_IDLE', 2);
|
||||
define('SWOOLE_WORKER_EXIT', 3);
|
||||
define('SWOOLE_WEBSOCKET_STATUS_CONNECTION', 1);
|
||||
define('SWOOLE_WEBSOCKET_STATUS_HANDSHAKE', 2);
|
||||
define('SWOOLE_WEBSOCKET_STATUS_ACTIVE', 3);
|
||||
define('SWOOLE_WEBSOCKET_STATUS_CLOSING', 4);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_CONTINUATION', 0);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_TEXT', 1);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_BINARY', 2);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_CLOSE', 8);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_PING', 9);
|
||||
define('SWOOLE_WEBSOCKET_OPCODE_PONG', 10);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_FIN', 1);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_RSV1', 4);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_RSV2', 8);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_RSV3', 16);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_MASK', 32);
|
||||
define('SWOOLE_WEBSOCKET_FLAG_COMPRESS', 2);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_NORMAL', 1000);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_GOING_AWAY', 1001);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_PROTOCOL_ERROR', 1002);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_DATA_ERROR', 1003);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_STATUS_ERROR', 1005);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_ABNORMAL', 1006);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_MESSAGE_ERROR', 1007);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_POLICY_ERROR', 1008);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_MESSAGE_TOO_BIG', 1009);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_EXTENSION_MISSING', 1010);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_SERVER_ERROR', 1011);
|
||||
define('SWOOLE_WEBSOCKET_CLOSE_TLS', 1015);
|
||||
define('WEBSOCKET_STATUS_CONNECTION', 1);
|
||||
define('WEBSOCKET_STATUS_HANDSHAKE', 2);
|
||||
define('WEBSOCKET_STATUS_FRAME', 3);
|
||||
define('WEBSOCKET_STATUS_ACTIVE', 3);
|
||||
define('WEBSOCKET_STATUS_CLOSING', 4);
|
||||
define('WEBSOCKET_OPCODE_CONTINUATION', 0);
|
||||
define('WEBSOCKET_OPCODE_TEXT', 1);
|
||||
define('WEBSOCKET_OPCODE_BINARY', 2);
|
||||
define('WEBSOCKET_OPCODE_CLOSE', 8);
|
||||
define('WEBSOCKET_OPCODE_PING', 9);
|
||||
define('WEBSOCKET_OPCODE_PONG', 10);
|
||||
define('WEBSOCKET_CLOSE_NORMAL', 1000);
|
||||
define('WEBSOCKET_CLOSE_GOING_AWAY', 1001);
|
||||
define('WEBSOCKET_CLOSE_PROTOCOL_ERROR', 1002);
|
||||
define('WEBSOCKET_CLOSE_DATA_ERROR', 1003);
|
||||
define('WEBSOCKET_CLOSE_STATUS_ERROR', 1005);
|
||||
define('WEBSOCKET_CLOSE_ABNORMAL', 1006);
|
||||
define('WEBSOCKET_CLOSE_MESSAGE_ERROR', 1007);
|
||||
define('WEBSOCKET_CLOSE_POLICY_ERROR', 1008);
|
||||
define('WEBSOCKET_CLOSE_MESSAGE_TOO_BIG', 1009);
|
||||
define('WEBSOCKET_CLOSE_EXTENSION_MISSING', 1010);
|
||||
define('WEBSOCKET_CLOSE_SERVER_ERROR', 1011);
|
||||
define('WEBSOCKET_CLOSE_TLS', 1015);
|
||||
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_version(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_cpu_num(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_last_error(){}
|
||||
|
||||
/**
|
||||
* @param $domain_name[required]
|
||||
* @param $timeout[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_async_dns_lookup_coro($domain_name, $timeout = null){}
|
||||
|
||||
/**
|
||||
* @param $settings[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_async_set($settings){}
|
||||
|
||||
/**
|
||||
* @param $func[required]
|
||||
* @param $params[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_coroutine_create($func, $params = null){}
|
||||
|
||||
/**
|
||||
* @param $callback[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_coroutine_defer($callback){}
|
||||
|
||||
/**
|
||||
* @param $read_array[required]
|
||||
* @param $write_array[required]
|
||||
* @param $error_array[required]
|
||||
* @param $timeout[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_client_select(&$read_array, &$write_array, &$error_array, $timeout = null){}
|
||||
|
||||
/**
|
||||
* @param $read_array[required]
|
||||
* @param $write_array[required]
|
||||
* @param $error_array[required]
|
||||
* @param $timeout[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_select(&$read_array, &$write_array, &$error_array, $timeout = null){}
|
||||
|
||||
/**
|
||||
* @param $process_name[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_set_process_name($process_name){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_get_local_ip(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_get_local_mac(){}
|
||||
|
||||
/**
|
||||
* @param $errno[required]
|
||||
* @param $error_type[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_strerror($errno, $error_type = null){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_errno(){}
|
||||
|
||||
/**
|
||||
* @param $data[required]
|
||||
* @param $type[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_hashcode($data, $type = null){}
|
||||
|
||||
/**
|
||||
* @param $suffix[required]
|
||||
* @param $mime_type[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_add($suffix, $mime_type){}
|
||||
|
||||
/**
|
||||
* @param $suffix[required]
|
||||
* @param $mime_type[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_set($suffix, $mime_type){}
|
||||
|
||||
/**
|
||||
* @param $suffix[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_delete($suffix){}
|
||||
|
||||
/**
|
||||
* @param $filename[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_get($filename){}
|
||||
|
||||
/**
|
||||
* @param $filename[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_get_mime_type($filename){}
|
||||
|
||||
/**
|
||||
* @param $filename[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_exists($filename){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_mime_type_list(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_clear_dns_cache(){}
|
||||
|
||||
/**
|
||||
* @param $str[required]
|
||||
* @param $offset[required]
|
||||
* @param $length[optional]
|
||||
* @param $options[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_substr_unserialize($str, $offset, $length = null, $options = null){}
|
||||
|
||||
/**
|
||||
* @param $json[required]
|
||||
* @param $offset[required]
|
||||
* @param $length[optional]
|
||||
* @param $associative[optional]
|
||||
* @param $depth[optional]
|
||||
* @param $flags[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_substr_json_decode($json, $offset, $length = null, $associative = null, $depth = null, $flags = null){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_internal_call_user_shutdown_begin(){}
|
||||
|
||||
/**
|
||||
* @param $func[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function go($func){}
|
||||
|
||||
/**
|
||||
* @param $callback[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function defer($callback){}
|
||||
|
||||
/**
|
||||
* @param $fd[required]
|
||||
* @param $read_callback[required]
|
||||
* @param $write_callback[optional]
|
||||
* @param $events[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_add($fd, $read_callback, $write_callback = null, $events = null){}
|
||||
|
||||
/**
|
||||
* @param $fd[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_del($fd){}
|
||||
|
||||
/**
|
||||
* @param $fd[required]
|
||||
* @param $read_callback[optional]
|
||||
* @param $write_callback[optional]
|
||||
* @param $events[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_set($fd, $read_callback = null, $write_callback = null, $events = null){}
|
||||
|
||||
/**
|
||||
* @param $fd[required]
|
||||
* @param $events[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_isset($fd, $events = null){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_dispatch(){}
|
||||
|
||||
/**
|
||||
* @param $callback[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_defer($callback){}
|
||||
|
||||
/**
|
||||
* @param $callback[required]
|
||||
* @param $before[optional]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_cycle($callback, $before = null){}
|
||||
|
||||
/**
|
||||
* @param $fd[required]
|
||||
* @param $data[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_write($fd, $data){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_wait(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_event_exit(){}
|
||||
|
||||
/**
|
||||
* @param $settings[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_set($settings){}
|
||||
|
||||
/**
|
||||
* @param $ms[required]
|
||||
* @param $callback[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_after($ms, $callback){}
|
||||
|
||||
/**
|
||||
* @param $ms[required]
|
||||
* @param $callback[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_tick($ms, $callback){}
|
||||
|
||||
/**
|
||||
* @param $timer_id[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_exists($timer_id){}
|
||||
|
||||
/**
|
||||
* @param $timer_id[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_info($timer_id){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_stats(){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_list(){}
|
||||
|
||||
/**
|
||||
* @param $timer_id[required]
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_clear($timer_id){}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
function swoole_timer_clear_all(){}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Atomic
|
||||
{
|
||||
|
||||
public function __construct($value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function add($add_value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sub($sub_value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function wait($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function wakeup($count = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function cmpset($cmp_value, $new_value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Atomic;
|
||||
|
||||
class Long
|
||||
{
|
||||
|
||||
public function __construct($value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function add($add_value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sub($sub_value = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function cmpset($cmp_value, $new_value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
public const MSG_OOB = 1;
|
||||
|
||||
public const MSG_PEEK = 2;
|
||||
|
||||
public const MSG_DONTWAIT = 64;
|
||||
|
||||
public const MSG_WAITALL = 256;
|
||||
|
||||
public const SHUT_RDWR = 2;
|
||||
|
||||
public const SHUT_RD = 0;
|
||||
|
||||
public const SHUT_WR = 1;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $sock = -1;
|
||||
|
||||
public $reuse = false;
|
||||
|
||||
public $reuseCount = 0;
|
||||
|
||||
public $type = 0;
|
||||
|
||||
public $id;
|
||||
|
||||
public $setting;
|
||||
|
||||
public function __construct($type, $async = null, $id = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect($host, $port = null, $timeout = null, $sock_flag = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($size = null, $flag = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($data, $flag = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendfile($filename, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendto($ip, $port, $data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function shutdown($how)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function enableSSL()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPeerCert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function verifyPeerCert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getsockname()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getpeername()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close($force = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Connection;
|
||||
|
||||
class Iterator implements \Iterator, \ArrayAccess
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetExists($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetSet($fd, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetUnset($fd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Coroutine
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function create(callable $func, ... $params)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function defer($callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function set($options)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function exists($cid)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function yield()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function suspend()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function resume($cid)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function stats()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getCid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getuid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getPcid($cid = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getContext($cid = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getBackTrace($cid = null, $options = null, $limit = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getElapsed($cid = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function list()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function listCoroutines()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function enableScheduler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function disableScheduler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function gethostbyname($domain_name, $family = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dnsLookup($domain_name, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function exec($command, $get_error_stream = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function sleep($seconds)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getaddrinfo($hostname, $family = null, $socktype = null, $protocol = null, $service = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function statvfs($path)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function readFile($filename)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function writeFile($filename, $data, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function wait($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitPid($pid, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitSignal($signo, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitEvent($fd, $events = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fread($handle, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fgets($handle)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fwrite($handle, $string, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Channel
|
||||
{
|
||||
|
||||
public $capacity = 0;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public function __construct($size = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($data, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isFull()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function length()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
public const MSG_OOB = 1;
|
||||
|
||||
public const MSG_PEEK = 2;
|
||||
|
||||
public const MSG_DONTWAIT = 64;
|
||||
|
||||
public const MSG_WAITALL = 256;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $errMsg = '';
|
||||
|
||||
public $fd = -1;
|
||||
|
||||
private $socket;
|
||||
|
||||
public $type = 1;
|
||||
|
||||
public $setting;
|
||||
|
||||
public $connected = false;
|
||||
|
||||
public function __construct($type)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect($host, $port = null, $timeout = null, $sock_flag = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function peek($length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendfile($filename, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendto($address, $port, $data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recvfrom($length, &$address, &$port = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function enableSSL()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPeerCert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function verifyPeerCert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getsockname()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getpeername()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exportSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Context extends \ArrayObject
|
||||
{
|
||||
|
||||
public const STD_PROP_LIST = 1;
|
||||
|
||||
public const ARRAY_AS_PROPS = 2;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Http;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $errMsg = '';
|
||||
|
||||
public $connected = false;
|
||||
|
||||
public $host = '';
|
||||
|
||||
public $port = 0;
|
||||
|
||||
public $ssl = false;
|
||||
|
||||
public $setting;
|
||||
|
||||
public $requestMethod;
|
||||
|
||||
public $requestHeaders;
|
||||
|
||||
public $requestBody;
|
||||
|
||||
public $uploadFiles;
|
||||
|
||||
public $downloadFile;
|
||||
|
||||
public $downloadOffset = 0;
|
||||
|
||||
public $statusCode = 0;
|
||||
|
||||
public $headers;
|
||||
|
||||
public $set_cookie_headers;
|
||||
|
||||
public $cookies;
|
||||
|
||||
public $body = '';
|
||||
|
||||
public function __construct($host, $port = null, $ssl = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefer()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setDefer($defer = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setBasicAuth($username, $password)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setCookies(array $cookies)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function addFile($path, $name, $type = null, $filename = null, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function addData($path, $name, $type = null, $filename = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($path)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getpeername()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getsockname()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($path)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($path, $data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function download($path, $file, $offset = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCookies()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHeaderOut()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPeerCert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function upgrade($path)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($data, $opcode = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Http\Client;
|
||||
|
||||
class Exception extends \Swoole\Exception
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Http;
|
||||
|
||||
class Server
|
||||
{
|
||||
|
||||
public $fd = -1;
|
||||
|
||||
public $host;
|
||||
|
||||
public $port = -1;
|
||||
|
||||
public $ssl = false;
|
||||
|
||||
public $settings;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $errMsg = '';
|
||||
|
||||
public function __construct($host, $port = null, $ssl = null, $reuse_port = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($pattern, callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function onAccept()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Http2;
|
||||
|
||||
class Client
|
||||
{
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $errMsg = 0;
|
||||
|
||||
public $sock = -1;
|
||||
|
||||
public $type = 0;
|
||||
|
||||
public $setting;
|
||||
|
||||
public $connected = false;
|
||||
|
||||
public $host;
|
||||
|
||||
public $port = 0;
|
||||
|
||||
public $ssl = false;
|
||||
|
||||
public function __construct($host, $port = null, $ssl = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function stats($key = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isStreamExist($stream_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($request)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function write($stream_id, $data, $end_stream = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function read($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function goaway($error_code = null, $debug_data = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function ping()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Http2\Client;
|
||||
|
||||
class Exception extends \Swoole\Exception
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Iterator extends \ArrayIterator
|
||||
{
|
||||
|
||||
public const STD_PROP_LIST = 1;
|
||||
|
||||
public const ARRAY_AS_PROPS = 2;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class MySQL
|
||||
{
|
||||
|
||||
public $serverInfo;
|
||||
|
||||
public $sock = -1;
|
||||
|
||||
public $connected = false;
|
||||
|
||||
public $connect_errno = 0;
|
||||
|
||||
public $connect_error = '';
|
||||
|
||||
public $affected_rows = 0;
|
||||
|
||||
public $insert_id = 0;
|
||||
|
||||
public $error = '';
|
||||
|
||||
public $errno = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefer()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setDefer($defer = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect(array $server_config = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($sql, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetch()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function nextResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function prepare($query, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function begin($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function commit($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rollback($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function escape($string, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\MySQL;
|
||||
|
||||
class Exception extends \Swoole\Exception
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\MySQL;
|
||||
|
||||
class Statement
|
||||
{
|
||||
|
||||
public $id = 0;
|
||||
|
||||
public $affected_rows = 0;
|
||||
|
||||
public $insert_id = 0;
|
||||
|
||||
public $error = '';
|
||||
|
||||
public $errno = 0;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($params = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetch($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchAll($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function nextResult($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Scheduler
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function add(callable $func, ... $params)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function parallel($n, callable $func = null, ... $params)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class Socket
|
||||
{
|
||||
|
||||
public $fd = -1;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $errMsg = '';
|
||||
|
||||
public function __construct($domain, $type, $protocol = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function bind($address, $port = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function listen($backlog = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function accept($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect($host, $port = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function checkLiveness()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function peek($length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv($length = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recvPacket($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($data, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendFile($filename, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recvAll($length = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendAll($data, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recvfrom(&$peername, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendto($addr, $port, $data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOption($level, $opt_name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setProtocol(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setOption($level, $opt_name, $opt_value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sslHandshake()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function shutdown($how = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function cancel($event = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getpeername()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getsockname()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine\Socket;
|
||||
|
||||
class Exception extends \Swoole\Exception
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
class System
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function gethostbyname($domain_name, $family = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dnsLookup($domain_name, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function exec($command, $get_error_stream = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function sleep($seconds)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getaddrinfo($hostname, $family = null, $socktype = null, $protocol = null, $service = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function statvfs($path)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function readFile($filename)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function writeFile($filename, $data, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function wait($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitPid($pid, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitSignal($signo, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function waitEvent($fd, $events = null, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fread($handle, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fwrite($handle, $string, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fgets($handle)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Error extends \Error
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Event
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function add($fd, ?callable $read_callback, ?callable $write_callback = null, $events = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function del($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function set($fd, ?callable $read_callback = null, ?callable $write_callback = null, $events = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function isset($fd, $events = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dispatch()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function defer(callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function cycle(?callable $callback, $before = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function write($fd, $data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function wait()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function rshutdown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function exit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class ExitException extends Exception
|
||||
{
|
||||
|
||||
private $flags = 0;
|
||||
|
||||
private $status = 0;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFlags()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Http;
|
||||
|
||||
class Request
|
||||
{
|
||||
|
||||
public $fd = 0;
|
||||
|
||||
public $streamId = 0;
|
||||
|
||||
public $header;
|
||||
|
||||
public $server;
|
||||
|
||||
public $cookie;
|
||||
|
||||
public $get;
|
||||
|
||||
public $files;
|
||||
|
||||
public $post;
|
||||
|
||||
public $tmpfiles;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rawContent()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Http;
|
||||
|
||||
class Response
|
||||
{
|
||||
|
||||
public $fd = 0;
|
||||
|
||||
public $socket;
|
||||
|
||||
public $header;
|
||||
|
||||
public $cookie;
|
||||
|
||||
public $trailer;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function initHeader()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function cookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rawcookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function status($http_code, $reason = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setStatusCode($http_code, $reason = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function header($key, $value, $ucwords = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setHeader($key, $value, $ucwords = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function trailer($key, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function ping()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function goaway()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function write($content)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function end($content = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendfile($filename, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function redirect($location, $http_code = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function detach()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function create($server, $fd = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function upgrade()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($data, $opcode = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function recv()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Http;
|
||||
|
||||
class Server extends \Swoole\Server
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Http2;
|
||||
|
||||
class Request
|
||||
{
|
||||
|
||||
public $path = '/';
|
||||
|
||||
public $method = 'GET';
|
||||
|
||||
public $headers;
|
||||
|
||||
public $cookies;
|
||||
|
||||
public $data = '';
|
||||
|
||||
public $pipeline = false;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Http2;
|
||||
|
||||
class Response
|
||||
{
|
||||
|
||||
public $streamId = 0;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public $statusCode = 0;
|
||||
|
||||
public $pipeline = false;
|
||||
|
||||
public $headers;
|
||||
|
||||
public $set_cookie_headers;
|
||||
|
||||
public $cookies;
|
||||
|
||||
public $data;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Lock
|
||||
{
|
||||
|
||||
public const FILELOCK = 2;
|
||||
|
||||
public const MUTEX = 3;
|
||||
|
||||
public const SEM = 4;
|
||||
|
||||
public const RWLOCK = 1;
|
||||
|
||||
public const SPINLOCK = 5;
|
||||
|
||||
public $errCode = 0;
|
||||
|
||||
public function __construct($type = null, $filename = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function lock()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function lockwait($timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function trylock()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function lock_read()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function trylock_read()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function unlock()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Process
|
||||
{
|
||||
|
||||
public const IPC_NOWAIT = 256;
|
||||
|
||||
public const PIPE_MASTER = 1;
|
||||
|
||||
public const PIPE_WORKER = 2;
|
||||
|
||||
public const PIPE_READ = 3;
|
||||
|
||||
public const PIPE_WRITE = 4;
|
||||
|
||||
public $pipe;
|
||||
|
||||
public $msgQueueId;
|
||||
|
||||
public $msgQueueKey;
|
||||
|
||||
public $pid;
|
||||
|
||||
public $id;
|
||||
|
||||
private $callback;
|
||||
|
||||
public function __construct(callable $callback, $redirect_stdin_and_stdout = null, $pipe_type = null, $enable_coroutine = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function wait($blocking = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function signal($signal_no, $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function alarm($usec, $type = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function kill($pid, $signal_no = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function daemon($nochdir = null, $noclose = null, $pipes = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setaffinity(array $cpu_settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setTimeout($seconds)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setBlocking($blocking)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function useQueue($key = null, $mode = null, $capacity = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function statQueue()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function freeQueue()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function read($size = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop($size = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exit($exit_code = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exec($exec_file, $args)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exportSocket()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function name($process_name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Process;
|
||||
|
||||
class Pool
|
||||
{
|
||||
|
||||
public $master_pid = -1;
|
||||
|
||||
public $workers;
|
||||
|
||||
public function __construct($worker_num, $ipc_type = null, $msgqueue_key = null, $enable_coroutine = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function on($event_name, callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProcess($worker_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function listen($host, $port = null, $backlog = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Redis;
|
||||
|
||||
class Server extends \Swoole\Server
|
||||
{
|
||||
|
||||
public const NIL = 1;
|
||||
|
||||
public const ERROR = 0;
|
||||
|
||||
public const STATUS = 2;
|
||||
|
||||
public const INT = 3;
|
||||
|
||||
public const STRING = 4;
|
||||
|
||||
public const SET = 5;
|
||||
|
||||
public const MAP = 6;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function setHandler($command, callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHandler($command)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function format($type, $value = null)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Runtime
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function enableCoroutine($enable = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getHookFlags()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setHookFlags($flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Server
|
||||
{
|
||||
|
||||
private $onStart;
|
||||
|
||||
private $onShutdown;
|
||||
|
||||
private $onWorkerStart;
|
||||
|
||||
private $onWorkerStop;
|
||||
|
||||
private $onBeforeReload;
|
||||
|
||||
private $onAfterReload;
|
||||
|
||||
private $onWorkerExit;
|
||||
|
||||
private $onWorkerError;
|
||||
|
||||
private $onTask;
|
||||
|
||||
private $onFinish;
|
||||
|
||||
private $onManagerStart;
|
||||
|
||||
private $onManagerStop;
|
||||
|
||||
private $onPipeMessage;
|
||||
|
||||
public $setting;
|
||||
|
||||
public $connections;
|
||||
|
||||
public $host = '';
|
||||
|
||||
public $port = 0;
|
||||
|
||||
public $type = 0;
|
||||
|
||||
public $mode = 0;
|
||||
|
||||
public $ports;
|
||||
|
||||
public $master_pid = 0;
|
||||
|
||||
public $manager_pid = 0;
|
||||
|
||||
public $worker_id = -1;
|
||||
|
||||
public $taskworker = false;
|
||||
|
||||
public $worker_pid = 0;
|
||||
|
||||
public $stats_timer;
|
||||
|
||||
public function __construct($host, $port = null, $mode = null, $sock_type = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function listen($host, $port, $sock_type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function addlistener($host, $port, $sock_type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function on($event_name, callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallback($event_name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($fd, $send_data, $server_socket = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendto($ip, $port, $send_data, $server_socket = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendwait($conn_fd, $send_data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exists($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exist($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function protect($fd, $is_protected = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendfile($conn_fd, $filename, $offset = null, $length = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function close($fd, $reset = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function confirm($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function pause($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function resume($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function task($data, $worker_id = null, ?callable $finish_callback = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function taskwait($data, $timeout = null, $worker_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function taskWaitMulti(array $tasks, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function taskCo(array $tasks, $timeout = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function finish($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function reload()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function stop($worker_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastError()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function heartbeat($reactor_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientInfo($fd, $reactor_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientList($start_fd, $find_count = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWorkerId()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWorkerPid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWorkerStatus($worker_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getManagerPid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMasterPid()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connection_info($fd, $reactor_id = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function connection_list($start_fd, $find_count = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendMessage($message, $dst_worker_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function addProcess(\swoole_process $process)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSocket($port = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function bind($fd, $uid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Server;
|
||||
|
||||
class Port
|
||||
{
|
||||
|
||||
private $onConnect;
|
||||
|
||||
private $onReceive;
|
||||
|
||||
private $onClose;
|
||||
|
||||
private $onPacket;
|
||||
|
||||
private $onBufferFull;
|
||||
|
||||
private $onBufferEmpty;
|
||||
|
||||
private $onRequest;
|
||||
|
||||
private $onHandShake;
|
||||
|
||||
private $onOpen;
|
||||
|
||||
private $onMessage;
|
||||
|
||||
public $host;
|
||||
|
||||
public $port = 0;
|
||||
|
||||
public $type = 0;
|
||||
|
||||
public $sock = -1;
|
||||
|
||||
public $setting;
|
||||
|
||||
public $connections;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function on($event_name, callable $callback)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallback($event_name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Server;
|
||||
|
||||
class Task
|
||||
{
|
||||
|
||||
public $data;
|
||||
|
||||
public $id = -1;
|
||||
|
||||
public $worker_id = -1;
|
||||
|
||||
public $flags = 0;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function finish($data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function pack($data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Table implements \Iterator, \ArrayAccess
|
||||
{
|
||||
|
||||
public const TYPE_INT = 1;
|
||||
|
||||
public const TYPE_STRING = 3;
|
||||
|
||||
public const TYPE_FLOAT = 2;
|
||||
|
||||
public function __construct($table_size, $conflict_proportion = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function column($name, $type, $size = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($key, array $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $field = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function del($key)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exists($key)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function exist($key)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function incr($key, $column, $incrby = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function decr($key, $column, $decrby = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMemorySize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Table;
|
||||
|
||||
class Row implements \ArrayAccess
|
||||
{
|
||||
|
||||
public $key;
|
||||
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Timer
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function set(array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function tick($ms, callable $callback, ... $params)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function after($ms, callable $callback, ... $params)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function exists($timer_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function info($timer_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function stats()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function list()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function clear($timer_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function clearAll()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\Timer;
|
||||
|
||||
class Iterator extends \ArrayIterator
|
||||
{
|
||||
|
||||
public const STD_PROP_LIST = 1;
|
||||
|
||||
public const ARRAY_AS_PROPS = 2;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\WebSocket;
|
||||
|
||||
class CloseFrame extends Frame
|
||||
{
|
||||
|
||||
public $opcode = 8;
|
||||
|
||||
public $code = 1000;
|
||||
|
||||
public $reason = '';
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\WebSocket;
|
||||
|
||||
class Frame
|
||||
{
|
||||
|
||||
public $fd = 0;
|
||||
|
||||
public $data = '';
|
||||
|
||||
public $opcode = 1;
|
||||
|
||||
public $flags = 1;
|
||||
|
||||
public $finish;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function pack($data, $opcode = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function unpack($data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Swoole\WebSocket;
|
||||
|
||||
class Server extends \Swoole\Http\Server
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function push($fd, $data, $opcode = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function disconnect($fd, $code = null, $reason = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isEstablished($fd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function pack($data, $opcode = null, $flags = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function unpack($data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (SWOOLE_USE_SHORTNAME) {
|
||||
class_alias(Swoole\Coroutine\WaitGroup::class, Co\WaitGroup::class, true);
|
||||
class_alias(Swoole\Coroutine\Server::class, Co\Server::class, true);
|
||||
class_alias(Swoole\Coroutine\Server\Connection::class, Co\Server\Connection::class, true);
|
||||
class_alias(Swoole\Coroutine\FastCGI\Client::class, Co\FastCGI\Client::class, true);
|
||||
class_alias(Swoole\Coroutine\FastCGI\Client\Exception::class, Co\FastCGI\Client\Exception::class, true);
|
||||
class_alias(Swoole\Coroutine\FastCGI\Proxy::class, Co\FastCGI\Proxy::class, true);
|
||||
}
|
||||
|
||||
class_alias(Swoole\Process\Manager::class, Swoole\Process\ProcessManager::class, true);
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine {
|
||||
function run(callable $fn, ...$args)
|
||||
{
|
||||
$s = new Scheduler();
|
||||
$s->add($fn, ...$args);
|
||||
return $s->start();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Co {
|
||||
if (SWOOLE_USE_SHORTNAME) {
|
||||
function run(callable $fn, ...$args)
|
||||
{
|
||||
return \Swoole\Coroutine\Run($fn, ...$args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,681 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
use RuntimeException;
|
||||
use Serializable;
|
||||
use Swoole\Exception\ArrayKeyNotExists;
|
||||
|
||||
class ArrayObject implements ArrayAccess, Serializable, Countable, Iterator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $array;
|
||||
|
||||
/**
|
||||
* ArrayObject constructor.
|
||||
*/
|
||||
public function __construct(array $array = [])
|
||||
{
|
||||
$this->array = $array;
|
||||
}
|
||||
|
||||
public function __toArray(): array
|
||||
{
|
||||
return $this->array;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->array;
|
||||
}
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->array);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->array);
|
||||
}
|
||||
|
||||
public function valid(): bool
|
||||
{
|
||||
return array_key_exists($this->key(), $this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
return reset($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return next($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return ArrayObject|StringObject
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (!$this->exists($key)) {
|
||||
throw new ArrayKeyNotExists($key);
|
||||
}
|
||||
return static::detectType($this->array[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
$key = array_key_last($this->array);
|
||||
if ($key === null) {
|
||||
return null;
|
||||
}
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int|string
|
||||
*/
|
||||
public function firstKey()
|
||||
{
|
||||
return array_key_first($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int|string
|
||||
*/
|
||||
public function lastKey()
|
||||
{
|
||||
return array_key_last($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
$key = array_key_first($this->array);
|
||||
if ($key === null) {
|
||||
return null;
|
||||
}
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value): self
|
||||
{
|
||||
$this->array[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return $this
|
||||
*/
|
||||
public function delete($key): self
|
||||
{
|
||||
unset($this->array[$key]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function remove($value, bool $strict = true, bool $loop = false): self
|
||||
{
|
||||
do {
|
||||
$key = $this->search($value, $strict);
|
||||
if ($key === false) {
|
||||
break;
|
||||
}
|
||||
unset($this->array[$key]);
|
||||
} while ($loop);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function clear(): self
|
||||
{
|
||||
$this->array = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return null|mixed
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
if (!array_key_exists($key, $this->array)) {
|
||||
return null;
|
||||
}
|
||||
return $this->array[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function offsetSet($key, $value): void
|
||||
{
|
||||
$this->array[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function offsetUnset($key): void
|
||||
{
|
||||
unset($this->array[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return isset($this->array[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function exists($key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function contains($value, bool $strict = true): bool
|
||||
{
|
||||
return in_array($value, $this->array, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function indexOf($value, bool $strict = true)
|
||||
{
|
||||
return $this->search($value, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastIndexOf($value, bool $strict = true)
|
||||
{
|
||||
$array = $this->array;
|
||||
for (end($array); ($currentKey = key($array)) !== null; prev($array)) {
|
||||
$currentValue = current($array);
|
||||
if ($currentValue == $value) {
|
||||
if ($strict && $currentValue !== $value) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $currentKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $needle
|
||||
* @return mixed
|
||||
*/
|
||||
public function search($needle, bool $strict = true)
|
||||
{
|
||||
return array_search($needle, $this->array, $strict);
|
||||
}
|
||||
|
||||
public function join(string $glue = ''): StringObject
|
||||
{
|
||||
return static::detectStringType(implode($glue, $this->array));
|
||||
}
|
||||
|
||||
public function serialize(): StringObject
|
||||
{
|
||||
return static::detectStringType(serialize($this->array));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return $this
|
||||
*/
|
||||
public function unserialize($string): self
|
||||
{
|
||||
$this->array = (array) unserialize((string) $string);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*/
|
||||
public function sum()
|
||||
{
|
||||
return array_sum($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return array_product($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function push($value)
|
||||
{
|
||||
return $this->pushBack($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function pushFront($value)
|
||||
{
|
||||
return array_unshift($this->array, $value);
|
||||
}
|
||||
|
||||
public function append(...$values): ArrayObject
|
||||
{
|
||||
array_push($this->array, ...$values);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
public function pushBack($value)
|
||||
{
|
||||
return array_push($this->array, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function insert(int $offset, $value): self
|
||||
{
|
||||
if (is_array($value) || is_object($value) || is_null($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
array_splice($this->array, $offset, 0, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
return $this->popBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function popFront()
|
||||
{
|
||||
return array_shift($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function popBack()
|
||||
{
|
||||
return array_pop($this->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param int $length
|
||||
* @return static
|
||||
*/
|
||||
public function slice($offset, int $length = null, bool $preserve_keys = false): self
|
||||
{
|
||||
return new static(array_slice($this->array, ...func_get_args()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayObject|mixed|StringObject
|
||||
*/
|
||||
public function randomGet()
|
||||
{
|
||||
return static::detectType($this->array[array_rand($this->array, 1)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function each(callable $fn): self
|
||||
{
|
||||
if (array_walk($this->array, $fn) === false) {
|
||||
throw new RuntimeException('array_walk() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @return static
|
||||
*/
|
||||
public function map(callable $fn, ...$args): self
|
||||
{
|
||||
return new static(array_map($fn, $this->array, ...$args));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $initial
|
||||
* @return mixed
|
||||
*/
|
||||
public function reduce(callable $fn, $initial = null)
|
||||
{
|
||||
return array_reduce($this->array, $fn, $initial);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @return static
|
||||
*/
|
||||
public function keys(...$args): self
|
||||
{
|
||||
return new static(array_keys($this->array, ...$args));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function values(): self
|
||||
{
|
||||
return new static(array_values($this->array));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $column_key
|
||||
* @param mixed $index
|
||||
* @return static
|
||||
*/
|
||||
public function column($column_key, $index = null): self
|
||||
{
|
||||
return new static(array_column($this->array, $column_key, $index));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function unique(int $sort_flags = SORT_STRING): self
|
||||
{
|
||||
return new static(array_unique($this->array, $sort_flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function reverse(bool $preserve_keys = false): self
|
||||
{
|
||||
return new static(array_reverse($this->array, $preserve_keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function chunk(int $size, bool $preserve_keys = false): self
|
||||
{
|
||||
return new static(array_chunk($this->array, $size, $preserve_keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap keys and values in an array.
|
||||
* @return static
|
||||
*/
|
||||
public function flip(): self
|
||||
{
|
||||
return new static(array_flip($this->array));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function filter(callable $fn, int $flag = 0): self
|
||||
{
|
||||
return new static(array_filter($this->array, $fn, $flag));
|
||||
}
|
||||
|
||||
/**
|
||||
* | Function name | Sorts by | Maintains key association | Order of sort | Related functions |
|
||||
* | :---------------- | :------- | :-------------------------- | :-------------------------- | :---------------- |
|
||||
* | array_multisort() | value | associative yes, numeric no | first array or sort options | array_walk() |
|
||||
* | asort() | value | yes | low to high | arsort() |
|
||||
* | arsort() | value | yes | high to low | asort() |
|
||||
* | krsort() | key | yes | high to low | ksort() |
|
||||
* | ksort() | key | yes | low to high | asort() |
|
||||
* | natcasesort() | value | yes | natural, case insensitive | natsort() |
|
||||
* | natsort() | value | yes | natural | natcasesort() |
|
||||
* | rsort() | value | no | high to low | sort() |
|
||||
* | shuffle() | value | no | random | array_rand() |
|
||||
* | sort() | value | no | low to high | rsort() |
|
||||
* | uasort() | value | yes | user defined | uksort() |
|
||||
* | uksort() | key | yes | user defined | uasort() |
|
||||
* | usort() | value | no | user defined | uasort() |
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function asort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (asort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('asort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function arsort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (arsort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('arsort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function krsort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (krsort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('krsort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function ksort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (ksort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('ksort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function natcasesort(): self
|
||||
{
|
||||
if (natcasesort($this->array) !== true) {
|
||||
throw new RuntimeException('natcasesort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function natsort(): self
|
||||
{
|
||||
if (natsort($this->array) !== true) {
|
||||
throw new RuntimeException('natsort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function rsort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (rsort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('rsort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function shuffle(): self
|
||||
{
|
||||
if (shuffle($this->array) !== true) {
|
||||
throw new RuntimeException('shuffle() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function sort(int $sort_flags = SORT_REGULAR): self
|
||||
{
|
||||
if (sort($this->array, $sort_flags) !== true) {
|
||||
throw new RuntimeException('sort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function uasort(callable $value_compare_func): self
|
||||
{
|
||||
if (uasort($this->array, $value_compare_func) !== true) {
|
||||
throw new RuntimeException('uasort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function uksort(callable $value_compare_func): self
|
||||
{
|
||||
if (uksort($this->array, $value_compare_func) !== true) {
|
||||
throw new RuntimeException('uksort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function usort(callable $value_compare_func): self
|
||||
{
|
||||
if (usort($this->array, $value_compare_func) !== true) {
|
||||
throw new RuntimeException('usort() failed');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return ArrayObject|mixed|StringObject
|
||||
*/
|
||||
protected static function detectType($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return static::detectStringType($value);
|
||||
}
|
||||
if (is_array($value)) {
|
||||
return static::detectArrayType($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected static function detectStringType(string $value): StringObject
|
||||
{
|
||||
return new StringObject($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
protected static function detectArrayType(array $value): self
|
||||
{
|
||||
return new static($value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
use RuntimeException;
|
||||
use Swoole\Coroutine\Channel;
|
||||
use Throwable;
|
||||
|
||||
class ConnectionPool
|
||||
{
|
||||
public const DEFAULT_SIZE = 64;
|
||||
|
||||
/** @var Channel */
|
||||
protected $pool;
|
||||
|
||||
/** @var callable */
|
||||
protected $constructor;
|
||||
|
||||
/** @var int */
|
||||
protected $size;
|
||||
|
||||
/** @var int */
|
||||
protected $num;
|
||||
|
||||
/** @var null|string */
|
||||
protected $proxy;
|
||||
|
||||
public function __construct(callable $constructor, int $size = self::DEFAULT_SIZE, ?string $proxy = null)
|
||||
{
|
||||
$this->pool = new Channel($this->size = $size);
|
||||
$this->constructor = $constructor;
|
||||
$this->num = 0;
|
||||
$this->proxy = $proxy;
|
||||
}
|
||||
|
||||
public function fill(): void
|
||||
{
|
||||
while ($this->size > $this->num) {
|
||||
$this->make();
|
||||
}
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
if ($this->pool === null) {
|
||||
throw new RuntimeException('Pool has been closed');
|
||||
}
|
||||
if ($this->pool->isEmpty() && $this->num < $this->size) {
|
||||
$this->make();
|
||||
}
|
||||
return $this->pool->pop();
|
||||
}
|
||||
|
||||
public function put($connection): void
|
||||
{
|
||||
if ($this->pool === null) {
|
||||
return;
|
||||
}
|
||||
if ($connection !== null) {
|
||||
$this->pool->push($connection);
|
||||
} else {
|
||||
/* connection broken */
|
||||
$this->num -= 1;
|
||||
$this->make();
|
||||
}
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
$this->pool->close();
|
||||
$this->pool = null;
|
||||
$this->num = 0;
|
||||
}
|
||||
|
||||
protected function make(): void
|
||||
{
|
||||
$this->num++;
|
||||
try {
|
||||
if ($this->proxy) {
|
||||
$connection = new $this->proxy($this->constructor);
|
||||
} else {
|
||||
$constructor = $this->constructor;
|
||||
$connection = $constructor();
|
||||
}
|
||||
} catch (Throwable $throwable) {
|
||||
$this->num--;
|
||||
throw $throwable;
|
||||
}
|
||||
$this->put($connection);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,404 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class Constant
|
||||
{
|
||||
public const EVENT_RECEIVE = 'receive';
|
||||
|
||||
public const EVENT_CONNECT = 'connect';
|
||||
|
||||
public const EVENT_CLOSE = 'close';
|
||||
|
||||
public const EVENT_PACKET = 'packet';
|
||||
|
||||
public const EVENT_REQUEST = 'request';
|
||||
|
||||
public const EVENT_MESSAGE = 'message';
|
||||
|
||||
public const EVENT_OPEN = 'open';
|
||||
|
||||
public const EVENT_HANDSHAKE = 'handshake';
|
||||
|
||||
public const EVENT_TASK = 'task';
|
||||
|
||||
public const EVENT_FINISH = 'finish';
|
||||
|
||||
public const EVENT_START = 'start';
|
||||
|
||||
public const EVENT_SHUTDOWN = 'shutdown';
|
||||
|
||||
public const EVENT_WORKER_START = 'workerStart';
|
||||
|
||||
public const EVENT_WORKER_EXIT = 'workerExit';
|
||||
|
||||
public const EVENT_WORKER_ERROR = 'workerError';
|
||||
|
||||
public const EVENT_WORKER_STOP = 'workerStop';
|
||||
|
||||
public const EVENT_PIPE_MESSAGE = 'pipeMessage';
|
||||
|
||||
public const EVENT_MANAGER_START = 'managerStart';
|
||||
|
||||
public const EVENT_MANAGER_STOP = 'managerStop';
|
||||
|
||||
public const EVENT_ERROR = 'error';
|
||||
|
||||
/* {{{ OPTION */
|
||||
public const OPTION_DEBUG_MODE = 'debug_mode';
|
||||
|
||||
public const OPTION_TRACE_FLAGS = 'trace_flags';
|
||||
|
||||
public const OPTION_LOG_FILE = 'log_file';
|
||||
|
||||
public const OPTION_LOG_LEVEL = 'log_level';
|
||||
|
||||
public const OPTION_LOG_DATE_FORMAT = 'log_date_format';
|
||||
|
||||
public const OPTION_LOG_DATE_WITH_MICROSECONDS = 'log_date_with_microseconds';
|
||||
|
||||
public const OPTION_LOG_ROTATION = 'log_rotation';
|
||||
|
||||
public const OPTION_DISPLAY_ERRORS = 'display_errors';
|
||||
|
||||
public const OPTION_DNS_SERVER = 'dns_server';
|
||||
|
||||
public const OPTION_SOCKET_DNS_TIMEOUT = 'socket_dns_timeout';
|
||||
|
||||
public const OPTION_SOCKET_CONNECT_TIMEOUT = 'socket_connect_timeout';
|
||||
|
||||
public const OPTION_SOCKET_WRITE_TIMEOUT = 'socket_write_timeout';
|
||||
|
||||
public const OPTION_SOCKET_SEND_TIMEOUT = 'socket_send_timeout';
|
||||
|
||||
public const OPTION_SOCKET_READ_TIMEOUT = 'socket_read_timeout';
|
||||
|
||||
public const OPTION_SOCKET_RECV_TIMEOUT = 'socket_recv_timeout';
|
||||
|
||||
public const OPTION_SOCKET_BUFFER_SIZE = 'socket_buffer_size';
|
||||
|
||||
public const OPTION_SOCKET_TIMEOUT = 'socket_timeout';
|
||||
|
||||
public const OPTION_ENABLE_SIGNALFD = 'enable_signalfd';
|
||||
|
||||
public const OPTION_WAIT_SIGNAL = 'wait_signal';
|
||||
|
||||
public const OPTION_DNS_CACHE_REFRESH_TIME = 'dns_cache_refresh_time';
|
||||
|
||||
public const OPTION_THREAD_NUM = 'thread_num';
|
||||
|
||||
public const OPTION_MIN_THREAD_NUM = 'min_thread_num';
|
||||
|
||||
public const OPTION_MAX_THREAD_NUM = 'max_thread_num';
|
||||
|
||||
public const OPTION_SOCKET_DONTWAIT = 'socket_dontwait';
|
||||
|
||||
public const OPTION_DNS_LOOKUP_RANDOM = 'dns_lookup_random';
|
||||
|
||||
public const OPTION_USE_ASYNC_RESOLVER = 'use_async_resolver';
|
||||
|
||||
public const OPTION_ENABLE_COROUTINE = 'enable_coroutine';
|
||||
|
||||
public const OPTION_SSL_PROTOCOLS = 'ssl_protocols';
|
||||
|
||||
public const OPTION_SSL_COMPRESS = 'ssl_compress';
|
||||
|
||||
public const OPTION_SSL_CERT_FILE = 'ssl_cert_file';
|
||||
|
||||
public const OPTION_SSL_KEY_FILE = 'ssl_key_file';
|
||||
|
||||
public const OPTION_SSL_PASSPHRASE = 'ssl_passphrase';
|
||||
|
||||
public const OPTION_SSL_HOST_NAME = 'ssl_host_name';
|
||||
|
||||
public const OPTION_SSL_VERIFY_PEER = 'ssl_verify_peer';
|
||||
|
||||
public const OPTION_SSL_ALLOW_SELF_SIGNED = 'ssl_allow_self_signed';
|
||||
|
||||
public const OPTION_SSL_CAFILE = 'ssl_cafile';
|
||||
|
||||
public const OPTION_SSL_CAPATH = 'ssl_capath';
|
||||
|
||||
public const OPTION_SSL_VERIFY_DEPTH = 'ssl_verify_depth';
|
||||
|
||||
public const OPTION_OPEN_EOF_CHECK = 'open_eof_check';
|
||||
|
||||
public const OPTION_OPEN_EOF_SPLIT = 'open_eof_split';
|
||||
|
||||
public const OPTION_PACKAGE_EOF = 'package_eof';
|
||||
|
||||
public const OPTION_OPEN_MQTT_PROTOCOL = 'open_mqtt_protocol';
|
||||
|
||||
public const OPTION_OPEN_LENGTH_CHECK = 'open_length_check';
|
||||
|
||||
public const OPTION_PACKAGE_LENGTH_TYPE = 'package_length_type';
|
||||
|
||||
public const OPTION_PACKAGE_LENGTH_OFFSET = 'package_length_offset';
|
||||
|
||||
public const OPTION_PACKAGE_BODY_OFFSET = 'package_body_offset';
|
||||
|
||||
public const OPTION_PACKAGE_LENGTH_FUNC = 'package_length_func';
|
||||
|
||||
public const OPTION_PACKAGE_MAX_LENGTH = 'package_max_length';
|
||||
|
||||
public const OPTION_BUFFER_HIGH_WATERMARK = 'buffer_high_watermark';
|
||||
|
||||
public const OPTION_BUFFER_LOW_WATERMARK = 'buffer_low_watermark';
|
||||
|
||||
public const OPTION_BIND_PORT = 'bind_port';
|
||||
|
||||
public const OPTION_BIND_ADDRESS = 'bind_address';
|
||||
|
||||
public const OPTION_OPEN_TCP_NODELAY = 'open_tcp_nodelay';
|
||||
|
||||
public const OPTION_SOCKS5_HOST = 'socks5_host';
|
||||
|
||||
public const OPTION_SOCKS5_PORT = 'socks5_port';
|
||||
|
||||
public const OPTION_SOCKS5_USERNAME = 'socks5_username';
|
||||
|
||||
public const OPTION_SOCKS5_PASSWORD = 'socks5_password';
|
||||
|
||||
public const OPTION_HTTP_PROXY_HOST = 'http_proxy_host';
|
||||
|
||||
public const OPTION_HTTP_PROXY_PORT = 'http_proxy_port';
|
||||
|
||||
public const OPTION_HTTP_PROXY_USERNAME = 'http_proxy_username';
|
||||
|
||||
public const OPTION_HTTP_PROXY_USER = 'http_proxy_user';
|
||||
|
||||
public const OPTION_HTTP_PROXY_PASSWORD = 'http_proxy_password';
|
||||
|
||||
public const OPTION_TIMEOUT = 'timeout';
|
||||
|
||||
public const OPTION_CONNECT_TIMEOUT = 'connect_timeout';
|
||||
|
||||
public const OPTION_READ_TIMEOUT = 'read_timeout';
|
||||
|
||||
public const OPTION_WRITE_TIMEOUT = 'write_timeout';
|
||||
|
||||
public const OPTION_SSL_DISABLE_COMPRESSION = 'ssl_disable_compression';
|
||||
|
||||
public const OPTION_MAX_COROUTINE = 'max_coroutine';
|
||||
|
||||
public const OPTION_HOOK_FLAGS = 'hook_flags';
|
||||
|
||||
public const OPTION_ENABLE_PREEMPTIVE_SCHEDULER = 'enable_preemptive_scheduler';
|
||||
|
||||
public const OPTION_C_STACK_SIZE = 'c_stack_size';
|
||||
|
||||
public const OPTION_STACK_SIZE = 'stack_size';
|
||||
|
||||
public const OPTION_DNS_CACHE_EXPIRE = 'dns_cache_expire';
|
||||
|
||||
public const OPTION_DNS_CACHE_CAPACITY = 'dns_cache_capacity';
|
||||
|
||||
public const OPTION_AIO_CORE_WORKER_NUM = 'aio_core_worker_num';
|
||||
|
||||
public const OPTION_AIO_WORKER_NUM = 'aio_worker_num';
|
||||
|
||||
public const OPTION_AIO_MAX_WAIT_TIME = 'aio_max_wait_time';
|
||||
|
||||
public const OPTION_AIO_MAX_IDLE_TIME = 'aio_max_idle_time';
|
||||
|
||||
public const OPTION_RECONNECT = 'reconnect';
|
||||
|
||||
public const OPTION_DEFER = 'defer';
|
||||
|
||||
public const OPTION_LOWERCASE_HEADER = 'lowercase_header';
|
||||
|
||||
public const OPTION_KEEP_ALIVE = 'keep_alive';
|
||||
|
||||
public const OPTION_WEBSOCKET_MASK = 'websocket_mask';
|
||||
|
||||
public const OPTION_WEBSOCKET_COMPRESSION = 'websocket_compression';
|
||||
|
||||
public const OPTION_HTTP_PARSE_COOKIE = 'http_parse_cookie';
|
||||
|
||||
public const OPTION_HTTP_PARSE_POST = 'http_parse_post';
|
||||
|
||||
public const OPTION_HTTP_PARSE_FILES = 'http_parse_files';
|
||||
|
||||
public const OPTION_HTTP_COMPRESSION = 'http_compression';
|
||||
|
||||
public const OPTION_HTTP_COMPRESSION_LEVEL = 'http_compression_level';
|
||||
|
||||
public const OPTION_HTTP_GZIP_LEVEL = 'http_gzip_level';
|
||||
|
||||
public const OPTION_UPLOAD_TMP_DIR = 'upload_tmp_dir';
|
||||
|
||||
public const OPTION_HOST = 'host';
|
||||
|
||||
public const OPTION_PORT = 'port';
|
||||
|
||||
public const OPTION_SSL = 'ssl';
|
||||
|
||||
public const OPTION_USER = 'user';
|
||||
|
||||
public const OPTION_PASSWORD = 'password';
|
||||
|
||||
public const OPTION_DATABASE = 'database';
|
||||
|
||||
public const OPTION_CHARSET = 'charset';
|
||||
|
||||
public const OPTION_STRICT_TYPE = 'strict_type';
|
||||
|
||||
public const OPTION_FETCH_MODE = 'fetch_mode';
|
||||
|
||||
public const OPTION_SERIALIZE = 'serialize';
|
||||
|
||||
public const OPTION_COMPATIBILITY_MODE = 'compatibility_mode';
|
||||
|
||||
public const OPTION_CHROOT = 'chroot';
|
||||
|
||||
public const OPTION_GROUP = 'group';
|
||||
|
||||
public const OPTION_DAEMONIZE = 'daemonize';
|
||||
|
||||
public const OPTION_PID_FILE = 'pid_file';
|
||||
|
||||
public const OPTION_REACTOR_NUM = 'reactor_num';
|
||||
|
||||
public const OPTION_SINGLE_THREAD = 'single_thread';
|
||||
|
||||
public const OPTION_WORKER_NUM = 'worker_num';
|
||||
|
||||
public const OPTION_MAX_WAIT_TIME = 'max_wait_time';
|
||||
|
||||
public const OPTION_MAX_QUEUED_BYTES = 'max_queued_bytes';
|
||||
|
||||
public const OPTION_MAX_CORO_NUM = 'max_coro_num';
|
||||
|
||||
public const OPTION_SEND_TIMEOUT = 'send_timeout';
|
||||
|
||||
public const OPTION_DISPATCH_MODE = 'dispatch_mode';
|
||||
|
||||
public const OPTION_SEND_YIELD = 'send_yield';
|
||||
|
||||
public const OPTION_DISPATCH_FUNC = 'dispatch_func';
|
||||
|
||||
public const OPTION_DISCARD_TIMEOUT_REQUEST = 'discard_timeout_request';
|
||||
|
||||
public const OPTION_ENABLE_UNSAFE_EVENT = 'enable_unsafe_event';
|
||||
|
||||
public const OPTION_ENABLE_DELAY_RECEIVE = 'enable_delay_receive';
|
||||
|
||||
public const OPTION_ENABLE_REUSE_PORT = 'enable_reuse_port';
|
||||
|
||||
public const OPTION_TASK_USE_OBJECT = 'task_use_object';
|
||||
|
||||
public const OPTION_TASK_ENABLE_COROUTINE = 'task_enable_coroutine';
|
||||
|
||||
public const OPTION_TASK_WORKER_NUM = 'task_worker_num';
|
||||
|
||||
public const OPTION_TASK_IPC_MODE = 'task_ipc_mode';
|
||||
|
||||
public const OPTION_TASK_TMPDIR = 'task_tmpdir';
|
||||
|
||||
public const OPTION_TASK_MAX_REQUEST = 'task_max_request';
|
||||
|
||||
public const OPTION_TASK_MAX_REQUEST_GRACE = 'task_max_request_grace';
|
||||
|
||||
public const OPTION_MAX_CONNECTION = 'max_connection';
|
||||
|
||||
public const OPTION_MAX_CONN = 'max_conn';
|
||||
|
||||
public const OPTION_HEARTBEAT_CHECK_INTERVAL = 'heartbeat_check_interval';
|
||||
|
||||
public const OPTION_HEARTBEAT_IDLE_TIME = 'heartbeat_idle_time';
|
||||
|
||||
public const OPTION_MAX_REQUEST = 'max_request';
|
||||
|
||||
public const OPTION_MAX_REQUEST_GRACE = 'max_request_grace';
|
||||
|
||||
public const OPTION_RELOAD_ASYNC = 'reload_async';
|
||||
|
||||
public const OPTION_OPEN_CPU_AFFINITY = 'open_cpu_affinity';
|
||||
|
||||
public const OPTION_CPU_AFFINITY_IGNORE = 'cpu_affinity_ignore';
|
||||
|
||||
public const OPTION_ENABLE_STATIC_HANDLER = 'enable_static_handler';
|
||||
|
||||
public const OPTION_DOCUMENT_ROOT = 'document_root';
|
||||
|
||||
public const OPTION_HTTP_AUTOINDEX = 'http_autoindex';
|
||||
|
||||
public const OPTION_HTTP_INDEX_FILES = 'http_index_files';
|
||||
|
||||
public const OPTION_STATIC_HANDLER_LOCATIONS = 'static_handler_locations';
|
||||
|
||||
public const OPTION_INPUT_BUFFER_SIZE = 'input_buffer_size';
|
||||
|
||||
public const OPTION_BUFFER_INPUT_SIZE = 'buffer_input_size';
|
||||
|
||||
public const OPTION_OUTPUT_BUFFER_SIZE = 'output_buffer_size';
|
||||
|
||||
public const OPTION_BUFFER_OUTPUT_SIZE = 'buffer_output_size';
|
||||
|
||||
public const OPTION_MESSAGE_QUEUE_KEY = 'message_queue_key';
|
||||
|
||||
public const OPTION_BACKLOG = 'backlog';
|
||||
|
||||
public const OPTION_KERNEL_SOCKET_RECV_BUFFER_SIZE = 'kernel_socket_recv_buffer_size';
|
||||
|
||||
public const OPTION_KERNEL_SOCKET_SEND_BUFFER_SIZE = 'kernel_socket_send_buffer_size';
|
||||
|
||||
public const OPTION_TCP_DEFER_ACCEPT = 'tcp_defer_accept';
|
||||
|
||||
public const OPTION_OPEN_TCP_KEEPALIVE = 'open_tcp_keepalive';
|
||||
|
||||
public const OPTION_OPEN_HTTP_PROTOCOL = 'open_http_protocol';
|
||||
|
||||
public const OPTION_OPEN_WEBSOCKET_PROTOCOL = 'open_websocket_protocol';
|
||||
|
||||
public const OPTION_WEBSOCKET_SUBPROTOCOL = 'websocket_subprotocol';
|
||||
|
||||
public const OPTION_OPEN_WEBSOCKET_CLOSE_FRAME = 'open_websocket_close_frame';
|
||||
|
||||
public const OPTION_OPEN_WEBSOCKET_PING_FRAME = 'open_websocket_ping_frame';
|
||||
|
||||
public const OPTION_OPEN_WEBSOCKET_PONG_FRAME = 'open_websocket_pong_frame';
|
||||
|
||||
public const OPTION_OPEN_HTTP2_PROTOCOL = 'open_http2_protocol';
|
||||
|
||||
public const OPTION_OPEN_REDIS_PROTOCOL = 'open_redis_protocol';
|
||||
|
||||
public const OPTION_MAX_IDLE_TIME = 'max_idle_time';
|
||||
|
||||
public const OPTION_TCP_KEEPIDLE = 'tcp_keepidle';
|
||||
|
||||
public const OPTION_TCP_KEEPINTERVAL = 'tcp_keepinterval';
|
||||
|
||||
public const OPTION_TCP_KEEPCOUNT = 'tcp_keepcount';
|
||||
|
||||
public const OPTION_TCP_USER_TIMEOUT = 'tcp_user_timeout';
|
||||
|
||||
public const OPTION_TCP_FASTOPEN = 'tcp_fastopen';
|
||||
|
||||
public const OPTION_PACKAGE_BODY_START = 'package_body_start';
|
||||
|
||||
public const OPTION_SSL_CLIENT_CERT_FILE = 'ssl_client_cert_file';
|
||||
|
||||
public const OPTION_SSL_PREFER_SERVER_CIPHERS = 'ssl_prefer_server_ciphers';
|
||||
|
||||
public const OPTION_SSL_CIPHERS = 'ssl_ciphers';
|
||||
|
||||
public const OPTION_SSL_ECDH_CURVE = 'ssl_ecdh_curve';
|
||||
|
||||
public const OPTION_SSL_DHPARAM = 'ssl_dhparam';
|
||||
|
||||
public const OPTION_OPEN_SSL = 'open_ssl';
|
||||
|
||||
public const OPTION_OPEN_FASTCGI_PROTOCOL = 'open_fastcgi_protocol';
|
||||
|
||||
/* }}} OPTION */
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Exception;
|
||||
use Swoole\Timer;
|
||||
|
||||
class Barrier
|
||||
{
|
||||
private $cid = -1;
|
||||
|
||||
private $timer = -1;
|
||||
|
||||
private static $cancel_list = [];
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->timer != -1) {
|
||||
Timer::clear($this->timer);
|
||||
if (static::$cancel_list[$this->cid]) {
|
||||
unset(static::$cancel_list[$this->cid]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($this->cid != -1) {
|
||||
Coroutine::resume($this->cid);
|
||||
}
|
||||
}
|
||||
|
||||
public static function make()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function wait(Barrier &$barrier, float $timeout = -1)
|
||||
{
|
||||
if ($barrier->cid != -1) {
|
||||
throw new Exception('The barrier is waiting, cannot wait again.');
|
||||
}
|
||||
$cid = Coroutine::getCid();
|
||||
$barrier->cid = $cid;
|
||||
if ($timeout > 0 && ($timeout_ms = intval($timeout * 1000)) > 0) {
|
||||
$barrier->timer = Timer::after($timeout_ms, function () use ($cid) {
|
||||
self::$cancel_list[$cid] = true;
|
||||
Coroutine::resume($cid);
|
||||
});
|
||||
}
|
||||
$barrier = null;
|
||||
Coroutine::yield();
|
||||
}
|
||||
}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine\FastCGI;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Swoole\Coroutine\FastCGI\Client\Exception;
|
||||
use Swoole\Coroutine\Socket;
|
||||
use Swoole\FastCGI\FrameParser;
|
||||
use Swoole\FastCGI\HttpRequest;
|
||||
use Swoole\FastCGI\HttpResponse;
|
||||
use Swoole\FastCGI\Record\EndRequest;
|
||||
use Swoole\FastCGI\Request;
|
||||
use Swoole\FastCGI\Response;
|
||||
|
||||
class Client
|
||||
{
|
||||
/** @var int */
|
||||
protected $af;
|
||||
|
||||
/** @var string */
|
||||
protected $host;
|
||||
|
||||
/** @var int */
|
||||
protected $port;
|
||||
|
||||
/** @var bool */
|
||||
protected $ssl;
|
||||
|
||||
/** @var Socket */
|
||||
protected $socket;
|
||||
|
||||
public function __construct(string $host, int $port = 0, bool $ssl = false)
|
||||
{
|
||||
if (stripos($host, 'unix:/') === 0) {
|
||||
$this->af = AF_UNIX;
|
||||
$host = '/' . ltrim(substr($host, strlen('unix:/')), '/');
|
||||
$port = 0;
|
||||
} elseif (strpos($host, ':') !== false) {
|
||||
$this->af = AF_INET6;
|
||||
} else {
|
||||
$this->af = AF_INET;
|
||||
}
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->ssl = $ssl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return HttpResponse|Response
|
||||
*/
|
||||
public function execute(Request $request, float $timeout = -1): Response
|
||||
{
|
||||
if (!$this->socket) {
|
||||
$this->socket = $socket = new Socket($this->af, SOCK_STREAM, IPPROTO_IP);
|
||||
$socket->setProtocol([
|
||||
'open_ssl' => $this->ssl,
|
||||
'open_fastcgi_protocol' => true,
|
||||
]);
|
||||
if (!$socket->connect($this->host, $this->port, $timeout)) {
|
||||
$this->ioException();
|
||||
}
|
||||
} else {
|
||||
$socket = $this->socket;
|
||||
}
|
||||
$sendData = (string) $request;
|
||||
if ($socket->sendAll($sendData) !== strlen($sendData)) {
|
||||
$this->ioException();
|
||||
}
|
||||
$records = [];
|
||||
while (true) {
|
||||
if (SWOOLE_VERSION_ID < 40500) {
|
||||
$recvData = '';
|
||||
while (true) {
|
||||
$tmp = $socket->recv(8192, $timeout);
|
||||
if (!$tmp) {
|
||||
if ($tmp === '') {
|
||||
$this->ioException(SOCKET_ECONNRESET);
|
||||
}
|
||||
$this->ioException();
|
||||
}
|
||||
$recvData .= $tmp;
|
||||
if (FrameParser::hasFrame($recvData)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$recvData = $socket->recvPacket($timeout);
|
||||
if (!$recvData) {
|
||||
if ($recvData === '') {
|
||||
$this->ioException(SOCKET_ECONNRESET);
|
||||
}
|
||||
$this->ioException();
|
||||
}
|
||||
if (!FrameParser::hasFrame($recvData)) {
|
||||
$this->ioException(SOCKET_EPROTO);
|
||||
}
|
||||
}
|
||||
do {
|
||||
$records[] = $record = FrameParser::parseFrame($recvData);
|
||||
} while (strlen($recvData) !== 0);
|
||||
if ($record instanceof EndRequest) {
|
||||
if (!$request->getKeepConn()) {
|
||||
$this->socket->close();
|
||||
$this->socket = null;
|
||||
}
|
||||
switch (true) {
|
||||
case $request instanceof HttpRequest:
|
||||
return new HttpResponse($records);
|
||||
default:
|
||||
return new Response($records);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* never here */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
public static function parseUrl(string $url): array
|
||||
{
|
||||
$url = parse_url($url);
|
||||
$host = $url['host'] ?? '';
|
||||
$port = $url['port'] ?? 0;
|
||||
if (empty($host)) {
|
||||
$host = $url['path'] ?? '';
|
||||
if (empty($host)) {
|
||||
throw new InvalidArgumentException('Invalid url');
|
||||
}
|
||||
$host = "unix:/{$host}";
|
||||
}
|
||||
return [$host, $port];
|
||||
}
|
||||
|
||||
public static function call(string $url, string $path, $data = '', float $timeout = -1): string
|
||||
{
|
||||
$client = new Client(...static::parseUrl($url));
|
||||
$pathInfo = parse_url($path);
|
||||
$path = $pathInfo['path'] ?? '';
|
||||
$root = dirname($path);
|
||||
$scriptName = '/' . basename($path);
|
||||
$documentUri = $scriptName;
|
||||
$query = $pathInfo['query'] ?? '';
|
||||
$requestUri = $query ? "{$documentUri}?{$query}" : $documentUri;
|
||||
$request = new HttpRequest();
|
||||
$request->withDocumentRoot($root)
|
||||
->withScriptFilename($path)
|
||||
->withScriptName($documentUri)
|
||||
->withDocumentUri($documentUri)
|
||||
->withRequestUri($requestUri)
|
||||
->withQueryString($query)
|
||||
->withBody($data)
|
||||
->withMethod($request->getContentLength() === 0 ? 'GET' : 'POST');
|
||||
$response = $client->execute($request, $timeout);
|
||||
return $response->getBody();
|
||||
}
|
||||
|
||||
protected function ioException(?int $errno = null): void
|
||||
{
|
||||
$socket = $this->socket;
|
||||
if ($errno !== null) {
|
||||
$socket->errCode = $errno;
|
||||
$socket->errMsg = swoole_strerror($errno);
|
||||
}
|
||||
$socket->close();
|
||||
$this->socket = null;
|
||||
throw new Exception($socket->errMsg, $socket->errCode);
|
||||
}
|
||||
}
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine\FastCGI\Client;
|
||||
|
||||
class Exception extends \Swoole\Exception
|
||||
{
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine\FastCGI;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Swoole\FastCGI\HttpRequest;
|
||||
use Swoole\FastCGI\HttpResponse;
|
||||
use Swoole\Http;
|
||||
|
||||
class Proxy
|
||||
{
|
||||
/* @var string */
|
||||
protected $host;
|
||||
|
||||
/* @var int */
|
||||
protected $port;
|
||||
|
||||
/* @var float */
|
||||
protected $timeout = -1;
|
||||
|
||||
/* @var string */
|
||||
protected $documentRoot;
|
||||
|
||||
/* @var bool */
|
||||
protected $https = false;
|
||||
|
||||
/* @var string */
|
||||
protected $index = 'index.php';
|
||||
|
||||
/* @var array */
|
||||
protected $params = [];
|
||||
|
||||
/* @var null|callable */
|
||||
protected $staticFileFilter;
|
||||
|
||||
public function __construct(string $url, string $documentRoot = '/')
|
||||
{
|
||||
[$this->host, $this->port] = Client::parseUrl($url);
|
||||
$this->documentRoot = $documentRoot;
|
||||
$this->staticFileFilter = [$this, 'staticFileFiltrate'];
|
||||
}
|
||||
|
||||
public function withTimeout(float $timeout): self
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withHttps(bool $https): self
|
||||
{
|
||||
$this->https = $https;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withIndex(string $index): self
|
||||
{
|
||||
$this->index = $index;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParam(string $name): ?string
|
||||
{
|
||||
return $this->params[$name] ?? null;
|
||||
}
|
||||
|
||||
public function withParam(string $name, string $value): self
|
||||
{
|
||||
$this->params[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutParam(string $name): self
|
||||
{
|
||||
unset($this->params[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParams(): array
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function withParams(array $params): self
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withAddedParams(array $params): self
|
||||
{
|
||||
$this->params = $params + $this->params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withStaticFileFilter(?callable $filter): self
|
||||
{
|
||||
$this->staticFileFilter = $filter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function translateRequest($userRequest): HttpRequest
|
||||
{
|
||||
$request = new HttpRequest();
|
||||
if ($userRequest instanceof \Swoole\Http\Request) {
|
||||
$server = $userRequest->server;
|
||||
$headers = $userRequest->header;
|
||||
$pathInfo = $userRequest->server['path_info'];
|
||||
$pathInfo = '/' . (ltrim($pathInfo, '/'));
|
||||
if (strlen($this->index) !== 0) {
|
||||
$extension = pathinfo($pathInfo, PATHINFO_EXTENSION);
|
||||
if (empty($extension)) {
|
||||
$pathInfo = rtrim($pathInfo, '/') . '/' . $this->index;
|
||||
}
|
||||
}
|
||||
$requestUri = $scriptName = $documentUri = $server['request_uri'];
|
||||
$queryString = $server['query_string'] ?? '';
|
||||
if (strlen($queryString) !== 0) {
|
||||
$requestUri .= "?{$server['query_string']}";
|
||||
}
|
||||
$request
|
||||
->withDocumentRoot($this->documentRoot)
|
||||
->withScriptFilename($this->documentRoot . $pathInfo)
|
||||
->withScriptName($scriptName)
|
||||
->withDocumentUri($documentUri)
|
||||
->withServerProtocol($server['server_protocol'])
|
||||
->withServerAddr('127.0.0.1')
|
||||
->withServerPort($server['server_port'])
|
||||
->withRemoteAddr($server['remote_addr'])
|
||||
->withRemotePort($server['remote_port'])
|
||||
->withMethod($server['request_method'])
|
||||
->withRequestUri($requestUri)
|
||||
->withQueryString($queryString)
|
||||
->withContentType($headers['content-type'] ?? '')
|
||||
->withContentLength((int) ($headers['content-length'] ?? 0))
|
||||
->withHeaders($headers)
|
||||
->withBody($userRequest->rawContent())
|
||||
->withAddedParams($this->params);
|
||||
if ($this->https) {
|
||||
$request->withParam('HTTPS', '1');
|
||||
}
|
||||
} else {
|
||||
throw new InvalidArgumentException('Not supported on ' . get_class($userRequest));
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function translateResponse(HttpResponse $response, $userResponse): void
|
||||
{
|
||||
if ($userResponse instanceof \Swoole\Http\Response) {
|
||||
$userResponse->status($response->getStatusCode(), $response->getReasonPhrase());
|
||||
$userResponse->header = $response->getHeaders();
|
||||
$userResponse->cookie = $response->getSetCookieHeaderLines();
|
||||
$userResponse->end($response->getBody());
|
||||
} else {
|
||||
throw new InvalidArgumentException('Not supported on ' . get_class($userResponse));
|
||||
}
|
||||
}
|
||||
|
||||
public function pass($userRequest, $userResponse): void
|
||||
{
|
||||
if (!($userRequest instanceof HttpRequest)) {
|
||||
$request = $this->translateRequest($userRequest);
|
||||
} else {
|
||||
$request = $userRequest;
|
||||
}
|
||||
unset($userRequest);
|
||||
if ($this->staticFileFilter) {
|
||||
$filter = $this->staticFileFilter;
|
||||
if ($filter($request, $userResponse)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$client = new Client($this->host, $this->port);
|
||||
$response = $client->execute($request, $this->timeout);
|
||||
$this->translateResponse($response, $userResponse);
|
||||
}
|
||||
|
||||
/* @return bool ['hit' => true, 'miss' => false] */
|
||||
public function staticFileFiltrate(HttpRequest $request, $userResponse): bool
|
||||
{
|
||||
if ($userResponse instanceof \Swoole\Http\Response) {
|
||||
$extension = pathinfo($request->getScriptFilename(), PATHINFO_EXTENSION);
|
||||
if ($extension !== 'php') {
|
||||
$realPath = realpath($request->getScriptFilename());
|
||||
if (!$realPath || strpos($realPath, $this->documentRoot) !== 0 || !is_file($realPath)) {
|
||||
$userResponse->status(Http\Status::NOT_FOUND);
|
||||
} else {
|
||||
$userResponse->sendfile($realPath);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
throw new InvalidArgumentException('Not supported on ' . get_class($userResponse));
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Coroutine\Server\Connection;
|
||||
use Swoole\Exception;
|
||||
|
||||
/* compatibility constant */
|
||||
define('SWOOLE_COROUTINE_SOCKET_HAVE_SSL_HANDSHAKE', method_exists(Socket::class, 'sslHandshake'));
|
||||
|
||||
class Server
|
||||
{
|
||||
/** @var string */
|
||||
public $host = '';
|
||||
|
||||
/** @var int */
|
||||
public $port = 0;
|
||||
|
||||
/** @var int */
|
||||
public $type = AF_INET;
|
||||
|
||||
/** @var int */
|
||||
public $fd = -1;
|
||||
|
||||
/** @var int */
|
||||
public $errCode = 0;
|
||||
|
||||
/** @var array */
|
||||
public $setting = [];
|
||||
|
||||
/** @var bool */
|
||||
protected $running = false;
|
||||
|
||||
/** @var null|callable */
|
||||
protected $fn;
|
||||
|
||||
/** @var Socket */
|
||||
protected $socket;
|
||||
|
||||
/**
|
||||
* Server constructor.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(string $host, int $port = 0, bool $ssl = false, bool $reuse_port = false)
|
||||
{
|
||||
$_host = swoole_string($host);
|
||||
if ($_host->contains('::')) {
|
||||
$this->type = AF_INET6;
|
||||
} elseif ($_host->startsWith('unix:/')) {
|
||||
$host = $_host->substr(5)->__toString();
|
||||
$this->type = AF_UNIX;
|
||||
} else {
|
||||
$this->type = AF_INET;
|
||||
}
|
||||
$this->host = $host;
|
||||
|
||||
$socket = new Socket($this->type, SOCK_STREAM, 0);
|
||||
if ($reuse_port and defined('SO_REUSEPORT')) {
|
||||
$socket->setOption(SOL_SOCKET, SO_REUSEPORT, true);
|
||||
}
|
||||
if (!$socket->bind($this->host, $port)) {
|
||||
throw new Exception("bind({$this->host}:{$port}) failed", $socket->errCode);
|
||||
}
|
||||
if (!$socket->listen()) {
|
||||
throw new Exception('listen() failed', $socket->errCode);
|
||||
}
|
||||
$this->port = $socket->getsockname()['port'] ?? 0;
|
||||
$this->fd = $socket->fd;
|
||||
$this->socket = $socket;
|
||||
$this->setting['open_ssl'] = $ssl;
|
||||
}
|
||||
|
||||
public function set(array $setting): void
|
||||
{
|
||||
$this->setting = array_merge($this->setting, $setting);
|
||||
}
|
||||
|
||||
public function handle(callable $fn): void
|
||||
{
|
||||
$this->fn = $fn;
|
||||
}
|
||||
|
||||
public function shutdown(): bool
|
||||
{
|
||||
$this->running = false;
|
||||
return $this->socket->cancel();
|
||||
}
|
||||
|
||||
public function start(): bool
|
||||
{
|
||||
$this->running = true;
|
||||
if ($this->fn === null) {
|
||||
$this->errCode = SOCKET_EINVAL;
|
||||
return false;
|
||||
}
|
||||
$socket = $this->socket;
|
||||
if (!$socket->setProtocol($this->setting)) {
|
||||
$this->errCode = SOCKET_EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
while ($this->running) {
|
||||
/** @var Socket $conn */
|
||||
$conn = null;
|
||||
$conn = $socket->accept();
|
||||
if ($conn) {
|
||||
$conn->setProtocol($this->setting);
|
||||
if (SWOOLE_COROUTINE_SOCKET_HAVE_SSL_HANDSHAKE && $this->setting['open_ssl'] ?? false) {
|
||||
$fn = static function ($fn, $connection) {
|
||||
/* @var $connection Connection */
|
||||
if (!$connection->exportSocket()->sslHandshake()) {
|
||||
return;
|
||||
}
|
||||
$fn($connection);
|
||||
};
|
||||
$arguments = [$this->fn, new Connection($conn)];
|
||||
} else {
|
||||
$fn = $this->fn;
|
||||
$arguments = [new Connection($conn)];
|
||||
}
|
||||
if (Coroutine::create($fn, ...$arguments) < 0) {
|
||||
goto _wait;
|
||||
}
|
||||
} else {
|
||||
if ($socket->errCode == SOCKET_EMFILE or $socket->errCode == SOCKET_ENFILE) {
|
||||
_wait:
|
||||
Coroutine::sleep(1);
|
||||
continue;
|
||||
}
|
||||
if ($socket->errCode == SOCKET_ETIMEDOUT) {
|
||||
continue;
|
||||
}
|
||||
if ($socket->errCode == SOCKET_ECANCELED) {
|
||||
break;
|
||||
}
|
||||
trigger_error("accept failed, Error: {$socket->errMsg}[{$socket->errCode}]", E_USER_WARNING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine\Server;
|
||||
|
||||
use Swoole\Coroutine\Socket;
|
||||
|
||||
class Connection
|
||||
{
|
||||
protected $socket;
|
||||
|
||||
public function __construct(Socket $conn)
|
||||
{
|
||||
$this->socket = $conn;
|
||||
}
|
||||
|
||||
public function recv(float $timeout = 0)
|
||||
{
|
||||
return $this->socket->recvPacket($timeout);
|
||||
}
|
||||
|
||||
public function send(string $data)
|
||||
{
|
||||
return $this->socket->sendAll($data);
|
||||
}
|
||||
|
||||
public function close(): bool
|
||||
{
|
||||
return $this->socket->close();
|
||||
}
|
||||
|
||||
public function exportSocket(): Socket
|
||||
{
|
||||
return $this->socket;
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
use BadMethodCallException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class WaitGroup
|
||||
{
|
||||
protected $chan;
|
||||
|
||||
protected $count = 0;
|
||||
|
||||
protected $waiting = false;
|
||||
|
||||
public function __construct(int $delta = 0)
|
||||
{
|
||||
$this->chan = new Channel(1);
|
||||
if ($delta > 0) {
|
||||
$this->add($delta);
|
||||
}
|
||||
}
|
||||
|
||||
public function add(int $delta = 1): void
|
||||
{
|
||||
if ($this->waiting) {
|
||||
throw new BadMethodCallException('WaitGroup misuse: add called concurrently with wait');
|
||||
}
|
||||
$count = $this->count + $delta;
|
||||
if ($count < 0) {
|
||||
throw new InvalidArgumentException('WaitGroup misuse: negative counter');
|
||||
}
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
public function done(): void
|
||||
{
|
||||
$count = $this->count - 1;
|
||||
if ($count < 0) {
|
||||
throw new BadMethodCallException('WaitGroup misuse: negative counter');
|
||||
}
|
||||
$this->count = $count;
|
||||
if ($count === 0 && $this->waiting) {
|
||||
$this->chan->push(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function wait(float $timeout = -1): bool
|
||||
{
|
||||
if ($this->waiting) {
|
||||
throw new BadMethodCallException('WaitGroup misuse: reused before previous wait has returned');
|
||||
}
|
||||
if ($this->count > 0) {
|
||||
$this->waiting = true;
|
||||
$done = $this->chan->pop($timeout);
|
||||
$this->waiting = false;
|
||||
return $done;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Coroutine;
|
||||
|
||||
use Swoole\Coroutine;
|
||||
|
||||
function batch(array $tasks, float $timeout = -1): array
|
||||
{
|
||||
$wg = new WaitGroup(count($tasks));
|
||||
foreach ($tasks as $id => $task) {
|
||||
Coroutine::create(function () use ($wg, &$tasks, $id, $task) {
|
||||
$tasks[$id] = null;
|
||||
$tasks[$id] = $task();
|
||||
$wg->done();
|
||||
});
|
||||
}
|
||||
$wg->wait($timeout);
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
function parallel(int $n, callable $fn): void
|
||||
{
|
||||
$count = $n;
|
||||
$wg = new WaitGroup($n);
|
||||
while ($count--) {
|
||||
Coroutine::create(function () use ($fn, $wg) {
|
||||
$fn();
|
||||
$wg->done();
|
||||
});
|
||||
}
|
||||
$wg->wait();
|
||||
}
|
||||
|
||||
function map(array $list, callable $fn, float $timeout = -1): array
|
||||
{
|
||||
$wg = new WaitGroup(count($list));
|
||||
foreach ($list as $id => $elem) {
|
||||
Coroutine::create(function () use ($wg, &$list, $id, $elem, $fn): void {
|
||||
$list[$id] = null;
|
||||
$list[$id] = $fn($elem);
|
||||
$wg->done();
|
||||
});
|
||||
}
|
||||
$wg->wait($timeout);
|
||||
return $list;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Curl;
|
||||
|
||||
use Swoole;
|
||||
|
||||
class Exception extends Swoole\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,869 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
/* @noinspection PhpComposerExtensionStubsInspection, PhpDuplicateSwitchCaseBodyInspection, PhpInconsistentReturnPointsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Curl;
|
||||
|
||||
use CURLFile;
|
||||
use ReflectionClass;
|
||||
use Swoole;
|
||||
use Swoole\Constant;
|
||||
use Swoole\Coroutine\Http\Client;
|
||||
use Swoole\Curl\Exception as CurlException;
|
||||
use Swoole\Http\Status;
|
||||
|
||||
final class Handler
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
private $info = [
|
||||
'url' => '',
|
||||
'content_type' => '',
|
||||
'http_code' => 0,
|
||||
'header_size' => 0,
|
||||
'request_size' => 0,
|
||||
'filetime' => -1,
|
||||
'ssl_verify_result' => 0,
|
||||
'redirect_count' => 0,
|
||||
'total_time' => 5.3E-5,
|
||||
'namelookup_time' => 0.0,
|
||||
'connect_time' => 0.0,
|
||||
'pretransfer_time' => 0.0,
|
||||
'size_upload' => 0.0,
|
||||
'size_download' => 0.0,
|
||||
'speed_download' => 0.0,
|
||||
'speed_upload' => 0.0,
|
||||
'download_content_length' => -1.0,
|
||||
'upload_content_length' => -1.0,
|
||||
'starttransfer_time' => 0.0,
|
||||
'redirect_time' => 0.0,
|
||||
'redirect_url' => '',
|
||||
'primary_ip' => '',
|
||||
'certinfo' => [],
|
||||
'primary_port' => 0,
|
||||
'local_ip' => '',
|
||||
'local_port' => 0,
|
||||
'http_version' => 0,
|
||||
'protocol' => 0,
|
||||
'ssl_verifyresult' => 0,
|
||||
'scheme' => '',
|
||||
];
|
||||
|
||||
private $withHeaderOut = false;
|
||||
|
||||
private $withFileTime = false;
|
||||
|
||||
private $urlInfo;
|
||||
|
||||
private $postData;
|
||||
|
||||
private $infile;
|
||||
|
||||
private $infileSize = PHP_INT_MAX;
|
||||
|
||||
private $outputStream;
|
||||
|
||||
private $proxyType;
|
||||
|
||||
private $proxy;
|
||||
|
||||
private $proxyPort = 1080;
|
||||
|
||||
private $proxyUsername;
|
||||
|
||||
private $proxyPassword;
|
||||
|
||||
private $clientOptions = [];
|
||||
|
||||
private $followLocation = false;
|
||||
|
||||
private $autoReferer = false;
|
||||
|
||||
private $maxRedirects;
|
||||
|
||||
private $withHeader = false;
|
||||
|
||||
private $nobody = false;
|
||||
|
||||
/** @var callable */
|
||||
private $headerFunction;
|
||||
|
||||
/** @var callable */
|
||||
private $readFunction;
|
||||
|
||||
/** @var callable */
|
||||
private $writeFunction;
|
||||
|
||||
/** @var callable */
|
||||
private $progressFunction;
|
||||
|
||||
private $returnTransfer = false;
|
||||
|
||||
private $method = '';
|
||||
|
||||
private $headers = [];
|
||||
|
||||
private $transfer;
|
||||
|
||||
private $errCode = 0;
|
||||
|
||||
private $errMsg = '';
|
||||
|
||||
private $failOnError = false;
|
||||
|
||||
private $closed = false;
|
||||
|
||||
public function __construct(string $url = '')
|
||||
{
|
||||
if ($url) {
|
||||
$this->setUrl($url);
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
if (PHP_VERSION_ID < 70200) {
|
||||
$id = spl_object_hash($this);
|
||||
} else {
|
||||
$id = spl_object_id($this);
|
||||
}
|
||||
return "Object({$id}) of type (curl)";
|
||||
}
|
||||
|
||||
/* ====== Public APIs ====== */
|
||||
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
if ($this->closed) {
|
||||
trigger_error('supplied resource is not a valid cURL handle resource', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setOpt(int $opt, $value): bool
|
||||
{
|
||||
return $this->isAvailable() and $this->setOption($opt, $value);
|
||||
}
|
||||
|
||||
public function exec()
|
||||
{
|
||||
if (!$this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
return $this->execute();
|
||||
}
|
||||
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->isAvailable() ? $this->info : false;
|
||||
}
|
||||
|
||||
public function errno()
|
||||
{
|
||||
return $this->isAvailable() ? $this->errCode : false;
|
||||
}
|
||||
|
||||
public function error()
|
||||
{
|
||||
return $this->isAvailable() ? $this->errMsg : false;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
if (!$this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
foreach ((new ReflectionClass(static::class))->getDefaultProperties() as $name => $value) {
|
||||
$this->{$name} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
if (!$this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
return $this->transfer;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
if (!$this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this as &$property) {
|
||||
$property = null;
|
||||
}
|
||||
$this->closed = true;
|
||||
}
|
||||
|
||||
private function create(?array $urlInfo = null): void
|
||||
{
|
||||
if ($urlInfo === null) {
|
||||
$urlInfo = $this->urlInfo;
|
||||
}
|
||||
$this->client = new Client($urlInfo['host'], $urlInfo['port'], $urlInfo['scheme'] === 'https');
|
||||
}
|
||||
|
||||
private function getUrl(): string
|
||||
{
|
||||
if (empty($this->urlInfo['path'])) {
|
||||
$url = '/';
|
||||
} else {
|
||||
$url = $this->urlInfo['path'];
|
||||
}
|
||||
if (!empty($this->urlInfo['query'])) {
|
||||
$url .= '?' . $this->urlInfo['query'];
|
||||
}
|
||||
if (!empty($this->urlInfo['fragment'])) {
|
||||
$url .= '#' . $this->urlInfo['fragment'];
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function setUrl(string $url, bool $setInfo = true): bool
|
||||
{
|
||||
if (strlen($url) === 0) {
|
||||
$this->setError(CURLE_URL_MALFORMAT, 'No URL set!');
|
||||
return false;
|
||||
}
|
||||
if (strpos($url, '://') === false) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
if ($setInfo) {
|
||||
$urlInfo = parse_url($url);
|
||||
if (!is_array($urlInfo)) {
|
||||
$this->setError(CURLE_URL_MALFORMAT, "URL[{$url}] using bad/illegal format");
|
||||
return false;
|
||||
}
|
||||
if (!$this->setUrlInfo($urlInfo)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->info['url'] = $url;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function setUrlInfo(array $urlInfo): bool
|
||||
{
|
||||
if (empty($urlInfo['scheme'])) {
|
||||
$urlInfo['scheme'] = 'http';
|
||||
}
|
||||
$scheme = $urlInfo['scheme'];
|
||||
if ($scheme !== 'http' and $scheme !== 'https') {
|
||||
$this->setError(CURLE_UNSUPPORTED_PROTOCOL, "Protocol \"{$scheme}\" not supported or disabled in libcurl");
|
||||
return false;
|
||||
}
|
||||
$host = $urlInfo['host'];
|
||||
if ($this->info['primary_port'] !== 0) {
|
||||
/* keep same with cURL, primary_port has the highest priority */
|
||||
$urlInfo['port'] = $this->info['primary_port'];
|
||||
} elseif (empty($urlInfo['port'])) {
|
||||
$urlInfo['port'] = $scheme === 'https' ? 443 : 80;
|
||||
} else {
|
||||
$urlInfo['port'] = intval($urlInfo['port']);
|
||||
}
|
||||
$port = $urlInfo['port'];
|
||||
if ($this->client) {
|
||||
$oldUrlInfo = $this->urlInfo;
|
||||
if (
|
||||
$host !== $oldUrlInfo['host'] or
|
||||
$port !== $oldUrlInfo['port'] or
|
||||
$scheme !== $oldUrlInfo['scheme']
|
||||
) {
|
||||
/* target changed */
|
||||
$this->create($urlInfo);
|
||||
}
|
||||
}
|
||||
$this->urlInfo = $urlInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function setPort(int $port): void
|
||||
{
|
||||
$this->info['primary_port'] = $port;
|
||||
if ($this->urlInfo['port'] !== $port) {
|
||||
$this->urlInfo['port'] = $port;
|
||||
if ($this->client) {
|
||||
/* target changed */
|
||||
$this->create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setError($code, $msg = ''): void
|
||||
{
|
||||
$this->errCode = $code;
|
||||
$this->errMsg = $msg ? $msg : curl_strerror($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @throws Swoole\Curl\Exception
|
||||
*/
|
||||
private function setOption(int $opt, $value): bool
|
||||
{
|
||||
switch ($opt) {
|
||||
// case CURLOPT_STDERR:
|
||||
// case CURLOPT_WRITEHEADER:
|
||||
case CURLOPT_FILE:
|
||||
case CURLOPT_INFILE:
|
||||
if (!is_resource($value)) {
|
||||
trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): supplied argument is not a valid File-Handle resource');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($opt) {
|
||||
/*
|
||||
* Basic
|
||||
*/
|
||||
case CURLOPT_URL:
|
||||
return $this->setUrl((string) $value);
|
||||
case CURLOPT_PORT:
|
||||
$this->setPort((int) $value);
|
||||
break;
|
||||
case CURLOPT_FORBID_REUSE:
|
||||
$this->clientOptions[Constant::OPTION_KEEP_ALIVE] = !$value;
|
||||
break;
|
||||
case CURLOPT_RETURNTRANSFER:
|
||||
$this->returnTransfer = $value;
|
||||
$this->transfer = '';
|
||||
break;
|
||||
case CURLOPT_ENCODING:
|
||||
if (empty($value)) {
|
||||
if (defined('SWOOLE_HAVE_ZLIB')) {
|
||||
$value = 'gzip, deflate';
|
||||
}
|
||||
if (defined('SWOOLE_HAVE_BROTLI')) {
|
||||
if (!empty($value)) {
|
||||
$value = 'br, ' . $value;
|
||||
} else {
|
||||
$value = 'br';
|
||||
}
|
||||
}
|
||||
if (empty($value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->headers['Accept-Encoding'] = $value;
|
||||
break;
|
||||
case CURLOPT_PROXYTYPE:
|
||||
if ($value !== CURLPROXY_HTTP and $value !== CURLPROXY_SOCKS5) {
|
||||
throw new Swoole\Curl\Exception(
|
||||
'swoole_curl_setopt(): Only support following CURLOPT_PROXYTYPE values: CURLPROXY_HTTP, CURLPROXY_SOCKS5'
|
||||
);
|
||||
}
|
||||
$this->proxyType = $value;
|
||||
break;
|
||||
case CURLOPT_PROXY:
|
||||
$this->proxy = $value;
|
||||
break;
|
||||
case CURLOPT_PROXYPORT:
|
||||
$this->proxyPort = $value;
|
||||
break;
|
||||
case CURLOPT_PROXYUSERNAME:
|
||||
$this->proxyUsername = $value;
|
||||
break;
|
||||
case CURLOPT_PROXYPASSWORD:
|
||||
$this->proxyPassword = $value;
|
||||
break;
|
||||
case CURLOPT_PROXYUSERPWD:
|
||||
$usernamePassword = explode(':', $value);
|
||||
$this->proxyUsername = urldecode($usernamePassword[0]);
|
||||
$this->proxyPassword = urldecode($usernamePassword[1] ?? null);
|
||||
break;
|
||||
case CURLOPT_PROXYAUTH:
|
||||
/* ignored temporarily */
|
||||
break;
|
||||
case CURLOPT_NOBODY:
|
||||
$this->nobody = boolval($value);
|
||||
$this->method = 'HEAD';
|
||||
break;
|
||||
case CURLOPT_IPRESOLVE:
|
||||
if ($value !== CURL_IPRESOLVE_WHATEVER and $value !== CURL_IPRESOLVE_V4) {
|
||||
throw new Swoole\Curl\Exception(
|
||||
'swoole_curl_setopt(): Only support following CURLOPT_IPRESOLVE values: CURL_IPRESOLVE_WHATEVER, CURL_IPRESOLVE_V4'
|
||||
);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* Ignore options
|
||||
*/
|
||||
case CURLOPT_VERBOSE:
|
||||
// trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): CURLOPT_VERBOSE is not supported');
|
||||
case CURLOPT_SSLVERSION:
|
||||
case CURLOPT_NOSIGNAL:
|
||||
case CURLOPT_FRESH_CONNECT:
|
||||
/*
|
||||
* From PHP 5.1.3, this option has no effect: the raw output will always be returned when CURLOPT_RETURNTRANSFER is used.
|
||||
*/
|
||||
case CURLOPT_BINARYTRANSFER: /* TODO */
|
||||
case CURLOPT_DNS_USE_GLOBAL_CACHE:
|
||||
case CURLOPT_DNS_CACHE_TIMEOUT:
|
||||
case CURLOPT_STDERR:
|
||||
case CURLOPT_WRITEHEADER:
|
||||
case CURLOPT_BUFFERSIZE:
|
||||
case CURLOPT_SSLCERTTYPE:
|
||||
case CURLOPT_SSLKEYTYPE:
|
||||
break;
|
||||
/*
|
||||
* SSL
|
||||
*/
|
||||
case CURLOPT_SSL_VERIFYHOST:
|
||||
break;
|
||||
case CURLOPT_SSL_VERIFYPEER:
|
||||
$this->clientOptions[Constant::OPTION_SSL_VERIFY_PEER] = $value;
|
||||
break;
|
||||
case CURLOPT_SSLCERT:
|
||||
$this->clientOptions[Constant::OPTION_SSL_CERT_FILE] = $value;
|
||||
break;
|
||||
case CURLOPT_SSLKEY:
|
||||
$this->clientOptions[Constant::OPTION_SSL_KEY_FILE] = $value;
|
||||
break;
|
||||
case CURLOPT_CAINFO:
|
||||
$this->clientOptions[Constant::OPTION_SSL_CAFILE] = $value;
|
||||
break;
|
||||
case CURLOPT_CAPATH:
|
||||
$this->clientOptions[Constant::OPTION_SSL_CAPATH] = $value;
|
||||
break;
|
||||
/*
|
||||
* Http POST
|
||||
*/
|
||||
case CURLOPT_POST:
|
||||
$this->method = 'POST';
|
||||
break;
|
||||
case CURLOPT_POSTFIELDS:
|
||||
$this->postData = $value;
|
||||
if (!$this->method) {
|
||||
$this->method = 'POST';
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* Upload
|
||||
*/
|
||||
case CURLOPT_SAFE_UPLOAD:
|
||||
if (!$value) {
|
||||
trigger_error('swoole_curl_setopt(): Disabling safe uploads is no longer supported', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* Http Header
|
||||
*/
|
||||
case CURLOPT_HTTPHEADER:
|
||||
if (!is_array($value) and !is_iterable($value)) {
|
||||
trigger_error('swoole_curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
foreach ($value as $header) {
|
||||
$header = explode(':', $header, 2);
|
||||
$headerName = $header[0];
|
||||
$headerValue = trim($header[1] ?? '');
|
||||
if (strlen($headerValue) === 0) {
|
||||
continue;
|
||||
}
|
||||
$this->headers[$headerName] = $headerValue;
|
||||
}
|
||||
break;
|
||||
case CURLOPT_REFERER:
|
||||
$this->headers['Referer'] = $value;
|
||||
break;
|
||||
case CURLINFO_HEADER_OUT:
|
||||
$this->withHeaderOut = boolval($value);
|
||||
break;
|
||||
case CURLOPT_FILETIME:
|
||||
$this->withFileTime = boolval($value);
|
||||
break;
|
||||
case CURLOPT_USERAGENT:
|
||||
$this->headers['User-Agent'] = $value;
|
||||
break;
|
||||
case CURLOPT_CUSTOMREQUEST:
|
||||
$this->method = (string) $value;
|
||||
break;
|
||||
case CURLOPT_PROTOCOLS:
|
||||
if (($value & ~(CURLPROTO_HTTP | CURLPROTO_HTTPS)) != 0) {
|
||||
throw new CurlException("swoole_curl_setopt(): CURLOPT_PROTOCOLS[{$value}] is not supported");
|
||||
}
|
||||
break;
|
||||
case CURLOPT_REDIR_PROTOCOLS:
|
||||
if (($value & ~(CURLPROTO_HTTP | CURLPROTO_HTTPS)) != 0) {
|
||||
throw new CurlException("swoole_curl_setopt(): CURLOPT_REDIR_PROTOCOLS[{$value}] is not supported");
|
||||
}
|
||||
break;
|
||||
case CURLOPT_HTTP_VERSION:
|
||||
if ($value != CURL_HTTP_VERSION_1_1) {
|
||||
trigger_error("swoole_curl_setopt(): CURLOPT_HTTP_VERSION[{$value}] is not supported", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case CURLOPT_FAILONERROR:
|
||||
$this->failOnError = $value;
|
||||
break;
|
||||
/*
|
||||
* Http Cookie
|
||||
*/
|
||||
case CURLOPT_COOKIE:
|
||||
$this->headers['Cookie'] = $value;
|
||||
break;
|
||||
case CURLOPT_CONNECTTIMEOUT:
|
||||
$this->clientOptions[Constant::OPTION_CONNECT_TIMEOUT] = $value;
|
||||
break;
|
||||
case CURLOPT_CONNECTTIMEOUT_MS:
|
||||
$this->clientOptions[Constant::OPTION_CONNECT_TIMEOUT] = $value / 1000;
|
||||
break;
|
||||
case CURLOPT_TIMEOUT:
|
||||
$this->clientOptions[Constant::OPTION_TIMEOUT] = $value;
|
||||
break;
|
||||
case CURLOPT_TIMEOUT_MS:
|
||||
$this->clientOptions[Constant::OPTION_TIMEOUT] = $value / 1000;
|
||||
break;
|
||||
case CURLOPT_FILE:
|
||||
$this->outputStream = $value;
|
||||
break;
|
||||
case CURLOPT_HEADER:
|
||||
$this->withHeader = $value;
|
||||
break;
|
||||
case CURLOPT_HEADERFUNCTION:
|
||||
$this->headerFunction = $value;
|
||||
break;
|
||||
case CURLOPT_READFUNCTION:
|
||||
$this->readFunction = $value;
|
||||
break;
|
||||
case CURLOPT_WRITEFUNCTION:
|
||||
$this->writeFunction = $value;
|
||||
break;
|
||||
case CURLOPT_PROGRESSFUNCTION:
|
||||
$this->progressFunction = $value;
|
||||
break;
|
||||
case CURLOPT_HTTPAUTH:
|
||||
if (!($value & CURLAUTH_BASIC)) {
|
||||
trigger_error("swoole_curl_setopt(): CURLOPT_HTTPAUTH[{$value}] is not supported", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case CURLOPT_USERPWD:
|
||||
$this->headers['Authorization'] = 'Basic ' . base64_encode($value);
|
||||
break;
|
||||
case CURLOPT_FOLLOWLOCATION:
|
||||
$this->followLocation = $value;
|
||||
break;
|
||||
case CURLOPT_AUTOREFERER:
|
||||
$this->autoReferer = $value;
|
||||
break;
|
||||
case CURLOPT_MAXREDIRS:
|
||||
$this->maxRedirects = $value;
|
||||
break;
|
||||
case CURLOPT_PUT:
|
||||
case CURLOPT_UPLOAD:
|
||||
/* after libcurl 7.12, CURLOPT_PUT is replaced by CURLOPT_UPLOAD */
|
||||
$this->method = 'PUT';
|
||||
break;
|
||||
case CURLOPT_INFILE:
|
||||
$this->infile = $value;
|
||||
break;
|
||||
case CURLOPT_INFILESIZE:
|
||||
$this->infileSize = $value;
|
||||
break;
|
||||
case CURLOPT_HTTPGET:
|
||||
/* Since GET is the default, this is only necessary if the request method has been changed. */
|
||||
$this->method = 'GET';
|
||||
break;
|
||||
default:
|
||||
throw new Swoole\Curl\Exception("swoole_curl_setopt(): option[{$opt}] is not supported");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function execute()
|
||||
{
|
||||
$this->info['redirect_count'] = $this->info['starttransfer_time'] = 0;
|
||||
$this->info['redirect_url'] = '';
|
||||
$timeBegin = microtime(true);
|
||||
/*
|
||||
* Socket
|
||||
*/
|
||||
if (!$this->urlInfo) {
|
||||
$this->setError(CURLE_URL_MALFORMAT, 'No URL set or URL using bad/illegal format');
|
||||
return false;
|
||||
}
|
||||
if (!$this->client) {
|
||||
$this->create();
|
||||
}
|
||||
do {
|
||||
$client = $this->client;
|
||||
/*
|
||||
* Http Proxy
|
||||
*/
|
||||
if ($this->proxy) {
|
||||
$proxy = explode(':', $this->proxy);
|
||||
$proxyPort = $proxy[1] ?? $this->proxyPort;
|
||||
$proxy = $proxy[0];
|
||||
if (!filter_var($proxy, FILTER_VALIDATE_IP)) {
|
||||
$ip = Swoole\Coroutine::gethostbyname($proxy, AF_INET, $this->clientOptions['connect_timeout'] ?? -1);
|
||||
if (!$ip) {
|
||||
$this->setError(CURLE_COULDNT_RESOLVE_PROXY, 'Could not resolve proxy: ' . $proxy);
|
||||
return false;
|
||||
}
|
||||
$this->proxy = $proxy = $ip;
|
||||
}
|
||||
switch ($this->proxyType) {
|
||||
case CURLPROXY_HTTP:
|
||||
$proxyOptions = [
|
||||
'http_proxy_host' => $proxy,
|
||||
'http_proxy_port' => $proxyPort,
|
||||
'http_proxy_username' => $this->proxyUsername,
|
||||
'http_proxy_password' => $this->proxyPassword,
|
||||
];
|
||||
break;
|
||||
case CURLPROXY_SOCKS5:
|
||||
$proxyOptions = [
|
||||
'socks5_host' => $proxy,
|
||||
'socks5_port' => $proxyPort,
|
||||
'socks5_username' => $this->proxyUsername,
|
||||
'socks5_password' => $this->proxyPassword,
|
||||
];
|
||||
break;
|
||||
default:
|
||||
throw new CurlException("Unexpected proxy type [{$this->proxyType}]");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Client Options
|
||||
*/
|
||||
$client->set(
|
||||
$this->clientOptions +
|
||||
($proxyOptions ?? [])
|
||||
);
|
||||
/*
|
||||
* Method
|
||||
*/
|
||||
if ($this->method) {
|
||||
$client->setMethod($this->method);
|
||||
}
|
||||
/*
|
||||
* Data
|
||||
*/
|
||||
if ($this->infile) {
|
||||
// Infile
|
||||
// Notice: we make its priority higher than postData but raw cURL will send both of them
|
||||
$data = '';
|
||||
while (true) {
|
||||
$nLength = $this->infileSize - strlen($data);
|
||||
if ($nLength === 0) {
|
||||
break;
|
||||
}
|
||||
if (feof($this->infile)) {
|
||||
break;
|
||||
}
|
||||
$data .= fread($this->infile, $nLength);
|
||||
}
|
||||
$client->setData($data);
|
||||
// Notice: although we reset it, raw cURL never do this
|
||||
$this->infile = null;
|
||||
$this->infileSize = PHP_INT_MAX;
|
||||
} else {
|
||||
// POST data
|
||||
if ($this->postData) {
|
||||
if (is_string($this->postData)) {
|
||||
if (empty($this->headers['Content-Type'])) {
|
||||
$this->headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
} elseif (is_array($this->postData)) {
|
||||
foreach ($this->postData as $k => $v) {
|
||||
if ($v instanceof CURLFile) {
|
||||
$client->addFile($v->getFilename(), $k, $v->getMimeType() ?: 'application/octet-stream', $v->getPostFilename());
|
||||
unset($this->postData[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$client->setData($this->postData);
|
||||
}
|
||||
/*
|
||||
* Headers
|
||||
*/
|
||||
// Notice: setHeaders must be placed last, because headers may be changed by other parts
|
||||
// As much as possible to ensure that Host is the first header.
|
||||
// See: http://tools.ietf.org/html/rfc7230#section-5.4
|
||||
foreach ($this->headers as $headerName => $headerValue) {
|
||||
if ($headerValue === '') {
|
||||
// remove empty headers (keep same with raw cURL)
|
||||
unset($this->headers[$headerName]);
|
||||
}
|
||||
}
|
||||
$client->setHeaders($this->headers);
|
||||
/**
|
||||
* Execute.
|
||||
*/
|
||||
$executeResult = $client->execute($this->getUrl());
|
||||
if (!$executeResult) {
|
||||
$errCode = $client->errCode;
|
||||
if ($errCode == SWOOLE_ERROR_DNSLOOKUP_RESOLVE_FAILED or $errCode == SWOOLE_ERROR_DNSLOOKUP_RESOLVE_TIMEOUT) {
|
||||
$this->setError(CURLE_COULDNT_RESOLVE_HOST, 'Could not resolve host: ' . $client->host);
|
||||
} else {
|
||||
$this->setError($errCode, $client->errMsg);
|
||||
}
|
||||
$this->info['total_time'] = microtime(true) - $timeBegin;
|
||||
return false;
|
||||
}
|
||||
if ($client->statusCode >= 300 and $client->statusCode < 400 and isset($client->headers['location'])) {
|
||||
$redirectParsedUrl = $this->getRedirectUrl($client->headers['location']);
|
||||
$redirectUrl = static::unparseUrl($redirectParsedUrl);
|
||||
if ($this->followLocation and ($this->maxRedirects === null or $this->info['redirect_count'] < $this->maxRedirects)) {
|
||||
if ($this->info['redirect_count'] === 0) {
|
||||
$this->info['starttransfer_time'] = microtime(true) - $timeBegin;
|
||||
$redirectBeginTime = microtime(true);
|
||||
}
|
||||
// force GET
|
||||
if (in_array($client->statusCode, [Status::MOVED_PERMANENTLY, Status::FOUND, Status::SEE_OTHER])) {
|
||||
$this->method = 'GET';
|
||||
}
|
||||
if ($this->autoReferer) {
|
||||
$this->headers['Referer'] = $this->info['url'];
|
||||
}
|
||||
$this->setUrl($redirectUrl, false);
|
||||
$this->setUrlInfo($redirectParsedUrl);
|
||||
$this->info['redirect_count']++;
|
||||
} else {
|
||||
$this->info['redirect_url'] = $redirectUrl;
|
||||
break;
|
||||
}
|
||||
} elseif ($this->failOnError && $client->statusCode >= 400) {
|
||||
$this->setError(CURLE_HTTP_RETURNED_ERROR, "The requested URL returned error: {$client->statusCode} " . Status::getReasonPhrase($client->statusCode));
|
||||
return false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
$this->info['total_time'] = microtime(true) - $timeBegin;
|
||||
$this->info['http_code'] = $client->statusCode;
|
||||
$this->info['content_type'] = $client->headers['content-type'] ?? '';
|
||||
$this->info['size_download'] = $this->info['download_content_length'] = strlen($client->body);
|
||||
$this->info['speed_download'] = 1 / $this->info['total_time'] * $this->info['size_download'];
|
||||
if (isset($redirectBeginTime)) {
|
||||
$this->info['redirect_time'] = microtime(true) - $redirectBeginTime;
|
||||
}
|
||||
|
||||
$headerContent = '';
|
||||
if ($client->headers) {
|
||||
$cb = $this->headerFunction;
|
||||
if ($client->statusCode > 0) {
|
||||
$row = "HTTP/1.1 {$client->statusCode} " . Status::getReasonPhrase($client->statusCode) . "\r\n";
|
||||
if ($cb) {
|
||||
$cb($this, $row);
|
||||
}
|
||||
$headerContent .= $row;
|
||||
}
|
||||
foreach ($client->headers as $k => $v) {
|
||||
$row = "{$k}: {$v}\r\n";
|
||||
if ($cb) {
|
||||
$cb($this, $row);
|
||||
}
|
||||
$headerContent .= $row;
|
||||
}
|
||||
$headerContent .= "\r\n";
|
||||
$this->info['header_size'] = strlen($headerContent);
|
||||
if ($cb) {
|
||||
$cb($this, '');
|
||||
}
|
||||
} else {
|
||||
$this->info['header_size'] = 0;
|
||||
}
|
||||
|
||||
if ($client->body and $this->readFunction) {
|
||||
$cb = $this->readFunction;
|
||||
$cb($this, $this->outputStream, strlen($client->body));
|
||||
}
|
||||
|
||||
if ($this->withHeader) {
|
||||
$transfer = $headerContent . $client->body;
|
||||
} else {
|
||||
$transfer = $client->body;
|
||||
}
|
||||
|
||||
if ($this->withHeaderOut) {
|
||||
$headerOutContent = $client->getHeaderOut();
|
||||
$this->info['request_header'] = $headerOutContent ? $headerOutContent . "\r\n\r\n" : '';
|
||||
}
|
||||
if ($this->withFileTime) {
|
||||
if (isset($client->headers['last-modified'])) {
|
||||
$this->info['filetime'] = strtotime($client->headers['last-modified']);
|
||||
} else {
|
||||
$this->info['filetime'] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->returnTransfer) {
|
||||
return $this->transfer = $transfer;
|
||||
}
|
||||
if ($this->outputStream) {
|
||||
return fwrite($this->outputStream, $transfer) === strlen($transfer);
|
||||
}
|
||||
echo $transfer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ====== Redirect helper ====== */
|
||||
|
||||
private static function unparseUrl(array $parsedUrl): string
|
||||
{
|
||||
$scheme = ($parsedUrl['scheme'] ?? 'http') . '://';
|
||||
$host = $parsedUrl['host'] ?? '';
|
||||
$port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
|
||||
$user = $parsedUrl['user'] ?? '';
|
||||
$pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : '';
|
||||
$pass = ($user or $pass) ? "{$pass}@" : '';
|
||||
$path = $parsedUrl['path'] ?? '';
|
||||
$query = (isset($parsedUrl['query']) and $parsedUrl['query'] !== '') ? '?' . $parsedUrl['query'] : '';
|
||||
$fragment = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : '';
|
||||
return $scheme . $user . $pass . $host . $port . $path . $query . $fragment;
|
||||
}
|
||||
|
||||
private function getRedirectUrl(string $location): array
|
||||
{
|
||||
$uri = parse_url($location);
|
||||
if (isset($uri['host'])) {
|
||||
$redirectUri = $uri;
|
||||
} else {
|
||||
if (!isset($location[0])) {
|
||||
return [];
|
||||
}
|
||||
$redirectUri = $this->urlInfo;
|
||||
$redirectUri['query'] = '';
|
||||
if ($location[0] === '/') {
|
||||
$redirectUri['path'] = $location;
|
||||
} else {
|
||||
$path = dirname($redirectUri['path'] ?? '');
|
||||
if ($path === '.') {
|
||||
$path = '/';
|
||||
}
|
||||
if (isset($location[1]) and substr($location, 0, 2) === './') {
|
||||
$location = substr($location, 2);
|
||||
}
|
||||
$redirectUri['path'] = $path . $location;
|
||||
}
|
||||
foreach ($uri as $k => $v) {
|
||||
if (!in_array($k, ['path', 'query'])) {
|
||||
$redirectUri[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $redirectUri;
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
class MysqliConfig
|
||||
{
|
||||
/** @var string */
|
||||
protected $host = '127.0.0.1';
|
||||
|
||||
/** @var int */
|
||||
protected $port = 3306;
|
||||
|
||||
/** @var null|string */
|
||||
protected $unixSocket = '';
|
||||
|
||||
/** @var string */
|
||||
protected $dbname = 'test';
|
||||
|
||||
/** @var string */
|
||||
protected $charset = 'utf8mb4';
|
||||
|
||||
/** @var string */
|
||||
protected $username = 'root';
|
||||
|
||||
/** @var string */
|
||||
protected $password = 'root';
|
||||
|
||||
/** @var array */
|
||||
protected $options = [];
|
||||
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
public function withHost($host): self
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPort(): int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function getUnixSocket(): string
|
||||
{
|
||||
return $this->unixSocket;
|
||||
}
|
||||
|
||||
public function withUnixSocket(?string $unixSocket): self
|
||||
{
|
||||
$this->unixSocket = $unixSocket;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPort(int $port): self
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDbname(): string
|
||||
{
|
||||
return $this->dbname;
|
||||
}
|
||||
|
||||
public function withDbname(string $dbname): self
|
||||
{
|
||||
$this->dbname = $dbname;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCharset(): string
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
public function withCharset(string $charset): self
|
||||
{
|
||||
$this->charset = $charset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function withUsername(string $username): self
|
||||
{
|
||||
$this->username = $username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPassword(): string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function withPassword(string $password): self
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function withOptions(array $options): self
|
||||
{
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MysqliException extends Exception
|
||||
{
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use mysqli;
|
||||
use Swoole\ConnectionPool;
|
||||
|
||||
/**
|
||||
* @method mysqli|MysqliProxy get()
|
||||
* @method void put(mysqli|MysqliProxy $connection)
|
||||
*/
|
||||
class MysqliPool extends ConnectionPool
|
||||
{
|
||||
/** @var MysqliConfig */
|
||||
protected $config;
|
||||
|
||||
public function __construct(MysqliConfig $config, int $size = self::DEFAULT_SIZE)
|
||||
{
|
||||
$this->config = $config;
|
||||
parent::__construct(function () {
|
||||
$mysqli = new mysqli();
|
||||
foreach ($this->config->getOptions() as $option => $value) {
|
||||
$mysqli->set_opt($option, $value);
|
||||
}
|
||||
$mysqli->real_connect(
|
||||
$this->config->getHost(),
|
||||
$this->config->getUsername(),
|
||||
$this->config->getPassword(),
|
||||
$this->config->getDbname(),
|
||||
$this->config->getPort(),
|
||||
$this->config->getUnixSocket()
|
||||
);
|
||||
if ($mysqli->connect_errno) {
|
||||
throw new MysqliException($mysqli->connect_error, $mysqli->connect_errno);
|
||||
}
|
||||
return $mysqli;
|
||||
}, $size, MysqliProxy::class);
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use mysqli;
|
||||
|
||||
class MysqliProxy extends ObjectProxy
|
||||
{
|
||||
public const IO_METHOD_REGEX = '/^autocommit|begin_transaction|change_user|close|commit|kill|multi_query|ping|prepare|query|real_connect|real_query|reap_async_query|refresh|release_savepoint|rollback|savepoint|select_db|send_query|set_charset|ssl_set$/i';
|
||||
|
||||
public const IO_ERRORS = [
|
||||
2002, // MYSQLND_CR_CONNECTION_ERROR
|
||||
2006, // MYSQLND_CR_SERVER_GONE_ERROR
|
||||
2013, // MYSQLND_CR_SERVER_LOST
|
||||
];
|
||||
|
||||
/** @var mysqli */
|
||||
protected $__object;
|
||||
|
||||
/** @var string */
|
||||
protected $charsetContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $setOptContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $changeUserContext;
|
||||
|
||||
/** @var callable */
|
||||
protected $constructor;
|
||||
|
||||
/** @var int */
|
||||
protected $round = 0;
|
||||
|
||||
public function __construct(callable $constructor)
|
||||
{
|
||||
parent::__construct($constructor());
|
||||
$this->constructor = $constructor;
|
||||
}
|
||||
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
for ($n = 3; $n--;) {
|
||||
$ret = @$this->__object->{$name}(...$arguments);
|
||||
if ($ret === false) {
|
||||
/* non-IO method */
|
||||
if (!preg_match(static::IO_METHOD_REGEX, $name)) {
|
||||
break;
|
||||
}
|
||||
/* no more chances or non-IO failures */
|
||||
if (
|
||||
!in_array($this->__object->errno, static::IO_ERRORS, true) ||
|
||||
$n === 0
|
||||
) {
|
||||
throw new MysqliException($this->__object->error, $this->__object->errno);
|
||||
}
|
||||
$this->reconnect();
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp($name, 'prepare') === 0) {
|
||||
$ret = new MysqliStatementProxy($ret, $arguments[0], $this);
|
||||
} elseif (strcasecmp($name, 'stmt_init') === 0) {
|
||||
$ret = new MysqliStatementProxy($ret, null, $this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* @noinspection PhpUndefinedVariableInspection */
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getRound(): int
|
||||
{
|
||||
return $this->round;
|
||||
}
|
||||
|
||||
public function reconnect(): void
|
||||
{
|
||||
$constructor = $this->constructor;
|
||||
parent::__construct($constructor());
|
||||
$this->round++;
|
||||
/* restore context */
|
||||
if ($this->charsetContext) {
|
||||
$this->__object->set_charset($this->charsetContext);
|
||||
}
|
||||
if ($this->setOptContext) {
|
||||
foreach ($this->setOptContext as $opt => $val) {
|
||||
$this->__object->set_opt($opt, $val);
|
||||
}
|
||||
}
|
||||
if ($this->changeUserContext) {
|
||||
$this->__object->change_user(...$this->changeUserContext);
|
||||
}
|
||||
}
|
||||
|
||||
public function options(int $option, $value): bool
|
||||
{
|
||||
$this->setOptContext[$option] = $value;
|
||||
return $this->__object->options($option, $value);
|
||||
}
|
||||
|
||||
public function set_opt(int $option, $value): bool
|
||||
{
|
||||
return $this->options($option, $value);
|
||||
}
|
||||
|
||||
public function set_charset(string $charset): bool
|
||||
{
|
||||
$this->charsetContext = $charset;
|
||||
return $this->__object->set_charset($charset);
|
||||
}
|
||||
|
||||
public function change_user(string $user, string $password, string $database): bool
|
||||
{
|
||||
$this->changeUserContext = [$user, $password, $database];
|
||||
return $this->__object->change_user($user, $password, $database);
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use mysqli;
|
||||
use mysqli_stmt;
|
||||
|
||||
class MysqliStatementProxy extends ObjectProxy
|
||||
{
|
||||
public const IO_METHOD_REGEX = '/^close|execute|fetch|prepare$/i';
|
||||
|
||||
/** @var mysqli_stmt */
|
||||
protected $__object;
|
||||
|
||||
/** @var null|string */
|
||||
protected $queryString;
|
||||
|
||||
/** @var null|array */
|
||||
protected $attrSetContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindParamContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindResultContext;
|
||||
|
||||
/** @var Mysqli|MysqliProxy */
|
||||
protected $parent;
|
||||
|
||||
/** @var int */
|
||||
protected $parentRound;
|
||||
|
||||
public function __construct(mysqli_stmt $object, ?string $queryString, MysqliProxy $parent)
|
||||
{
|
||||
parent::__construct($object);
|
||||
$this->queryString = $queryString;
|
||||
$this->parent = $parent;
|
||||
$this->parentRound = $parent->getRound();
|
||||
}
|
||||
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
for ($n = 3; $n--;) {
|
||||
$ret = @$this->__object->{$name}(...$arguments);
|
||||
if ($ret === false) {
|
||||
/* non-IO method */
|
||||
if (!preg_match(static::IO_METHOD_REGEX, $name)) {
|
||||
break;
|
||||
}
|
||||
/* no more chances or non-IO failures or in transaction */
|
||||
if (
|
||||
!in_array($this->__object->errno, $this->parent::IO_ERRORS, true) ||
|
||||
$n === 0
|
||||
) {
|
||||
throw new MysqliException($this->__object->error, $this->__object->errno);
|
||||
}
|
||||
if ($this->parent->getRound() === $this->parentRound) {
|
||||
/* if not equal, parent has reconnected */
|
||||
$this->parent->reconnect();
|
||||
}
|
||||
$parent = $this->parent->__getObject();
|
||||
$this->__object = $this->queryString ? @$parent->prepare($this->queryString) : @$parent->stmt_init();
|
||||
if ($this->__object === false) {
|
||||
throw new MysqliException($parent->error, $parent->errno);
|
||||
}
|
||||
if ($this->bindParamContext) {
|
||||
$this->__object->bind_param($this->bindParamContext[0], ...$this->bindParamContext[1]);
|
||||
}
|
||||
if ($this->bindResultContext) {
|
||||
$this->__object->bind_result($this->bindResultContext);
|
||||
}
|
||||
if ($this->attrSetContext) {
|
||||
foreach ($this->attrSetContext as $attr => $value) {
|
||||
$this->__object->attr_set($attr, $value);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp($name, 'prepare') === 0) {
|
||||
$this->queryString = $arguments[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* @noinspection PhpUndefinedVariableInspection */
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function attr_set($attr, $mode): bool
|
||||
{
|
||||
$this->attrSetContext[$attr] = $mode;
|
||||
return $this->__object->attr_set($attr, $mode);
|
||||
}
|
||||
|
||||
public function bind_param($types, &...$arguments): bool
|
||||
{
|
||||
$this->bindParamContext = [$types, $arguments];
|
||||
return $this->__object->bind_param($types, ...$arguments);
|
||||
}
|
||||
|
||||
public function bind_result(&...$arguments): bool
|
||||
{
|
||||
$this->bindResultContext = $arguments;
|
||||
return $this->__object->bind_result(...$arguments);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use Error;
|
||||
|
||||
class ObjectProxy extends \Swoole\ObjectProxy
|
||||
{
|
||||
public function __clone()
|
||||
{
|
||||
throw new Error('Trying to clone an uncloneable database proxy object');
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
class PDOConfig
|
||||
{
|
||||
public const DRIVER_MYSQL = 'mysql';
|
||||
|
||||
/** @var string */
|
||||
protected $driver = self::DRIVER_MYSQL;
|
||||
|
||||
/** @var string */
|
||||
protected $host = '127.0.0.1';
|
||||
|
||||
/** @var int */
|
||||
protected $port = 3306;
|
||||
|
||||
/** @var null|string */
|
||||
protected $unixSocket;
|
||||
|
||||
/** @var string */
|
||||
protected $dbname = 'test';
|
||||
|
||||
/** @var string */
|
||||
protected $charset = 'utf8mb4';
|
||||
|
||||
/** @var string */
|
||||
protected $username = 'root';
|
||||
|
||||
/** @var string */
|
||||
protected $password = 'root';
|
||||
|
||||
/** @var array */
|
||||
protected $options = [];
|
||||
|
||||
public function getDriver(): string
|
||||
{
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
public function withDriver(string $driver): self
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
public function withHost($host): self
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPort(): int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function hasUnixSocket(): bool
|
||||
{
|
||||
return isset($this->unixSocket);
|
||||
}
|
||||
|
||||
public function getUnixSocket(): string
|
||||
{
|
||||
return $this->unixSocket;
|
||||
}
|
||||
|
||||
public function withUnixSocket(?string $unixSocket): self
|
||||
{
|
||||
$this->unixSocket = $unixSocket;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPort(int $port): self
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDbname(): string
|
||||
{
|
||||
return $this->dbname;
|
||||
}
|
||||
|
||||
public function withDbname(string $dbname): self
|
||||
{
|
||||
$this->dbname = $dbname;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCharset(): string
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
public function withCharset(string $charset): self
|
||||
{
|
||||
$this->charset = $charset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function withUsername(string $username): self
|
||||
{
|
||||
$this->username = $username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPassword(): string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function withPassword(string $password): self
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function withOptions(array $options): self
|
||||
{
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of available drivers
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getAvailableDrivers()
|
||||
{
|
||||
return [
|
||||
self::DRIVER_MYSQL,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use PDO;
|
||||
use Swoole\ConnectionPool;
|
||||
|
||||
/**
|
||||
* @method PDO|PDOProxy get()
|
||||
* @method void put(PDO|PDOProxy $connection)
|
||||
*/
|
||||
class PDOPool extends ConnectionPool
|
||||
{
|
||||
/** @var int */
|
||||
protected $size = 64;
|
||||
|
||||
/** @var PDOConfig */
|
||||
protected $config;
|
||||
|
||||
public function __construct(PDOConfig $config, int $size = self::DEFAULT_SIZE)
|
||||
{
|
||||
$this->config = $config;
|
||||
parent::__construct(function () {
|
||||
return new PDO(
|
||||
"{$this->config->getDriver()}:" .
|
||||
(
|
||||
$this->config->hasUnixSocket() ?
|
||||
"unix_socket={$this->config->getUnixSocket()};" :
|
||||
"host={$this->config->getHost()};" . "port={$this->config->getPort()};"
|
||||
) .
|
||||
"dbname={$this->config->getDbname()};" .
|
||||
"charset={$this->config->getCharset()}",
|
||||
$this->config->getUsername(),
|
||||
$this->config->getPassword(),
|
||||
$this->config->getOptions()
|
||||
);
|
||||
}, $size, PDOProxy::class);
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
class PDOProxy extends ObjectProxy
|
||||
{
|
||||
public const IO_METHOD_REGEX = '/^query|prepare|exec|beginTransaction|commit|rollback$/i';
|
||||
|
||||
public const IO_ERRORS = [
|
||||
2002, // MYSQLND_CR_CONNECTION_ERROR
|
||||
2006, // MYSQLND_CR_SERVER_GONE_ERROR
|
||||
2013, // MYSQLND_CR_SERVER_LOST
|
||||
];
|
||||
|
||||
/** @var PDO */
|
||||
protected $__object;
|
||||
|
||||
/** @var null|array */
|
||||
protected $setAttributeContext;
|
||||
|
||||
/** @var callable */
|
||||
protected $constructor;
|
||||
|
||||
/** @var int */
|
||||
protected $round = 0;
|
||||
|
||||
public function __construct(callable $constructor)
|
||||
{
|
||||
parent::__construct($constructor());
|
||||
$this->__object->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
$this->constructor = $constructor;
|
||||
}
|
||||
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
for ($n = 3; $n--;) {
|
||||
$ret = @$this->__object->{$name}(...$arguments);
|
||||
if ($ret === false) {
|
||||
/* non-IO method */
|
||||
if (!preg_match(static::IO_METHOD_REGEX, $name)) {
|
||||
break;
|
||||
}
|
||||
$errorInfo = $this->__object->errorInfo();
|
||||
/* no more chances or non-IO failures */
|
||||
if (
|
||||
!in_array($errorInfo[1], static::IO_ERRORS, true) ||
|
||||
$n === 0 ||
|
||||
$this->__object->inTransaction()
|
||||
) {
|
||||
$exception = new PDOException($errorInfo[2], $errorInfo[1]);
|
||||
$exception->errorInfo = $errorInfo;
|
||||
throw $exception;
|
||||
}
|
||||
$this->reconnect();
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
strcasecmp($name, 'prepare') === 0 ||
|
||||
strcasecmp($name, 'query') === 0
|
||||
) {
|
||||
$ret = new PDOStatementProxy($ret, $this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* @noinspection PhpUndefinedVariableInspection */
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getRound(): int
|
||||
{
|
||||
return $this->round;
|
||||
}
|
||||
|
||||
public function reconnect(): void
|
||||
{
|
||||
$constructor = $this->constructor;
|
||||
parent::__construct($constructor());
|
||||
$this->round++;
|
||||
/* restore context */
|
||||
if ($this->setAttributeContext) {
|
||||
foreach ($this->setAttributeContext as $attribute => $value) {
|
||||
$this->__object->setAttribute($attribute, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setAttribute(int $attribute, $value): bool
|
||||
{
|
||||
$this->setAttributeContext[$attribute] = $value;
|
||||
return $this->__object->setAttribute($attribute, $value);
|
||||
}
|
||||
|
||||
public function inTransaction(): bool
|
||||
{
|
||||
return $this->__object->inTransaction();
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use PDOStatement;
|
||||
|
||||
class PDOStatementProxy extends ObjectProxy
|
||||
{
|
||||
/** @var PDOStatement */
|
||||
protected $__object;
|
||||
|
||||
/** @var null|array */
|
||||
protected $setAttributeContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $setFetchModeContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindParamContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindColumnContext;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindValueContext;
|
||||
|
||||
/** @var PDO|PDOProxy */
|
||||
protected $parent;
|
||||
|
||||
/** @var int */
|
||||
protected $parentRound;
|
||||
|
||||
public function __construct(PDOStatement $object, PDOProxy $parent)
|
||||
{
|
||||
parent::__construct($object);
|
||||
$this->parent = $parent;
|
||||
$this->parentRound = $parent->getRound();
|
||||
}
|
||||
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
for ($n = 3; $n--;) {
|
||||
$ret = @$this->__object->{$name}(...$arguments);
|
||||
if ($ret === false) {
|
||||
/* no IO */
|
||||
if (strtolower($name) !== 'execute') {
|
||||
break;
|
||||
}
|
||||
/* no more chances or non-IO failures or in transaction */
|
||||
if (
|
||||
!in_array($this->__object->errorInfo()[1], $this->parent::IO_ERRORS, true) ||
|
||||
$n === 0 ||
|
||||
$this->parent->inTransaction()
|
||||
) {
|
||||
$errorInfo = $this->__object->errorInfo();
|
||||
|
||||
// '00000' means “no error.”, as specified by ANSI SQL and ODBC.
|
||||
if ($errorInfo[0] !== '00000') {
|
||||
$exception = new PDOException($errorInfo[2], $errorInfo[1]);
|
||||
$exception->errorInfo = $errorInfo;
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
if ($this->parent->getRound() === $this->parentRound) {
|
||||
/* if not equal, parent has reconnected */
|
||||
$this->parent->reconnect();
|
||||
}
|
||||
$parent = $this->parent->__getObject();
|
||||
$this->__object = $parent->prepare($this->__object->queryString);
|
||||
if ($this->__object === false) {
|
||||
$errorInfo = $parent->errorInfo();
|
||||
$exception = new PDOException($errorInfo[2], $errorInfo[1]);
|
||||
$exception->errorInfo = $errorInfo;
|
||||
throw $exception;
|
||||
}
|
||||
if ($this->setAttributeContext) {
|
||||
foreach ($this->setAttributeContext as $attribute => $value) {
|
||||
$this->__object->setAttribute($attribute, $value);
|
||||
}
|
||||
}
|
||||
if ($this->setFetchModeContext) {
|
||||
$this->__object->setFetchMode(...$this->setFetchModeContext);
|
||||
}
|
||||
if ($this->bindParamContext) {
|
||||
foreach ($this->bindParamContext as $param => $item) {
|
||||
$this->__object->bindParam($param, ...$item);
|
||||
}
|
||||
}
|
||||
if ($this->bindColumnContext) {
|
||||
foreach ($this->bindColumnContext as $column => $item) {
|
||||
$this->__object->bindColumn($column, ...$item);
|
||||
}
|
||||
}
|
||||
if ($this->bindValueContext) {
|
||||
foreach ($this->bindValueContext as $value => $item) {
|
||||
$this->__object->bindParam($value, ...$item);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* @noinspection PhpUndefinedVariableInspection */
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function setAttribute(int $attribute, $value): bool
|
||||
{
|
||||
$this->setAttributeContext[$attribute] = $value;
|
||||
return $this->__object->setAttribute($attribute, $value);
|
||||
}
|
||||
|
||||
public function setFetchMode(int $mode, $classNameObject = null, array $ctorarfg = []): bool
|
||||
{
|
||||
$this->setFetchModeContext = [$mode, $classNameObject, $ctorarfg];
|
||||
if (!isset($classNameObject)) {
|
||||
return $this->__object->setFetchMode($mode);
|
||||
}
|
||||
return $this->__object->setFetchMode($mode, $classNameObject, $ctorarfg);
|
||||
}
|
||||
|
||||
public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null): bool
|
||||
{
|
||||
$this->bindParamContext[$parameter] = [$variable, $data_type, $length, $driver_options];
|
||||
return $this->__object->bindParam($parameter, $variable, $data_type, $length, $driver_options);
|
||||
}
|
||||
|
||||
public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null): bool
|
||||
{
|
||||
$this->bindColumnContext[$column] = [$param, $type, $maxlen, $driverdata];
|
||||
return $this->__object->bindColumn($column, $param, $type, $maxlen, $driverdata);
|
||||
}
|
||||
|
||||
public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR): bool
|
||||
{
|
||||
$this->bindValueContext[$parameter] = [$value, $data_type];
|
||||
return $this->__object->bindValue($parameter, $value, $data_type);
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
class RedisConfig
|
||||
{
|
||||
/** @var string */
|
||||
protected $host = '127.0.0.1';
|
||||
|
||||
/** @var int */
|
||||
protected $port = 6379;
|
||||
|
||||
/** @var float */
|
||||
protected $timeout = 0.0;
|
||||
|
||||
/** @var string */
|
||||
protected $reserved = '';
|
||||
|
||||
/** @var int */
|
||||
protected $retry_interval = 0;
|
||||
|
||||
/** @var float */
|
||||
protected $read_timeout = 0.0;
|
||||
|
||||
/** @var string */
|
||||
protected $auth = '';
|
||||
|
||||
/** @var int */
|
||||
protected $dbIndex = 0;
|
||||
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
public function withHost($host): self
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPort(): int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function withPort(int $port): self
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTimeout(): float
|
||||
{
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
public function withTimeout(float $timeout): self
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReserved(): string
|
||||
{
|
||||
return $this->reserved;
|
||||
}
|
||||
|
||||
public function withReserved(string $reserved): self
|
||||
{
|
||||
$this->reserved = $reserved;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRetryInterval(): int
|
||||
{
|
||||
return $this->retry_interval;
|
||||
}
|
||||
|
||||
public function withRetryInterval(int $retry_interval): self
|
||||
{
|
||||
$this->retry_interval = $retry_interval;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReadTimeout(): float
|
||||
{
|
||||
return $this->read_timeout;
|
||||
}
|
||||
|
||||
public function withReadTimeout(float $read_timeout): self
|
||||
{
|
||||
$this->read_timeout = $read_timeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuth(): string
|
||||
{
|
||||
return $this->auth;
|
||||
}
|
||||
|
||||
public function withAuth(string $auth): self
|
||||
{
|
||||
$this->auth = $auth;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDbIndex(): int
|
||||
{
|
||||
return $this->dbIndex;
|
||||
}
|
||||
|
||||
public function withDbIndex(int $dbIndex): self
|
||||
{
|
||||
$this->dbIndex = $dbIndex;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Database;
|
||||
|
||||
use Redis;
|
||||
use Swoole\ConnectionPool;
|
||||
|
||||
/**
|
||||
* @method Redis get()
|
||||
* @method void put(Redis $connection)
|
||||
*/
|
||||
class RedisPool extends ConnectionPool
|
||||
{
|
||||
/** @var RedisConfig */
|
||||
protected $config;
|
||||
|
||||
public function __construct(RedisConfig $config, int $size = self::DEFAULT_SIZE)
|
||||
{
|
||||
$this->config = $config;
|
||||
parent::__construct(function () {
|
||||
$redis = new Redis();
|
||||
/* Compatible with different versions of Redis extension as much as possible */
|
||||
$arguments = [
|
||||
$this->config->getHost(),
|
||||
$this->config->getPort(),
|
||||
];
|
||||
if ($this->config->getTimeout() !== 0.0) {
|
||||
$arguments[] = $this->config->getTimeout();
|
||||
}
|
||||
if ($this->config->getRetryInterval() !== 0) {
|
||||
/* reserved should always be NULL */
|
||||
$arguments[] = null;
|
||||
$arguments[] = $this->config->getRetryInterval();
|
||||
}
|
||||
if ($this->config->getReadTimeout() !== 0.0) {
|
||||
$arguments[] = $this->config->getReadTimeout();
|
||||
}
|
||||
$redis->connect(...$arguments);
|
||||
if ($this->config->getAuth()) {
|
||||
$redis->auth($this->config->getAuth());
|
||||
}
|
||||
if ($this->config->getDbIndex() !== 0) {
|
||||
$redis->select($this->config->getDbIndex());
|
||||
}
|
||||
return $redis;
|
||||
}, $size);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Exception;
|
||||
|
||||
class ArrayKeyNotExists extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
/**
|
||||
* FastCGI constants.
|
||||
*/
|
||||
class FastCGI
|
||||
{
|
||||
/**
|
||||
* Number of bytes in a FCGI_Header. Future versions of the protocol
|
||||
* will not reduce this number.
|
||||
*/
|
||||
public const HEADER_LEN = 8;
|
||||
|
||||
/**
|
||||
* Format of FCGI_HEADER for unpacking in PHP
|
||||
*/
|
||||
public const HEADER_FORMAT = 'Cversion/Ctype/nrequestId/ncontentLength/CpaddingLength/Creserved';
|
||||
|
||||
/**
|
||||
* Max content length of a record
|
||||
*/
|
||||
public const MAX_CONTENT_LENGTH = 65535;
|
||||
|
||||
/**
|
||||
* Value for version component of FCGI_Header
|
||||
*/
|
||||
public const VERSION_1 = 1;
|
||||
|
||||
/**
|
||||
* Values for type component of FCGI_Header
|
||||
*/
|
||||
public const BEGIN_REQUEST = 1;
|
||||
|
||||
public const ABORT_REQUEST = 2;
|
||||
|
||||
public const END_REQUEST = 3;
|
||||
|
||||
public const PARAMS = 4;
|
||||
|
||||
public const STDIN = 5;
|
||||
|
||||
public const STDOUT = 6;
|
||||
|
||||
public const STDERR = 7;
|
||||
|
||||
public const DATA = 8;
|
||||
|
||||
public const GET_VALUES = 9;
|
||||
|
||||
public const GET_VALUES_RESULT = 10;
|
||||
|
||||
public const UNKNOWN_TYPE = 11;
|
||||
|
||||
/**
|
||||
* Value for requestId component of FCGI_Header
|
||||
*/
|
||||
public const DEFAULT_REQUEST_ID = 1;
|
||||
|
||||
/**
|
||||
* Mask for flags component of FCGI_BeginRequestBody
|
||||
*/
|
||||
public const KEEP_CONN = 1;
|
||||
|
||||
/**
|
||||
* Values for role component of FCGI_BeginRequestBody
|
||||
*/
|
||||
public const RESPONDER = 1;
|
||||
|
||||
public const AUTHORIZER = 2;
|
||||
|
||||
public const FILTER = 3;
|
||||
|
||||
/**
|
||||
* Values for protocolStatus component of FCGI_EndRequestBody
|
||||
*/
|
||||
public const REQUEST_COMPLETE = 0;
|
||||
|
||||
public const CANT_MPX_CONN = 1;
|
||||
|
||||
public const OVERLOADED = 2;
|
||||
|
||||
public const UNKNOWN_ROLE = 3;
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use DomainException;
|
||||
use RuntimeException;
|
||||
use Swoole\FastCGI;
|
||||
|
||||
/**
|
||||
* Utility class to simplify parsing of FastCGI protocol data.
|
||||
*/
|
||||
class FrameParser
|
||||
{
|
||||
/**
|
||||
* Mapping of constants to the classes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $classMapping = [
|
||||
FastCGI::BEGIN_REQUEST => FastCGI\Record\BeginRequest::class,
|
||||
FastCGI::ABORT_REQUEST => FastCGI\Record\AbortRequest::class,
|
||||
FastCGI::END_REQUEST => FastCGI\Record\EndRequest::class,
|
||||
FastCGI::PARAMS => FastCGI\Record\Params::class,
|
||||
FastCGI::STDIN => FastCGI\Record\Stdin::class,
|
||||
FastCGI::STDOUT => FastCGI\Record\Stdout::class,
|
||||
FastCGI::STDERR => FastCGI\Record\Stderr::class,
|
||||
FastCGI::DATA => FastCGI\Record\Data::class,
|
||||
FastCGI::GET_VALUES => FastCGI\Record\GetValues::class,
|
||||
FastCGI::GET_VALUES_RESULT => FastCGI\Record\GetValuesResult::class,
|
||||
FastCGI::UNKNOWN_TYPE => FastCGI\Record\UnknownType::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Checks if the buffer contains a valid frame to parse
|
||||
*
|
||||
* @param string $buffer Binary buffer
|
||||
*/
|
||||
public static function hasFrame(string $buffer): bool
|
||||
{
|
||||
$bufferLength = strlen($buffer);
|
||||
if ($bufferLength < FastCGI::HEADER_LEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fastInfo = unpack(FastCGI::HEADER_FORMAT, $buffer);
|
||||
if ($bufferLength < FastCGI::HEADER_LEN + $fastInfo['contentLength'] + $fastInfo['paddingLength']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a frame from the binary buffer
|
||||
*
|
||||
* @param string $buffer Binary buffer
|
||||
*
|
||||
* @return Record One of the corresponding FastCGI record
|
||||
*/
|
||||
public static function parseFrame(string &$buffer): Record
|
||||
{
|
||||
$bufferLength = strlen($buffer);
|
||||
if ($bufferLength < FastCGI::HEADER_LEN) {
|
||||
throw new RuntimeException('Not enough data in the buffer to parse');
|
||||
}
|
||||
$recordHeader = unpack(FastCGI::HEADER_FORMAT, $buffer);
|
||||
$recordType = $recordHeader['type'];
|
||||
if (!isset(self::$classMapping[$recordType])) {
|
||||
throw new DomainException("Invalid FastCGI record type {$recordType} received");
|
||||
}
|
||||
|
||||
/** @var Record $className */
|
||||
$className = self::$classMapping[$recordType];
|
||||
$record = $className::unpack($buffer);
|
||||
|
||||
$offset = FastCGI::HEADER_LEN + $record->getContentLength() + $record->getPaddingLength();
|
||||
$buffer = substr($buffer, $offset);
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
+424
@@ -0,0 +1,424 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class HttpRequest extends Request
|
||||
{
|
||||
protected $params = [
|
||||
'REQUEST_SCHEME' => 'http',
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'DOCUMENT_ROOT' => '',
|
||||
'SCRIPT_FILENAME' => '',
|
||||
'SCRIPT_NAME' => '',
|
||||
'DOCUMENT_URI' => '/',
|
||||
'REQUEST_URI' => '/',
|
||||
'QUERY_STRING' => '',
|
||||
'CONTENT_TYPE' => 'text/plain',
|
||||
'CONTENT_LENGTH' => '0',
|
||||
'GATEWAY_INTERFACE' => 'CGI/1.1',
|
||||
'SERVER_PROTOCOL' => 'HTTP/1.1',
|
||||
'SERVER_SOFTWARE' => 'swoole/' . SWOOLE_VERSION,
|
||||
'REMOTE_ADDR' => 'unknown',
|
||||
'REMOTE_PORT' => '0',
|
||||
'SERVER_ADDR' => 'unknown',
|
||||
'SERVER_PORT' => '0',
|
||||
'SERVER_NAME' => 'Swoole',
|
||||
'REDIRECT_STATUS' => '200',
|
||||
];
|
||||
|
||||
public function getScheme(): ?string
|
||||
{
|
||||
return $this->params['REQUEST_SCHEME'] ?? null;
|
||||
}
|
||||
|
||||
public function withScheme(string $scheme): self
|
||||
{
|
||||
$this->params['REQUEST_SCHEME'] = $scheme;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutScheme(): void
|
||||
{
|
||||
unset($this->params['REQUEST_SCHEME']);
|
||||
}
|
||||
|
||||
public function getMethod(): ?string
|
||||
{
|
||||
return $this->params['REQUEST_METHOD'] ?? null;
|
||||
}
|
||||
|
||||
public function withMethod(string $method): self
|
||||
{
|
||||
$this->params['REQUEST_METHOD'] = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutMethod(): void
|
||||
{
|
||||
unset($this->params['REQUEST_METHOD']);
|
||||
}
|
||||
|
||||
public function getDocumentRoot(): ?string
|
||||
{
|
||||
return $this->params['DOCUMENT_ROOT'] ?? null;
|
||||
}
|
||||
|
||||
public function withDocumentRoot(string $documentRoot): self
|
||||
{
|
||||
$this->params['DOCUMENT_ROOT'] = $documentRoot;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutDocumentRoot(): void
|
||||
{
|
||||
unset($this->params['DOCUMENT_ROOT']);
|
||||
}
|
||||
|
||||
public function getScriptFilename(): ?string
|
||||
{
|
||||
return $this->params['SCRIPT_FILENAME'] ?? null;
|
||||
}
|
||||
|
||||
public function withScriptFilename(string $scriptFilename): self
|
||||
{
|
||||
$this->params['SCRIPT_FILENAME'] = $scriptFilename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutScriptFilename(): void
|
||||
{
|
||||
unset($this->params['SCRIPT_FILENAME']);
|
||||
}
|
||||
|
||||
public function getScriptName(): ?string
|
||||
{
|
||||
return $this->params['SCRIPT_NAME'] ?? null;
|
||||
}
|
||||
|
||||
public function withScriptName(string $scriptName): self
|
||||
{
|
||||
$this->params['SCRIPT_NAME'] = $scriptName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutScriptName(): void
|
||||
{
|
||||
unset($this->params['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
public function withUri(string $uri): self
|
||||
{
|
||||
$info = parse_url($uri);
|
||||
return $this->withRequestUri($uri)
|
||||
->withDocumentUri($info['path'] ?? '')
|
||||
->withQueryString($info['query'] ?? '');
|
||||
}
|
||||
|
||||
public function getDocumentUri(): ?string
|
||||
{
|
||||
return $this->params['DOCUMENT_URI'] ?? null;
|
||||
}
|
||||
|
||||
public function withDocumentUri(string $documentUri): self
|
||||
{
|
||||
$this->params['DOCUMENT_URI'] = $documentUri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutDocumentUri(): void
|
||||
{
|
||||
unset($this->params['DOCUMENT_URI']);
|
||||
}
|
||||
|
||||
public function getRequestUri(): ?string
|
||||
{
|
||||
return $this->params['REQUEST_URI'] ?? null;
|
||||
}
|
||||
|
||||
public function withRequestUri(string $requestUri): self
|
||||
{
|
||||
$this->params['REQUEST_URI'] = $requestUri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutRequestUri(): void
|
||||
{
|
||||
unset($this->params['REQUEST_URI']);
|
||||
}
|
||||
|
||||
public function withQuery($query): self
|
||||
{
|
||||
if (is_array($query)) {
|
||||
$query = http_build_query($query);
|
||||
}
|
||||
return $this->withQueryString($query);
|
||||
}
|
||||
|
||||
public function getQueryString(): ?string
|
||||
{
|
||||
return $this->params['QUERY_STRING'] ?? null;
|
||||
}
|
||||
|
||||
public function withQueryString(string $queryString): self
|
||||
{
|
||||
$this->params['QUERY_STRING'] = $queryString;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutQueryString(): void
|
||||
{
|
||||
unset($this->params['QUERY_STRING']);
|
||||
}
|
||||
|
||||
public function getContentType(): ?string
|
||||
{
|
||||
return $this->params['CONTENT_TYPE'] ?? null;
|
||||
}
|
||||
|
||||
public function withContentType(string $contentType): self
|
||||
{
|
||||
$this->params['CONTENT_TYPE'] = $contentType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutContentType(): void
|
||||
{
|
||||
unset($this->params['CONTENT_TYPE']);
|
||||
}
|
||||
|
||||
public function getContentLength(): ?int
|
||||
{
|
||||
return isset($this->params['CONTENT_LENGTH']) ? (int) $this->params['CONTENT_LENGTH'] : null;
|
||||
}
|
||||
|
||||
public function withContentLength(int $contentLength): self
|
||||
{
|
||||
$this->params['CONTENT_LENGTH'] = (string) $contentLength;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutContentLength(): void
|
||||
{
|
||||
unset($this->params['CONTENT_LENGTH']);
|
||||
}
|
||||
|
||||
public function getGatewayInterface(): ?string
|
||||
{
|
||||
return $this->params['GATEWAY_INTERFACE'] ?? null;
|
||||
}
|
||||
|
||||
public function withGatewayInterface(string $gatewayInterface): self
|
||||
{
|
||||
$this->params['GATEWAY_INTERFACE'] = $gatewayInterface;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutGatewayInterface(): void
|
||||
{
|
||||
unset($this->params['GATEWAY_INTERFACE']);
|
||||
}
|
||||
|
||||
public function getServerProtocol(): ?string
|
||||
{
|
||||
return $this->params['SERVER_PROTOCOL'] ?? null;
|
||||
}
|
||||
|
||||
public function withServerProtocol(string $serverProtocol): self
|
||||
{
|
||||
$this->params['SERVER_PROTOCOL'] = $serverProtocol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutServerProtocol(): void
|
||||
{
|
||||
unset($this->params['SERVER_PROTOCOL']);
|
||||
}
|
||||
|
||||
public function withProtocolVersion(string $protocolVersion): self
|
||||
{
|
||||
if (!is_numeric($protocolVersion)) {
|
||||
throw new InvalidArgumentException('Protocol version must be numeric');
|
||||
}
|
||||
$this->params['SERVER_PROTOCOL'] = "HTTP/{$protocolVersion}";
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getServerSoftware(): ?string
|
||||
{
|
||||
return $this->params['SERVER_SOFTWARE'] ?? null;
|
||||
}
|
||||
|
||||
public function withServerSoftware(string $serverSoftware): self
|
||||
{
|
||||
$this->params['SERVER_SOFTWARE'] = $serverSoftware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutServerSoftware(): void
|
||||
{
|
||||
unset($this->params['SERVER_SOFTWARE']);
|
||||
}
|
||||
|
||||
public function getRemoteAddr(): ?string
|
||||
{
|
||||
return $this->params['REMOTE_ADDR'] ?? null;
|
||||
}
|
||||
|
||||
public function withRemoteAddr(string $remoteAddr): self
|
||||
{
|
||||
$this->params['REMOTE_ADDR'] = $remoteAddr;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutRemoteAddr(): void
|
||||
{
|
||||
unset($this->params['REMOTE_ADDR']);
|
||||
}
|
||||
|
||||
public function getRemotePort(): ?int
|
||||
{
|
||||
return isset($this->params['REMOTE_PORT']) ? (int) $this->params['REMOTE_PORT'] : null;
|
||||
}
|
||||
|
||||
public function withRemotePort(int $remotePort): self
|
||||
{
|
||||
$this->params['REMOTE_PORT'] = (string) $remotePort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutRemotePort(): void
|
||||
{
|
||||
unset($this->params['REMOTE_PORT']);
|
||||
}
|
||||
|
||||
public function getServerAddr(): ?string
|
||||
{
|
||||
return $this->params['SERVER_ADDR'] ?? null;
|
||||
}
|
||||
|
||||
public function withServerAddr(string $serverAddr): self
|
||||
{
|
||||
$this->params['SERVER_ADDR'] = $serverAddr;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutServerAddr(): void
|
||||
{
|
||||
unset($this->params['SERVER_ADDR']);
|
||||
}
|
||||
|
||||
public function getServerPort(): ?int
|
||||
{
|
||||
return isset($this->params['SERVER_PORT']) ? (int) $this->params['SERVER_PORT'] : null;
|
||||
}
|
||||
|
||||
public function withServerPort(int $serverPort): self
|
||||
{
|
||||
$this->params['SERVER_PORT'] = (string) $serverPort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutServerPort(): void
|
||||
{
|
||||
unset($this->params['SERVER_PORT']);
|
||||
}
|
||||
|
||||
public function getServerName(): ?string
|
||||
{
|
||||
return $this->params['SERVER_NAME'] ?? null;
|
||||
}
|
||||
|
||||
public function withServerName(string $serverName): self
|
||||
{
|
||||
$this->params['SERVER_NAME'] = $serverName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutServerName(): void
|
||||
{
|
||||
unset($this->params['SERVER_NAME']);
|
||||
}
|
||||
|
||||
public function getRedirectStatus(): ?string
|
||||
{
|
||||
return $this->params['REDIRECT_STATUS'] ?? null;
|
||||
}
|
||||
|
||||
public function withRedirectStatus(string $redirectStatus): self
|
||||
{
|
||||
$this->params['REDIRECT_STATUS'] = $redirectStatus;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutRedirectStatus(): void
|
||||
{
|
||||
unset($this->params['REDIRECT_STATUS']);
|
||||
}
|
||||
|
||||
public function getHeader(string $name): ?string
|
||||
{
|
||||
return $this->params[static::convertHeaderNameToParamName($name)] ?? null;
|
||||
}
|
||||
|
||||
public function withHeader(string $name, string $value): self
|
||||
{
|
||||
$this->params[static::convertHeaderNameToParamName($name)] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutHeader(string $name): void
|
||||
{
|
||||
unset($this->params[static::convertHeaderNameToParamName($name)]);
|
||||
}
|
||||
|
||||
public function getHeaders(): array
|
||||
{
|
||||
$headers = [];
|
||||
foreach ($this->params as $name => $value) {
|
||||
if (strpos($name, 'HTTP_') === 0) {
|
||||
$headers[static::convertParamNameToHeaderName($name)] = $value;
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function withHeaders(array $headers): self
|
||||
{
|
||||
foreach ($headers as $name => $value) {
|
||||
$this->withHeader($name, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function withBody($body): Message
|
||||
{
|
||||
if (is_array($body)) {
|
||||
$body = http_build_query($body);
|
||||
$this->withContentType('application/x-www-form-urlencoded');
|
||||
}
|
||||
parent::withBody($body);
|
||||
return $this->withContentLength(strlen($body));
|
||||
}
|
||||
|
||||
protected static function convertHeaderNameToParamName(string $name)
|
||||
{
|
||||
return 'HTTP_' . str_replace('-', '_', strtoupper($name));
|
||||
}
|
||||
|
||||
protected static function convertParamNameToHeaderName(string $name)
|
||||
{
|
||||
return ucwords(str_replace('_', '-', substr($name, strlen('HTTP_'))), '-');
|
||||
}
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use Swoole\Http\Status;
|
||||
|
||||
class HttpResponse extends Response
|
||||
{
|
||||
/** @var int */
|
||||
protected $statusCode;
|
||||
|
||||
/** @var string */
|
||||
protected $reasonPhrase;
|
||||
|
||||
/** @var array */
|
||||
protected $headers = [];
|
||||
|
||||
/** @var array */
|
||||
protected $headersMap = [];
|
||||
|
||||
/** @var array */
|
||||
protected $setCookieHeaderLines = [];
|
||||
|
||||
public function __construct(array $records = [])
|
||||
{
|
||||
parent::__construct($records);
|
||||
$body = (string) $this->getBody();
|
||||
if (strlen($body) === 0) {
|
||||
return;
|
||||
}
|
||||
$array = explode("\r\n\r\n", $body, 2); // An array that contains the HTTP headers and the body.
|
||||
if (count($array) != 2) {
|
||||
$this->withStatusCode(Status::BAD_GATEWAY)->withReasonPhrase('Invalid FastCGI Response')->withError($body);
|
||||
return;
|
||||
}
|
||||
$headers = explode("\r\n", $array[0]);
|
||||
$body = $array[1];
|
||||
foreach ($headers as $header) {
|
||||
$array = explode(':', $header, 2); // An array that contains the name and the value of an HTTP header.
|
||||
if (count($array) != 2) {
|
||||
continue; // Invalid HTTP header? Ignore it!
|
||||
}
|
||||
$name = trim($array[0]);
|
||||
$value = trim($array[1]);
|
||||
if (strcasecmp($name, 'Status') === 0) {
|
||||
$array = explode(' ', $value, 2); // An array that contains the status code (and the reason phrase).
|
||||
$statusCode = $array[0];
|
||||
$reasonPhrase = $array[1] ?? null;
|
||||
} elseif (strcasecmp($name, 'Set-Cookie') === 0) {
|
||||
$this->withSetCookieHeaderLine($value);
|
||||
} else {
|
||||
$this->withHeader($name, $value);
|
||||
}
|
||||
}
|
||||
$statusCode = (int) ($statusCode ?? Status::OK);
|
||||
$reasonPhrase = (string) ($reasonPhrase ?? Status::getReasonPhrase($statusCode));
|
||||
$this->withStatusCode($statusCode)->withReasonPhrase($reasonPhrase);
|
||||
$this->withBody($body);
|
||||
}
|
||||
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
public function withStatusCode(int $statusCode): self
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReasonPhrase(): string
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
public function withReasonPhrase(string $reasonPhrase): self
|
||||
{
|
||||
$this->reasonPhrase = $reasonPhrase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeader(string $name): ?string
|
||||
{
|
||||
$name = $this->headersMap[strtolower($name)] ?? null;
|
||||
return $name ? $this->headers[$name] : null;
|
||||
}
|
||||
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function withHeader(string $name, string $value): self
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
$this->headersMap[strtolower($name)] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withHeaders(array $headers): self
|
||||
{
|
||||
foreach ($headers as $name => $value) {
|
||||
$this->withHeader($name, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSetCookieHeaderLines(): array
|
||||
{
|
||||
return $this->setCookieHeaderLines;
|
||||
}
|
||||
|
||||
public function withSetCookieHeaderLine(string $value): self
|
||||
{
|
||||
$this->setCookieHeaderLines[] = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
class Message
|
||||
{
|
||||
/** @var array */
|
||||
protected $params = [];
|
||||
|
||||
/** @var string */
|
||||
protected $body = '';
|
||||
|
||||
/** @var string */
|
||||
protected $error = '';
|
||||
|
||||
public function getParam(string $name): ?string
|
||||
{
|
||||
return $this->params[$name] ?? null;
|
||||
}
|
||||
|
||||
public function withParam(string $name, string $value): self
|
||||
{
|
||||
$this->params[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withoutParam(string $name): self
|
||||
{
|
||||
unset($this->params[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParams(): array
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function withParams(array $params): self
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withAddedParams(array $params): self
|
||||
{
|
||||
$this->params = $params + $this->params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBody(): string
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
public function withBody($body): self
|
||||
{
|
||||
$this->body = (string) $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getError(): string
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function withError(string $error): self
|
||||
{
|
||||
$this->error = $error;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
|
||||
/**
|
||||
* FastCGI record.
|
||||
*/
|
||||
class Record
|
||||
{
|
||||
/**
|
||||
* Identifies the FastCGI protocol version.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $version = FastCGI::VERSION_1;
|
||||
|
||||
/**
|
||||
* Identifies the FastCGI record type, i.e. the general function that the record performs.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $type = FastCGI::UNKNOWN_TYPE;
|
||||
|
||||
/**
|
||||
* Identifies the FastCGI request to which the record belongs.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $requestId = FastCGI::DEFAULT_REQUEST_ID;
|
||||
|
||||
/**
|
||||
* Reserved byte for future proposes
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $reserved = 0;
|
||||
|
||||
/**
|
||||
* The number of bytes in the contentData component of the record.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $contentLength = 0;
|
||||
|
||||
/**
|
||||
* The number of bytes in the paddingData component of the record.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $paddingLength = 0;
|
||||
|
||||
/**
|
||||
* Binary data, between 0 and 65535 bytes of data, interpreted according to the record type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $contentData = '';
|
||||
|
||||
/**
|
||||
* Padding data, between 0 and 255 bytes of data, which are ignored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $paddingData = '';
|
||||
|
||||
/**
|
||||
* Returns the binary message representation of record
|
||||
*/
|
||||
final public function __toString(): string
|
||||
{
|
||||
$headerPacket = pack(
|
||||
'CCnnCC',
|
||||
$this->version,
|
||||
$this->type,
|
||||
$this->requestId,
|
||||
$this->contentLength,
|
||||
$this->paddingLength,
|
||||
$this->reserved
|
||||
);
|
||||
|
||||
$payloadPacket = $this->packPayload();
|
||||
$paddingPacket = pack("a{$this->paddingLength}", $this->paddingData);
|
||||
|
||||
return $headerPacket . $payloadPacket . $paddingPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the message from the binary data buffer
|
||||
*
|
||||
* @param string $data Binary buffer with raw data
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
final public static function unpack(string $data): self
|
||||
{
|
||||
$self = new static();
|
||||
[
|
||||
$self->version,
|
||||
$self->type,
|
||||
$self->requestId,
|
||||
$self->contentLength,
|
||||
$self->paddingLength,
|
||||
$self->reserved
|
||||
] = array_values(unpack(FastCGI::HEADER_FORMAT, $data));
|
||||
|
||||
$payload = substr($data, FastCGI::HEADER_LEN);
|
||||
self::unpackPayload($self, $payload);
|
||||
if (get_called_class() !== __CLASS__ && $self->contentLength > 0) {
|
||||
static::unpackPayload($self, $payload);
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content data and adjusts the length fields
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setContentData(string $data): self
|
||||
{
|
||||
$this->contentLength = strlen($data);
|
||||
if ($this->contentLength > FastCGI::MAX_CONTENT_LENGTH) {
|
||||
$this->contentLength = FastCGI::MAX_CONTENT_LENGTH;
|
||||
$this->contentData = substr($data, 0, FastCGI::MAX_CONTENT_LENGTH);
|
||||
} else {
|
||||
$this->contentData = $data;
|
||||
}
|
||||
$extraLength = $this->contentLength % 8;
|
||||
$this->paddingLength = $extraLength ? (8 - $extraLength) : 0;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context data from the record
|
||||
*/
|
||||
public function getContentData(): string
|
||||
{
|
||||
return $this->contentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of record
|
||||
*/
|
||||
public function getVersion(): int
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns record type
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns request ID
|
||||
*/
|
||||
public function getRequestId(): int
|
||||
{
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets request ID
|
||||
*
|
||||
* There should be only one unique ID for all active requests,
|
||||
* use random number or preferably resetting auto-increment.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setRequestId(int $requestId): self
|
||||
{
|
||||
$this->requestId = $requestId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of content length
|
||||
*/
|
||||
final public function getContentLength(): int
|
||||
{
|
||||
return $this->contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of padding length
|
||||
*/
|
||||
final public function getPaddingLength(): int
|
||||
{
|
||||
return $this->paddingLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to unpack the payload for the record.
|
||||
*
|
||||
* NB: Default implementation will be always called
|
||||
*
|
||||
* @param static $self Instance of current frame
|
||||
* @param string $data Binary data
|
||||
*/
|
||||
protected static function unpackPayload($self, string $data): void
|
||||
{
|
||||
[
|
||||
$self->contentData,
|
||||
$self->paddingData
|
||||
] = array_values(
|
||||
unpack("a{$self->contentLength}contentData/a{$self->paddingLength}paddingData", $data)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of packing the payload
|
||||
*/
|
||||
protected function packPayload(): string
|
||||
{
|
||||
return pack("a{$this->contentLength}", $this->contentData);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* The Web server sends a FCGI_ABORT_REQUEST record to abort a request
|
||||
*/
|
||||
class AbortRequest extends Record
|
||||
{
|
||||
public function __construct(int $requestId = 0)
|
||||
{
|
||||
$this->type = FastCGI::ABORT_REQUEST;
|
||||
$this->setRequestId($requestId);
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* The Web server sends a FCGI_BEGIN_REQUEST record to start a request.
|
||||
*/
|
||||
class BeginRequest extends Record
|
||||
{
|
||||
/**
|
||||
* The role component sets the role the Web server expects the application to play.
|
||||
* The currently-defined roles are:
|
||||
* FCGI_RESPONDER
|
||||
* FCGI_AUTHORIZER
|
||||
* FCGI_FILTER
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $role = FastCGI::UNKNOWN_ROLE;
|
||||
|
||||
/**
|
||||
* The flags component contains a bit that controls connection shutdown.
|
||||
*
|
||||
* flags & FCGI_KEEP_CONN:
|
||||
* If zero, the application closes the connection after responding to this request.
|
||||
* If not zero, the application does not close the connection after responding to this request;
|
||||
* the Web server retains responsibility for the connection.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $flags;
|
||||
|
||||
/**
|
||||
* Reserved data, 5 bytes maximum
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reserved1;
|
||||
|
||||
public function __construct(int $role = FastCGI::UNKNOWN_ROLE, int $flags = 0, string $reserved = '')
|
||||
{
|
||||
$this->type = FastCGI::BEGIN_REQUEST;
|
||||
$this->role = $role;
|
||||
$this->flags = $flags;
|
||||
$this->reserved1 = $reserved;
|
||||
$this->setContentData($this->packPayload());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the role
|
||||
*
|
||||
* The role component sets the role the Web server expects the application to play.
|
||||
* The currently-defined roles are:
|
||||
* FCGI_RESPONDER
|
||||
* FCGI_AUTHORIZER
|
||||
* FCGI_FILTER
|
||||
*/
|
||||
public function getRole(): int
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags
|
||||
*
|
||||
* The flags component contains a bit that controls connection shutdown.
|
||||
*
|
||||
* flags & FCGI_KEEP_CONN:
|
||||
* If zero, the application closes the connection after responding to this request.
|
||||
* If not zero, the application does not close the connection after responding to this request;
|
||||
* the Web server retains responsibility for the connection.
|
||||
*/
|
||||
public function getFlags(): int
|
||||
{
|
||||
return $this->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param static $self
|
||||
*/
|
||||
protected static function unpackPayload($self, string $data): void
|
||||
{
|
||||
[
|
||||
$self->role,
|
||||
$self->flags,
|
||||
$self->reserved1
|
||||
] = array_values(unpack('nrole/Cflags/a5reserved', $data));
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
protected function packPayload(): string
|
||||
{
|
||||
return pack(
|
||||
'nCa5',
|
||||
$this->role,
|
||||
$this->flags,
|
||||
$this->reserved1
|
||||
);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Data binary stream
|
||||
*
|
||||
* FCGI_DATA is a second stream record type used to send additional data to the application.
|
||||
*/
|
||||
class Data extends Record
|
||||
{
|
||||
public function __construct(string $contentData = '')
|
||||
{
|
||||
$this->type = FastCGI::DATA;
|
||||
$this->setContentData($contentData);
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* The application sends a FCGI_END_REQUEST record to terminate a request, either because the application
|
||||
* has processed the request or because the application has rejected the request.
|
||||
*/
|
||||
class EndRequest extends Record
|
||||
{
|
||||
/**
|
||||
* The appStatus component is an application-level status code. Each role documents its usage of appStatus.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $appStatus = 0;
|
||||
|
||||
/**
|
||||
* The protocolStatus component is a protocol-level status code.
|
||||
*
|
||||
* The possible protocolStatus values are:
|
||||
* FCGI_REQUEST_COMPLETE: normal end of request.
|
||||
* FCGI_CANT_MPX_CONN: rejecting a new request.
|
||||
* This happens when a Web server sends concurrent requests over one connection to an application that is
|
||||
* designed to process one request at a time per connection.
|
||||
* FCGI_OVERLOADED: rejecting a new request.
|
||||
* This happens when the application runs out of some resource, e.g. database connections.
|
||||
* FCGI_UNKNOWN_ROLE: rejecting a new request.
|
||||
* This happens when the Web server has specified a role that is unknown to the application.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $protocolStatus = FastCGI::REQUEST_COMPLETE;
|
||||
|
||||
/**
|
||||
* Reserved data, 3 bytes maximum
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reserved1;
|
||||
|
||||
public function __construct(
|
||||
int $protocolStatus = FastCGI::REQUEST_COMPLETE,
|
||||
int $appStatus = 0,
|
||||
string $reserved = ''
|
||||
) {
|
||||
$this->type = FastCGI::END_REQUEST;
|
||||
$this->protocolStatus = $protocolStatus;
|
||||
$this->appStatus = $appStatus;
|
||||
$this->reserved1 = $reserved;
|
||||
$this->setContentData($this->packPayload());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns app status
|
||||
*
|
||||
* The appStatus component is an application-level status code. Each role documents its usage of appStatus.
|
||||
*/
|
||||
public function getAppStatus(): int
|
||||
{
|
||||
return $this->appStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the protocol status
|
||||
*
|
||||
* The possible protocolStatus values are:
|
||||
* FCGI_REQUEST_COMPLETE: normal end of request.
|
||||
* FCGI_CANT_MPX_CONN: rejecting a new request.
|
||||
* This happens when a Web server sends concurrent requests over one connection to an application that is
|
||||
* designed to process one request at a time per connection.
|
||||
* FCGI_OVERLOADED: rejecting a new request.
|
||||
* This happens when the application runs out of some resource, e.g. database connections.
|
||||
* FCGI_UNKNOWN_ROLE: rejecting a new request.
|
||||
* This happens when the Web server has specified a role that is unknown to the application.
|
||||
*/
|
||||
public function getProtocolStatus(): int
|
||||
{
|
||||
return $this->protocolStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param static $self
|
||||
*/
|
||||
protected static function unpackPayload($self, string $data): void
|
||||
{
|
||||
[
|
||||
$self->appStatus,
|
||||
$self->protocolStatus,
|
||||
$self->reserved1
|
||||
] = array_values(unpack('NappStatus/CprotocolStatus/a3reserved', $data));
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
protected function packPayload(): string
|
||||
{
|
||||
return pack(
|
||||
'NCa3',
|
||||
$this->appStatus,
|
||||
$this->protocolStatus,
|
||||
$this->reserved1
|
||||
);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
|
||||
/**
|
||||
* GetValues API
|
||||
*
|
||||
* The Web server can query specific variables within the application.
|
||||
* The server will typically perform a query on application startup in order to to automate certain aspects of
|
||||
* system configuration.
|
||||
*
|
||||
* The application responds by sending a record {FCGI_GET_VALUES_RESULT, 0, ...} with the values supplied.
|
||||
* If the application doesn't understand a variable name that was included in the query, it omits that name from
|
||||
* the response.
|
||||
*
|
||||
* FCGI_GET_VALUES is designed to allow an open-ended set of variables.
|
||||
*
|
||||
* The initial set provides information to help the server perform application and connection management:
|
||||
* FCGI_MAX_CONNS: The maximum number of concurrent transport connections this application will accept,
|
||||
* e.g. "1" or "10".
|
||||
* FCGI_MAX_REQS: The maximum number of concurrent requests this application will accept, e.g. "1" or "50".
|
||||
* FCGI_MPXS_CONNS: "0" if this application does not multiplex connections (i.e. handle concurrent requests
|
||||
* over each connection), "1" otherwise.
|
||||
*/
|
||||
class GetValues extends Params
|
||||
{
|
||||
/**
|
||||
* Constructs a request
|
||||
*
|
||||
* @param array $keys List of keys to receive
|
||||
*/
|
||||
public function __construct(array $keys = [])
|
||||
{
|
||||
parent::__construct(array_fill_keys($keys, ''));
|
||||
$this->type = FastCGI::GET_VALUES;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
|
||||
/**
|
||||
* GetValues API
|
||||
*
|
||||
* The Web server can query specific variables within the application.
|
||||
* The server will typically perform a query on application startup in order to to automate certain aspects of
|
||||
* system configuration.
|
||||
*
|
||||
* The application responds by sending a record {FCGI_GET_VALUES_RESULT, 0, ...} with the values supplied.
|
||||
* If the application doesn't understand a variable name that was included in the query, it omits that name from
|
||||
* the response.
|
||||
*
|
||||
* FCGI_GET_VALUES is designed to allow an open-ended set of variables.
|
||||
*
|
||||
* The initial set provides information to help the server perform application and connection management:
|
||||
* FCGI_MAX_CONNS: The maximum number of concurrent transport connections this application will accept,
|
||||
* e.g. "1" or "10".
|
||||
* FCGI_MAX_REQS: The maximum number of concurrent requests this application will accept, e.g. "1" or "50".
|
||||
* FCGI_MPXS_CONNS: "0" if this application does not multiplex connections (i.e. handle concurrent requests
|
||||
* over each connection), "1" otherwise.
|
||||
*/
|
||||
class GetValuesResult extends Params
|
||||
{
|
||||
/**
|
||||
* Constructs a param request
|
||||
*/
|
||||
public function __construct(array $values = [])
|
||||
{
|
||||
parent::__construct($values);
|
||||
$this->type = FastCGI::GET_VALUES_RESULT;
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Params request record
|
||||
*/
|
||||
class Params extends Record
|
||||
{
|
||||
/**
|
||||
* List of params
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values = [];
|
||||
|
||||
/**
|
||||
* Constructs a param request
|
||||
*/
|
||||
public function __construct(array $values = [])
|
||||
{
|
||||
$this->type = FastCGI::PARAMS;
|
||||
$this->values = $values;
|
||||
$this->setContentData($this->packPayload());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associative list of parameters
|
||||
*/
|
||||
public function getValues(): array
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param static $self
|
||||
*/
|
||||
protected static function unpackPayload($self, string $data): void
|
||||
{
|
||||
$currentOffset = 0;
|
||||
do {
|
||||
[$nameLengthHigh] = array_values(unpack('CnameLengthHigh', $data));
|
||||
$isLongName = ($nameLengthHigh >> 7 == 1);
|
||||
$valueOffset = $isLongName ? 4 : 1;
|
||||
|
||||
[$valueLengthHigh] = array_values(unpack('CvalueLengthHigh', substr($data, $valueOffset)));
|
||||
$isLongValue = ($valueLengthHigh >> 7 == 1);
|
||||
$dataOffset = $valueOffset + ($isLongValue ? 4 : 1);
|
||||
|
||||
$formatParts = [
|
||||
$isLongName ? 'NnameLength' : 'CnameLength',
|
||||
$isLongValue ? 'NvalueLength' : 'CvalueLength',
|
||||
];
|
||||
$format = join('/', $formatParts);
|
||||
[$nameLength, $valueLength] = array_values(unpack($format, $data));
|
||||
|
||||
// Clear top bit for long record
|
||||
$nameLength &= ($isLongName ? 0x7fffffff : 0x7f);
|
||||
$valueLength &= ($isLongValue ? 0x7fffffff : 0x7f);
|
||||
|
||||
[$nameData, $valueData] = array_values(
|
||||
unpack(
|
||||
"a{$nameLength}nameData/a{$valueLength}valueData",
|
||||
substr($data, $dataOffset)
|
||||
)
|
||||
);
|
||||
|
||||
$self->values[$nameData] = $valueData;
|
||||
|
||||
$keyValueLength = $dataOffset + $nameLength + $valueLength;
|
||||
$data = substr($data, $keyValueLength);
|
||||
$currentOffset += $keyValueLength;
|
||||
} while ($currentOffset < $self->getContentLength());
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
protected function packPayload(): string
|
||||
{
|
||||
$payload = '';
|
||||
foreach ($this->values as $nameData => $valueData) {
|
||||
if ($valueData === null) {
|
||||
continue;
|
||||
}
|
||||
$nameLength = strlen($nameData);
|
||||
$valueLength = strlen((string) $valueData);
|
||||
$isLongName = $nameLength > 127;
|
||||
$isLongValue = $valueLength > 127;
|
||||
$formatParts = [
|
||||
$isLongName ? 'N' : 'C',
|
||||
$isLongValue ? 'N' : 'C',
|
||||
"a{$nameLength}",
|
||||
"a{$valueLength}",
|
||||
];
|
||||
$format = join('', $formatParts);
|
||||
|
||||
$payload .= pack(
|
||||
$format,
|
||||
$isLongName ? ($nameLength | 0x80000000) : $nameLength,
|
||||
$isLongValue ? ($valueLength | 0x80000000) : $valueLength,
|
||||
$nameData,
|
||||
$valueData
|
||||
);
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Stderr binary stream
|
||||
*
|
||||
* FCGI_STDERR is a stream record for sending arbitrary data from the application to the Web server
|
||||
*/
|
||||
class Stderr extends Record
|
||||
{
|
||||
public function __construct(string $contentData = '')
|
||||
{
|
||||
$this->type = FastCGI::STDERR;
|
||||
$this->setContentData($contentData);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Stdin binary stream
|
||||
*
|
||||
* FCGI_STDIN is a stream record type used in sending arbitrary data from the Web server to the application
|
||||
*/
|
||||
class Stdin extends Record
|
||||
{
|
||||
public function __construct(string $contentData = '')
|
||||
{
|
||||
$this->type = FastCGI::STDIN;
|
||||
$this->setContentData($contentData);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Stdout binary stream
|
||||
*
|
||||
* FCGI_STDOUT is a stream record for sending arbitrary data from the application to the Web server
|
||||
*/
|
||||
class Stdout extends Record
|
||||
{
|
||||
public function __construct(string $contentData = '')
|
||||
{
|
||||
$this->type = FastCGI::STDOUT;
|
||||
$this->setContentData($contentData);
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI\Record;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record;
|
||||
|
||||
/**
|
||||
* Record for unknown queries
|
||||
*
|
||||
* The set of management record types is likely to grow in future versions of this protocol.
|
||||
* To provide for this evolution, the protocol includes the FCGI_UNKNOWN_TYPE management record.
|
||||
* When an application receives a management record whose type T it does not understand, the application responds
|
||||
* with {FCGI_UNKNOWN_TYPE, 0, {T}}.
|
||||
*/
|
||||
class UnknownType extends Record
|
||||
{
|
||||
/**
|
||||
* Type of the unrecognized management record.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $type1;
|
||||
|
||||
/**
|
||||
* Reserved data, 7 bytes maximum
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reserved1;
|
||||
|
||||
public function __construct(int $type = 0, string $reserved = '')
|
||||
{
|
||||
$this->type = FastCGI::UNKNOWN_TYPE;
|
||||
$this->type1 = $type;
|
||||
$this->reserved1 = $reserved;
|
||||
$this->setContentData($this->packPayload());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unrecognized type
|
||||
*/
|
||||
public function getUnrecognizedType(): int
|
||||
{
|
||||
return $this->type1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param static $self
|
||||
*/
|
||||
public static function unpackPayload($self, string $data): void
|
||||
{
|
||||
[$self->type1, $self->reserved1] = array_values(unpack('Ctype/a7reserved', $data));
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
protected function packPayload(): string
|
||||
{
|
||||
return pack(
|
||||
'Ca7',
|
||||
$this->type1,
|
||||
$this->reserved1
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use Swoole\FastCGI;
|
||||
use Swoole\FastCGI\Record\BeginRequest;
|
||||
use Swoole\FastCGI\Record\Params;
|
||||
use Swoole\FastCGI\Record\Stdin;
|
||||
|
||||
class Request extends Message
|
||||
{
|
||||
protected $keepConn = false;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$body = $this->getBody();
|
||||
$beginRequestFrame = new BeginRequest(FastCGI::RESPONDER, ($this->keepConn ? FastCGI::KEEP_CONN : 0));
|
||||
$paramsFrame = new Params($this->getParams());
|
||||
$paramsEofFrame = new Params();
|
||||
if (empty($body)) {
|
||||
$message = "{$beginRequestFrame}{$paramsFrame}{$paramsEofFrame}}";
|
||||
} else {
|
||||
$stdinList = [];
|
||||
while (true) {
|
||||
$stdinList[] = $stdin = new Stdin($body);
|
||||
$stdinLength = $stdin->getContentLength();
|
||||
if ($stdinLength === strlen($body)) {
|
||||
break;
|
||||
}
|
||||
$body = substr($body, $stdinLength);
|
||||
}
|
||||
$stdinList[] = new Stdin();
|
||||
$stdin = implode($stdinList);
|
||||
$message = "{$beginRequestFrame}{$paramsFrame}{$paramsEofFrame}{$stdin}}";
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function getKeepConn(): bool
|
||||
{
|
||||
return $this->keepConn;
|
||||
}
|
||||
|
||||
public function withKeepConn(bool $keepConn): self
|
||||
{
|
||||
$this->keepConn = $keepConn;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\FastCGI;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Swoole\FastCGI\Record\EndRequest;
|
||||
use Swoole\FastCGI\Record\Stderr;
|
||||
use Swoole\FastCGI\Record\Stdout;
|
||||
|
||||
class Response extends Message
|
||||
{
|
||||
public function __construct(array $records = [])
|
||||
{
|
||||
if (!static::verify($records)) {
|
||||
throw new InvalidArgumentException('Bad records');
|
||||
}
|
||||
$body = '';
|
||||
$error = '';
|
||||
foreach ($records as $record) {
|
||||
if ($record instanceof Stdout) {
|
||||
if ($record->getContentLength() > 0) {
|
||||
$body .= $record->getContentData();
|
||||
}
|
||||
} elseif ($record instanceof Stderr) {
|
||||
if ($record->getContentLength() > 0) {
|
||||
$error .= $record->getContentData();
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->withBody($body)->withError($error);
|
||||
}
|
||||
|
||||
public static function verify(array $records): bool
|
||||
{
|
||||
return !empty($records) && $records[count($records) - 1] instanceof EndRequest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Http;
|
||||
|
||||
abstract class Status
|
||||
{
|
||||
public const CONTINUE = 100;
|
||||
|
||||
public const SWITCHING_PROTOCOLS = 101;
|
||||
|
||||
public const PROCESSING = 102;
|
||||
|
||||
public const OK = 200;
|
||||
|
||||
public const CREATED = 201;
|
||||
|
||||
public const ACCEPTED = 202;
|
||||
|
||||
public const NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
|
||||
public const NO_CONTENT = 204;
|
||||
|
||||
public const RESET_CONTENT = 205;
|
||||
|
||||
public const PARTIAL_CONTENT = 206;
|
||||
|
||||
public const MULTI_STATUS = 207;
|
||||
|
||||
public const ALREADY_REPORTED = 208;
|
||||
|
||||
public const IM_USED = 226;
|
||||
|
||||
public const MULTIPLE_CHOICES = 300;
|
||||
|
||||
public const MOVED_PERMANENTLY = 301;
|
||||
|
||||
public const FOUND = 302;
|
||||
|
||||
public const SEE_OTHER = 303;
|
||||
|
||||
public const NOT_MODIFIED = 304;
|
||||
|
||||
public const USE_PROXY = 305;
|
||||
|
||||
public const SWITCH_PROXY = 306;
|
||||
|
||||
public const TEMPORARY_REDIRECT = 307;
|
||||
|
||||
public const PERMANENT_REDIRECT = 308;
|
||||
|
||||
public const BAD_REQUEST = 400;
|
||||
|
||||
public const UNAUTHORIZED = 401;
|
||||
|
||||
public const PAYMENT_REQUIRED = 402;
|
||||
|
||||
public const FORBIDDEN = 403;
|
||||
|
||||
public const NOT_FOUND = 404;
|
||||
|
||||
public const METHOD_NOT_ALLOWED = 405;
|
||||
|
||||
public const NOT_ACCEPTABLE = 406;
|
||||
|
||||
public const PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
|
||||
public const REQUEST_TIME_OUT = 408;
|
||||
|
||||
public const CONFLICT = 409;
|
||||
|
||||
public const GONE = 410;
|
||||
|
||||
public const LENGTH_REQUIRED = 411;
|
||||
|
||||
public const PRECONDITION_FAILED = 412;
|
||||
|
||||
public const REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
|
||||
public const REQUEST_URI_TOO_LARGE = 414;
|
||||
|
||||
public const UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
|
||||
public const REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
|
||||
public const EXPECTATION_FAILED = 417;
|
||||
|
||||
public const MISDIRECTED_REQUEST = 421;
|
||||
|
||||
public const UNPROCESSABLE_ENTITY = 422;
|
||||
|
||||
public const LOCKED = 423;
|
||||
|
||||
public const FAILED_DEPENDENCY = 424;
|
||||
|
||||
public const UNORDERED_COLLECTION = 425;
|
||||
|
||||
public const UPGRADE_REQUIRED = 426;
|
||||
|
||||
public const PRECONDITION_REQUIRED = 428;
|
||||
|
||||
public const TOO_MANY_REQUESTS = 429;
|
||||
|
||||
public const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
|
||||
|
||||
public const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
|
||||
public const INTERNAL_SERVER_ERROR = 500;
|
||||
|
||||
public const NOT_IMPLEMENTED = 501;
|
||||
|
||||
public const BAD_GATEWAY = 502;
|
||||
|
||||
public const SERVICE_UNAVAILABLE = 503;
|
||||
|
||||
public const GATEWAY_TIME_OUT = 504;
|
||||
|
||||
public const HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
|
||||
public const VARIANT_ALSO_NEGOTIATES = 506;
|
||||
|
||||
public const INSUFFICIENT_STORAGE = 507;
|
||||
|
||||
public const LOOP_DETECTED = 508;
|
||||
|
||||
public const NOT_EXTENDED = 510;
|
||||
|
||||
public const NETWORK_AUTHENTICATION_REQUIRED = 511;
|
||||
|
||||
protected static $reasonPhrases = [
|
||||
self::CONTINUE => 'Continue',
|
||||
self::SWITCHING_PROTOCOLS => 'Switching Protocols',
|
||||
self::PROCESSING => 'Processing',
|
||||
self::OK => 'OK',
|
||||
self::CREATED => 'Created',
|
||||
self::ACCEPTED => 'Accepted',
|
||||
self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information',
|
||||
self::NO_CONTENT => 'No Content',
|
||||
self::RESET_CONTENT => 'Reset Content',
|
||||
self::PARTIAL_CONTENT => 'Partial Content',
|
||||
self::MULTI_STATUS => 'Multi-status',
|
||||
self::ALREADY_REPORTED => 'Already Reported',
|
||||
self::IM_USED => 'IM Used',
|
||||
self::MULTIPLE_CHOICES => 'Multiple Choices',
|
||||
self::MOVED_PERMANENTLY => 'Moved Permanently',
|
||||
self::FOUND => 'Found',
|
||||
self::SEE_OTHER => 'See Other',
|
||||
self::NOT_MODIFIED => 'Not Modified',
|
||||
self::USE_PROXY => 'Use Proxy',
|
||||
self::SWITCH_PROXY => 'Switch Proxy',
|
||||
self::TEMPORARY_REDIRECT => 'Temporary Redirect',
|
||||
self::PERMANENT_REDIRECT => 'Permanent Redirect',
|
||||
self::BAD_REQUEST => 'Bad Request',
|
||||
self::UNAUTHORIZED => 'Unauthorized',
|
||||
self::PAYMENT_REQUIRED => 'Payment Required',
|
||||
self::FORBIDDEN => 'Forbidden',
|
||||
self::NOT_FOUND => 'Not Found',
|
||||
self::METHOD_NOT_ALLOWED => 'Method Not Allowed',
|
||||
self::NOT_ACCEPTABLE => 'Not Acceptable',
|
||||
self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
|
||||
self::REQUEST_TIME_OUT => 'Request Time-out',
|
||||
self::CONFLICT => 'Conflict',
|
||||
self::GONE => 'Gone',
|
||||
self::LENGTH_REQUIRED => 'Length Required',
|
||||
self::PRECONDITION_FAILED => 'Precondition Failed',
|
||||
self::REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
|
||||
self::REQUEST_URI_TOO_LARGE => 'Request-URI Too Large',
|
||||
self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
|
||||
self::REQUESTED_RANGE_NOT_SATISFIABLE => 'Requested range not satisfiable',
|
||||
self::EXPECTATION_FAILED => 'Expectation Failed',
|
||||
self::MISDIRECTED_REQUEST => 'Unprocessable Entity',
|
||||
self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity',
|
||||
self::LOCKED => 'Locked',
|
||||
self::FAILED_DEPENDENCY => 'Failed Dependency',
|
||||
self::UNORDERED_COLLECTION => 'Unordered Collection',
|
||||
self::UPGRADE_REQUIRED => 'Upgrade Required',
|
||||
self::PRECONDITION_REQUIRED => 'Precondition Required',
|
||||
self::TOO_MANY_REQUESTS => 'Too Many Requests',
|
||||
self::REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large',
|
||||
self::UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons',
|
||||
self::INTERNAL_SERVER_ERROR => 'Internal Server Error',
|
||||
self::NOT_IMPLEMENTED => 'Not Implemented',
|
||||
self::BAD_GATEWAY => 'Bad Gateway',
|
||||
self::SERVICE_UNAVAILABLE => 'Service Unavailable',
|
||||
self::GATEWAY_TIME_OUT => 'Gateway Time-out',
|
||||
self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported',
|
||||
self::VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
|
||||
self::INSUFFICIENT_STORAGE => 'Insufficient Storage',
|
||||
self::LOOP_DETECTED => 'Loop Detected',
|
||||
self::NOT_EXTENDED => 'Not Extended',
|
||||
self::NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required',
|
||||
];
|
||||
|
||||
public static function getReasonPhrases(): array
|
||||
{
|
||||
return static::$reasonPhrases;
|
||||
}
|
||||
|
||||
public static function getReasonPhrase(int $value): string
|
||||
{
|
||||
return static::$reasonPhrases[$value] ?? 'Unknown';
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
class MultibyteStringObject extends StringObject
|
||||
{
|
||||
public function length(): int
|
||||
{
|
||||
return mb_strlen($this->string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function indexOf(string $needle, int $offset = 0, ?string $encoding = null)
|
||||
{
|
||||
return mb_strpos($this->string, ...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function lastIndexOf(string $needle, int $offset = 0, ?string $encoding = null)
|
||||
{
|
||||
return mb_strrpos($this->string, ...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function pos(string $needle, int $offset = 0, ?string $encoding = null)
|
||||
{
|
||||
return mb_strpos($this->string, ...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function rpos(string $needle, int $offset = 0, ?string $encoding = null)
|
||||
{
|
||||
return mb_strrpos($this->string, ...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function ipos(string $needle, ?string $encoding = null)
|
||||
{
|
||||
return mb_stripos($this->string, ...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function substr(int $offset, ?int $length = null, ?string $encoding = null)
|
||||
{
|
||||
return new static(mb_substr($this->string, ...func_get_args()));
|
||||
}
|
||||
|
||||
public function chunk(int $splitLength = 1, ?int $limit = null): ArrayObject
|
||||
{
|
||||
return static::detectArrayType(mb_split($this->string, ...func_get_args()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole;
|
||||
|
||||
use TypeError;
|
||||
|
||||
class ObjectProxy
|
||||
{
|
||||
/** @var object */
|
||||
protected $__object;
|
||||
|
||||
public function __construct($object)
|
||||
{
|
||||
if (!is_object($object)) {
|
||||
throw new TypeError('Non-object given');
|
||||
}
|
||||
$this->__object = $object;
|
||||
}
|
||||
|
||||
public function __getObject()
|
||||
{
|
||||
return $this->__object;
|
||||
}
|
||||
|
||||
public function __get(string $name)
|
||||
{
|
||||
return $this->__object->{$name};
|
||||
}
|
||||
|
||||
public function __set(string $name, $value): void
|
||||
{
|
||||
$this->__object->{$name} = $value;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
return isset($this->__object->{$name});
|
||||
}
|
||||
|
||||
public function __unset(string $name): void
|
||||
{
|
||||
unset($this->__object->{$name});
|
||||
}
|
||||
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
return $this->__object->{$name}(...$arguments);
|
||||
}
|
||||
|
||||
public function __invoke(...$arguments)
|
||||
{
|
||||
/** @var mixed $object */
|
||||
$object = $this->__object;
|
||||
return $object(...$arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Swoole.
|
||||
*
|
||||
* @link https://www.swoole.com
|
||||
* @contact team@swoole.com
|
||||
* @license https://github.com/swoole/library/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Swoole\Process;
|
||||
|
||||
use Swoole\Constant;
|
||||
use function Swoole\Coroutine\run;
|
||||
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* @var Pool
|
||||
*/
|
||||
protected $pool;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $ipcType = SWOOLE_IPC_NONE;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $msgQueueKey = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $startFuncMap = [];
|
||||
|
||||
public function __construct(int $ipcType = SWOOLE_IPC_NONE, int $msgQueueKey = 0)
|
||||
{
|
||||
$this->setIPCType($ipcType)->setMsgQueueKey($msgQueueKey);
|
||||
}
|
||||
|
||||
public function add(callable $func, bool $enableCoroutine = false): self
|
||||
{
|
||||
$this->addBatch(1, $func, $enableCoroutine);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addBatch(int $workerNum, callable $func, bool $enableCoroutine = false): self
|
||||
{
|
||||
for ($i = 0; $i < $workerNum; $i++) {
|
||||
$this->startFuncMap[] = [$func, $enableCoroutine];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
$this->pool = new Pool(count($this->startFuncMap), $this->ipcType, $this->msgQueueKey, false);
|
||||
|
||||
$this->pool->on(Constant::EVENT_WORKER_START, function (Pool $pool, int $workerId) {
|
||||
[$func, $enableCoroutine] = $this->startFuncMap[$workerId];
|
||||
if ($enableCoroutine) {
|
||||
run($func, $pool, $workerId);
|
||||
} else {
|
||||
$func($pool, $workerId);
|
||||
}
|
||||
});
|
||||
|
||||
$this->pool->start();
|
||||
}
|
||||
|
||||
public function setIPCType(int $ipcType): self
|
||||
{
|
||||
$this->ipcType = $ipcType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIPCType(): int
|
||||
{
|
||||
return $this->ipcType;
|
||||
}
|
||||
|
||||
public function setMsgQueueKey(int $msgQueueKey): self
|
||||
{
|
||||
$this->msgQueueKey = $msgQueueKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMsgQueueKey(): int
|
||||
{
|
||||
return $this->msgQueueKey;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user