Releases: Falseclock/dbd-php
Release list
3.1.5
dbd-php 3.1.5
Backward-compatible patch release. No public API or query execution behavior changed; PHP requirement (>=8.0) and Composer constraints unchanged. Every fix ships with a regression test that failed on 3.1.4.
Fixes
1. DBD\Cache\MemCache is loadable with psr/simple-cache ^3.0
- Bug. 3.1.4 raised the requirement to
psr/simple-cache ^3.0.0(typed PSR-16 signatures) butMemCache::get(),getMultiple(),setMultiple()anddeleteMultiple()kept untyped v1 signatures. Autoloading the class fails withPHP Fatal error: Declaration of DBD\Cache\MemCache::get($key, $default = null) must be compatible with Psr\SimpleCache\CacheInterface::get(string $key, mixed $default = null): mixed. - Impact. Any application that instantiates
MemCache(or passes it toConfig::setCacheDriver()) cannot run on 3.1.4; the library's own test suite could not start. - Fix. Return types
: mixed,: iterable,: bool,: booladded; parameters stay untyped (contravariant with the interface); PHPDoc@return voidcorrected to the real types. - Compatibility. Callers unaffected. Subclasses overriding one of the four methods must declare a compatible return type; such subclasses could not load on 3.1.4 either.
- Regression coverage.
tests/Cache/MemCacheCompatibilityTest.phploads the class in a separate PHP process (a signature mismatch is a compile-time fatal error that cannot be caught in-process).
2. PgUtils::tableStructure() reports nullability correctly
- Bug. ext-pgsql returns PostgreSQL booleans as the strings
't'/'f'; the code testedisset($row['is_nullable']), which is true for both, so every column came back withColumn->nullable === false, with and withoutOptions::convertBoolean. - Impact. Schema introspection and any code generation built on
tableStructure()treated nullable columns as NOT NULL. - Fix.
Column->nullable = Utils::convertBoolVar($row['is_nullable'])(handles't'/'f', native booleans and'true'/'false'; available in dbd-php-entity since 3.0.0, the minimum allowed version). - Compatibility.
Column->nullableis nowtruefor nullable columns; consumers that relied on the constantfalsewill observe the corrected value. - Regression coverage.
tests/Pg/PgUtilsNullableTest.php(testNullableIsParsedFromPostgresBooleanStrings,testNullableIsParsedWhenBooleanConversionIsEnabled) with a fixturerequired_value TEXT NOT NULL, optional_value TEXT NULL.
3. PgUtils::tableStructure() works for tables without a comment
- Bug.
obj_description()returns NULL for a table withoutCOMMENT ON TABLE; assigning it to the non-nullableTable::$annotation(string, dbd-php-entity 3.x) raisedTypeError: Cannot assign null to property DBD\Entity\Table::$annotation of type string. - Fix. Empty string when no comment exists.
- Compatibility. Previously a fatal error;
''is the only representable value for the typed property. - Regression coverage.
PgUtilsNullableTest::testTableWithoutCommentIsDescribedWithEmptyAnnotation.
4. Pg::escape() / Pg::escapeBinary() use the connection of the current Pg instance
- Bug.
Pg::_escape()andPg::_escapeBinary()calledpg_escape_string()/pg_escape_bytea()without a connection argument. ext-pgsql then uses the last opened PostgreSQL connection of the process (deprecated since PHP 8.1:Automatic fetching of PostgreSQL connection is deprecated), or no connection at all when nothing is connected yet. - Impact. Two deprecations in every process that escapes values (
src/Pg.php:504,src/Pg.php:483). With twoPginstances the escaping followed the connection opened last, not the instance's own (standard_conforming_strings, client encoding). On anonDemandinstance that had not connected yet,escape('a\b')doubled the backslash ('a\b', the pre-9.1 rule) andescapeBinary()produced the legacy escape format instead of the hex format the connection would use. - Fix. Both methods pass
$this->resourceLinkand, when the instance is not connected, open its own connection first with the existingif (!$this->isConnected()) { $this->_connect(); }semantics ofDBD::connectionPreCheck().escape(null|true|false)andescapeBinary(null)still never connect.pg_escape_literal()was deliberately not adopted (a separate API decision). - Compatibility. Return values for a connected instance are unchanged (pinned by
PgEscapeTestandPgEscapeConnectionTest). New: escaping a string or binary on a not-yet-connectedonDemandinstance opens the connection, as any query would, and can therefore throwDBDExceptionwhen the server is unreachable; before, it silently escaped without a connection. - Regression coverage.
tests/Pg/PgEscapeConnectionTest.php(+tests/Pg/PgConnectionProbe.php): results with an open connection; anonDemandinstance connects on the firstescape(string)/escapeBinary(non-null)and not before; reconnect afterdisconnect()like the query path; two instances with distinct backends (SET standard_conforming_strings = offon the one opened last) escape through their own connection. Three of the four tests fail on 3.1.4.
Test infrastructure (no production change)
- Test cache fixtures (
tests/Common/TestCacheDriver.php,tests/Common/BadCacheDriver.php) implement the PSR-16 v3 signatures. CommonTest::assertException()runs the callback withpg_*E_WARNINGs captured locally (captureDriverWarnings()): ext-pgsql reports intentionally failing queries, prepares and connections as warnings in addition to returningfalse; PHPUnit 10 no longer converts them to exceptions, so withfailOnWarning="true"the suite exited 1 even though all tests passed. Three tests that usedexpectException()directly now useassertException(). Non-driver warnings still reach PHPUnit.- Abstract base classes
tests/CommonTest.phpandtests/Pg/PgAbstractTest.phpare excluded from the test suite inphpunit.xml(PHPUnit 10 reported them as runner warnings).
Known, not changed
DBD::$preparedStatements is process-wide and keyed by crc32, DBD::$executedStatements grows unbounded, the ? placeholder scanner is not SQL-aware, two Pg instances with the same DSN share one libpq connection. These are v4 topics; see the v4 baseline report.
Creation of dynamic property Memcache::$connection is deprecated (reported at src/Cache/MemCache.php:45) is raised inside the PECL memcache extension: addServer() / connect() store the pool as a dynamic connection property of the Memcache object (add_property_resource() in src/memcache.c). Builds based on upstream 8.0 / 4.0.5.2 (for example Ubuntu 24.04 php8.3-memcache 8.0+4.0.5.2+..., reporting version 4.0.5.2) emit it on PHP 8.2+; upstream PECL memcache 8.2 (2023-04-30) flags Memcache / MemcachePool with ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES and is clean. No DBD code change; upgrade the extension.
Test result
PHPUnit 10.5.64, PostgreSQL 16: OK (97 tests, 1051 assertions), exit code 0 on PHP 8.1.34 (dbd-php-entity 3.0.0), 8.2.33 and 8.3.6 (3.1.4 baseline: suite could not start). The only remaining deprecation on the PHP 8.3 host is the PECL memcache 4.0.5.2 one described above; with PECL memcache 8.2 (the 8.1 / 8.2 runs) the suite reports none.
3.1.4
3.1.2
v3.1.0
v3.0.3
Fixes JSON field with entityUpdate and entityInsert
v3.0.2
Fixes JSON field with entityUpdate and entityInsert
v3.0.0
v2.0.1
php 8.0 & 8.1 PostgreSQL driver capability
v2.0.0
Latest Release of v1
v1 is no longer maintaned.
v2 is upcoming and in dev-master branch