You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[PHPUnit] Possible bugs surfaced from coverage improvements #76
The following findings need to be verified. Found during #57
Findings to flag (not fixed — src bugs uncovered):
Statement::bindParametersFromContainer — plain-array params (no errata) build empty bind type string → mysqli_stmt::bind_param(): Argument #1 ($types) must not be empty. Worked around in tests via ParameterContainer + errata. Real bug in execute(array) path.
getTrigger()/getTriggers() throw TypeError: TriggerObject::setActionOrder() wants string, MySQL INFORMATION_SCHEMA.TRIGGERS.ACTION_ORDER returns int. Library bug.
Statement::prepare() InvalidQueryException branch dead under PHP 8.1+ (mysqli throws mysqli_sql_exception, never returns false).
Metadata\Source::loadConstraintDataNames()
Uncaught ValueError: mysqli_stmt::bind_param(): Argument #1 ($types) must not be empty
at vendor/php-db/phpdb-mysql/src/Statement.php:233
from bindParametersFromContainer() at Statement.php:68
Reached on the mysqli driver: 'driver' => DriverInterface::class resolves through the ConfigProvider alias to PhpDb\Mysql\Driver. PDO does not hit it.
Cause. The driver builds $type only from errata, but appends an argument for every parameter. Insert::processInsert() and Update::processUpdate(), scalar branch, call offsetSet($column, $value) with no errata, so $type ends up empty and bind_param('', ...) throws.
Supporting: SqlInterface::TYPE_VALUE is declared and used nowhere in either package; 1ae5c59b and 86665115 replaced the TYPE_* constants with the ArgumentType enum; resolveColumnValue() sets no errata either. The scalar branch looks like it never got that plumbing.
Fixes.
A. In phpdb, set the type where the parameter is registered:
in Insert::processInsert() and Update::processUpdate(), or route the scalar branch through ArgumentType::Value.
B. In phpdb-mysql, default to 's' when a parameter carries no errata, so mysqli behaves like PDO. This also keeps hand-built ParameterContainers valid, which is what the tests do today.
Not mutually exclusive. Worth also replacing the tests' errata workaround with a plain-array case, since that workaround kept the suite green while every real Insert/Update with scalar values failed.
Impact: mysqli plus Insert/Update with scalar values, the ordinary path.
Activity
tyrsson commentedon Sep 24, 2026
Reproduced outside the test suite, on the ordinary path in a Mezzio app, with no hand-built container and no explicit errata.
Env: PHP 8.4.24,
phpdb ^0.6.x-dev,phpdb-mysql ^0.5.x-dev, MySQL 9.7.Reached on the mysqli driver:
'driver' => DriverInterface::classresolves through the ConfigProvider alias toPhpDb\Mysql\Driver. PDO does not hit it.Cause. The driver builds
$typeonly from errata, but appends an argument for every parameter.Insert::processInsert()andUpdate::processUpdate(), scalar branch, calloffsetSet($column, $value)with no errata, so$typeends up empty andbind_param('', ...)throws.Supporting:
SqlInterface::TYPE_VALUEis declared and used nowhere in either package;1ae5c59band86665115replaced theTYPE_*constants with theArgumentTypeenum;resolveColumnValue()sets no errata either. The scalar branch looks like it never got that plumbing.Fixes.
A. In
phpdb, set the type where the parameter is registered:in
Insert::processInsert()andUpdate::processUpdate(), or route the scalar branch throughArgumentType::Value.B. In
phpdb-mysql, default to's'when a parameter carries no errata, so mysqli behaves like PDO. This also keeps hand-builtParameterContainers valid, which is what the tests do today.Not mutually exclusive. Worth also replacing the tests' errata workaround with a plain-array case, since that workaround kept the suite green while every real
Insert/Updatewith scalar values failed.Impact: mysqli plus
Insert/Updatewith scalar values, the ordinary path.