{"record":{"id":"7c07fe24d5754e72","repo":"walkor/workerman","slug":"class-protocols-scheme-not-exist-7c07fe","errorCode":null,"errorMessage":"class \\Protocols\\$scheme not exist","messagePattern":"class \\\\Protocols\\\\\\$scheme not exist","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Connection/AsyncUdpConnection.php","lineNumber":92,"sourceCode":"     * @param string $remoteAddress\n     * @throws Throwable\n     */\n    public function __construct($remoteAddress, $contextOption = [])\n    {\n        // Get the application layer communication protocol and listening address.\n        [$scheme, $address] = explode(':', $remoteAddress, 2);\n        // Check application layer protocol class.\n        if ($scheme !== 'udp') {\n            // Validate scheme contains only safe characters for class name resolution.\n            if (!preg_match('/^[a-zA-Z][a-zA-Z0-9]*$/', $scheme)) {\n                throw new RuntimeException(\"Invalid protocol scheme '$scheme'\");\n            }\n            $scheme = ucfirst($scheme);\n            $this->protocol = '\\\\Protocols\\\\' . $scheme;\n            if (!class_exists($this->protocol)) {\n                $this->protocol = \"\\\\Workerman\\\\Protocols\\\\$scheme\";\n                if (!class_exists($this->protocol)) {\n                    throw new RuntimeException(\"class \\\\Protocols\\\\$scheme not exist\");\n                }\n            }\n        }\n\n        $this->remoteAddress = substr($address, 2);\n        $this->contextOption = $contextOption;\n    }\n\n    /**\n     * For udp package.\n     *\n     * @param resource $socket\n     * @return void\n     */\n    public function baseRead($socket): void\n    {\n        $recvBuffer = stream_socket_recvfrom($socket, static::MAX_UDP_PACKAGE_SIZE, 0, $remoteAddress);\n        if (false === $recvBuffer || empty($remoteAddress)) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Connection/AsyncUdpConnection.php#L74-L110","documentation":"For AsyncUdpConnection, any scheme other than 'udp' is resolved as an application-layer protocol class: '\\Protocols\\<Scheme>' first, then '\\Workerman\\Protocols\\<Scheme>'. When neither class can be autoloaded the constructor throws. This mirrors the TCP connection behavior and is how custom UDP wire formats are plugged in.","triggerScenarios":"new AsyncUdpConnection('mydns://host:53') without defining Protocols\\Mydns; typo such as 'dns2://' instead of the intended protocol name; protocol file present but the Protocols namespace is not in composer's PSR-4 autoload map; case mismatch between file name and the ucfirst()-derived class name on Linux.","commonSituations":"Prototyping a DNS-like or game UDP protocol and forgetting the protocol class; moving code into a project whose composer.json lacks the Protocols PSR-4 mapping; forgetting 'composer dump-autoload' after adding the mapping.","solutions":["Create Protocols/Mydns.php with namespace Protocols, class Mydns, implementing input/decode/encode static methods","Register the namespace in composer.json (\"psr-4\": {\"Protocols\\\\\": \"Protocols/\"}) and run composer dump-autoload","Or switch to plain 'udp://host:port' if no application protocol layer is needed"],"exampleFix":"// before\n$conn = new AsyncUdpConnection('mydns://8.8.8.8:53'); // throws class \\Protocols\\Mydns not exist\n\n// after\n// Protocols/Mydns.php\nclass Mydns { /* protocol implementation */ }\n// with PSR-4 mapping for Protocols\\\\ and composer dump-autoload run\n$conn = new AsyncUdpConnection('mydns://8.8.8.8:53');","handlingStrategy":"validation","validationCode":"$scheme = 'mydns';\nif ($scheme !== 'udp'\n    && !class_exists('\\\\Protocols\\\\' . ucfirst($scheme))\n    && !class_exists('\\\\Workerman\\\\Protocols\\\\' . ucfirst($scheme))) {\n    throw new InvalidArgumentException(\"Define Protocols\\\\\" . ucfirst($scheme) . ' before using ' . \"$scheme://\");\n}\n$conn = new AsyncUdpConnection(\"$scheme://8.8.8.8:53\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create the protocol class before writing the connection code, and verify it autoloads with a tiny php -r class_exists check","Keep the Protocols PSR-4 mapping in composer.json current"],"tags":["php","workerman","udp","protocol","autoloading"],"backgroundTag":"class-not-found","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}