phalcon/cphalcon · error · Phalcon\Db\Exceptions\InvalidDialectClass

The 'dialectClass' '{className}' must implement Phalcon\Db\D

Error message

The 'dialectClass' '{className}' must implement Phalcon\Db\DialectInterface

What it means

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.

Source

Thrown at phalcon/Db/Adapter/AbstractAdapter.zep:214

        let connectionId = self::connectionConsecutive,
            this->connectionId = connectionId,
            self::connectionConsecutive = connectionId + 1;

        /**
         * Dialect class can override the default dialect
         */
        if !fetch dialectClass, descriptor["dialectClass"] {
            let dialectClass = "phalcon\\db\\dialect\\" . this->dialectType;
        }

        /**
         * Create the instance only if the dialect is a string
         */
        if typeof dialectClass === "string" {
            let this->dialect = create_instance(dialectClass);
        } elseif typeof dialectClass === "object" {
            if unlikely !(dialectClass instanceof DialectInterface) {
                throw new InvalidDialectClass(get_class(dialectClass));
            }

            let this->dialect = dialectClass;
        }

        let this->descriptor = descriptor;

        if (isset (descriptor["options"]) && typeof descriptor["options"] === "array") {
            self::setup(descriptor["options"]);
        }
    }

    /**
     * Adds a column to a table
     */
    public function addColumn( string tableName,  string schemaName, <ColumnInterface> column) -> bool
    {
        return this->{"execute"}(

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Make the injected class implement Phalcon\Db\DialectInterface, most simply by extending Phalcon\Db\Dialect (which supplies all base methods)
  2. Or pass a string class name instead of an instance: 'dialectClass' => MyDialect::class (the string path instantiates without the instanceof guard)
  3. 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

Example fix

// before
$dialect = new class {  // anonymous class, no interface
    public function select($a) { return $a; }
};
$db = new Mysql(['dialectClass' => $dialect, ...]);

// after
$dialect = new class extends \Phalcon\Db\Dialect {};
$db = new Mysql(['dialectClass' => $dialect, ...]);
Defensive patterns

Strategy: type-guard

Type guard

use Phalcon\Db\DialectInterface;

function assertUsableDialect($dialectClass): void
{
    if (is_object($dialectClass) && !($dialectClass instanceof DialectInterface)) {
        throw new InvalidArgumentException(sprintf(
            '%s does not implement DialectInterface',
            get_class($dialectClass)
        ));
    }
}

assertUsableDialect($descriptor['dialectClass'] ?? null);

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/e5bf0ebe00d62de8. Report an issue: GitHub.