{"record":{"id":"e5bf0ebe00d62de8","repo":"phalcon/cphalcon","slug":"the-dialectclass-classname-must-implement-ph","errorCode":null,"errorMessage":"The 'dialectClass' '{className}' must implement Phalcon\\Db\\DialectInterface","messagePattern":"The 'dialectClass' '(.+?)' must implement Phalcon\\\\Db\\\\DialectInterface","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\InvalidDialectClass","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Adapter/AbstractAdapter.zep","lineNumber":214,"sourceCode":"        let connectionId = self::connectionConsecutive,\n            this->connectionId = connectionId,\n            self::connectionConsecutive = connectionId + 1;\n\n        /**\n         * Dialect class can override the default dialect\n         */\n        if !fetch dialectClass, descriptor[\"dialectClass\"] {\n            let dialectClass = \"phalcon\\\\db\\\\dialect\\\\\" . this->dialectType;\n        }\n\n        /**\n         * Create the instance only if the dialect is a string\n         */\n        if typeof dialectClass === \"string\" {\n            let this->dialect = create_instance(dialectClass);\n        } elseif typeof dialectClass === \"object\" {\n            if unlikely !(dialectClass instanceof DialectInterface) {\n                throw new InvalidDialectClass(get_class(dialectClass));\n            }\n\n            let this->dialect = dialectClass;\n        }\n\n        let this->descriptor = descriptor;\n\n        if (isset (descriptor[\"options\"]) && typeof descriptor[\"options\"] === \"array\") {\n            self::setup(descriptor[\"options\"]);\n        }\n    }\n\n    /**\n     * Adds a column to a table\n     */\n    public function addColumn( string tableName,  string schemaName, <ColumnInterface> column) -> bool\n    {\n        return this->{\"execute\"}(","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Adapter/AbstractAdapter.zep#L196-L232","documentation":"Thrown while constructing a Phalcon Db adapter (AbstractAdapter::__construct). The 'dialectClass' descriptor entry accepts either a string class name (instantiated via create_instance with no check) or an already-built object. Only the object path is validated: the object must implement Phalcon\\Db\\DialectInterface. Passing any other object (a query object, a PDO instance, a dialect class from a different Phalcon major version, a partial mock) trips InvalidDialectClass.","triggerScenarios":"new Mysql(['host' => ..., 'dialectClass' => $someObject]) where $someObject does not implement Phalcon\\Db\\DialectInterface; injecting an anonymous class or test double that only mimics some dialect methods; passing a Phalcon 3/4 dialect instance into a Phalcon 5/6 adapter.","commonSituations":"Custom dialects injected to tweak SQL generation; unit tests passing mocks that implement a subset of methods; config systems that stringify/unwrap values so what was meant to be MyDialect::class arrives as an unrelated object; mixing components across Phalcon major versions during an upgrade.","solutions":["Make the injected class implement Phalcon\\Db\\DialectInterface, most simply by extending Phalcon\\Db\\Dialect (which supplies all base methods)","Or pass a string class name instead of an instance: 'dialectClass' => MyDialect::class (the string path instantiates without the instanceof guard)","If the object came from config, fix the config value type: it must be either a fully qualified class name string or a DialectInterface instance"],"exampleFix":"// before\n$dialect = new class {  // anonymous class, no interface\n    public function select($a) { return $a; }\n};\n$db = new Mysql(['dialectClass' => $dialect, ...]);\n\n// after\n$dialect = new class extends \\Phalcon\\Db\\Dialect {};\n$db = new Mysql(['dialectClass' => $dialect, ...]);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"use Phalcon\\Db\\DialectInterface;\n\nfunction assertUsableDialect($dialectClass): void\n{\n    if (is_object($dialectClass) && !($dialectClass instanceof DialectInterface)) {\n        throw new InvalidArgumentException(sprintf(\n            '%s does not implement DialectInterface',\n            get_class($dialectClass)\n        ));\n    }\n}\n\nassertUsableDialect($descriptor['dialectClass'] ?? null);","tryCatchPattern":null,"preventionTips":["Prefer extending Phalcon\\Db\\Dialect for custom dialects — the interface is then satisfied implicitly","In config, use a class-name string ('dialectClass' => MyDialect::class) unless you must inject a configured instance","Validate the descriptor shape once in the factory that builds adapters, not at call sites"],"tags":["php","phalcon","db","dialect","interface","configuration","constructor"],"backgroundTag":"class-does-not-implement-interface","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}