diff --git a/composer.json b/composer.json
index 55effa2..1f58b5a 100644
--- a/composer.json
+++ b/composer.json
@@ -32,8 +32,8 @@
}
},
"require": {
- "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
- "php-db/phpdb": "^0.1.0"
+ "php": "~8.2.0 || ~8.3.0 || ~8.4.0",
+ "php-db/phpdb": "^0.1.1"
},
"require-dev": {
"ext-mysqli": "*",
diff --git a/composer.lock b/composer.lock
index 930fce5..8e9f62b 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "0a28997311306ff77626a0d7c49dc330",
+ "content-hash": "e5e1ef9a4473d1845705bbe6dfa7c935",
"packages": [
{
"name": "brick/varexporter",
@@ -259,16 +259,16 @@
},
{
"name": "php-db/phpdb",
- "version": "0.1.0",
+ "version": "0.1.1",
"source": {
"type": "git",
"url": "https://github.com/php-db/phpdb.git",
- "reference": "db3f84bd1952885ded3ed2b6731e82b7e9943bf9"
+ "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-db/phpdb/zipball/db3f84bd1952885ded3ed2b6731e82b7e9943bf9",
- "reference": "db3f84bd1952885ded3ed2b6731e82b7e9943bf9",
+ "url": "https://api.github.com/repos/php-db/phpdb/zipball/f671eabd951cd5da927ea814c8d0f83bb16247e0",
+ "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0",
"shasum": ""
},
"require": {
@@ -321,7 +321,7 @@
"issues": "https://github.com/php-db/phpdb/issues",
"source": "https://github.com/php-db/phpdb"
},
- "time": "2025-08-06T05:15:11+00:00"
+ "time": "2025-09-15T22:14:40+00:00"
},
{
"name": "psr/container",
@@ -2875,16 +2875,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "11.5.36",
+ "version": "11.5.39",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "264a87c7ef68b1ab9af7172357740dc266df5957"
+ "reference": "ad5597f79d8489d2870073ac0bc0dd0ad1fa9931"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/264a87c7ef68b1ab9af7172357740dc266df5957",
- "reference": "264a87c7ef68b1ab9af7172357740dc266df5957",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ad5597f79d8489d2870073ac0bc0dd0ad1fa9931",
+ "reference": "ad5597f79d8489d2870073ac0bc0dd0ad1fa9931",
"shasum": ""
},
"require": {
@@ -2956,7 +2956,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.36"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.39"
},
"funding": [
{
@@ -2980,7 +2980,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-03T06:24:17+00:00"
+ "time": "2025-09-14T06:20:41+00:00"
},
{
"name": "psalm/plugin-phpunit",
@@ -4246,16 +4246,16 @@
},
{
"name": "slevomat/coding-standard",
- "version": "8.22.0",
+ "version": "8.22.1",
"source": {
"type": "git",
"url": "https://github.com/slevomat/coding-standard.git",
- "reference": "a4cef983bad2e70125612d22b2f6e2bd1333d5c2"
+ "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/a4cef983bad2e70125612d22b2f6e2bd1333d5c2",
- "reference": "a4cef983bad2e70125612d22b2f6e2bd1333d5c2",
+ "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/1dd80bf3b93692bedb21a6623c496887fad05fec",
+ "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec",
"shasum": ""
},
"require": {
@@ -4267,11 +4267,11 @@
"require-dev": {
"phing/phing": "3.0.1|3.1.0",
"php-parallel-lint/php-parallel-lint": "1.4.0",
- "phpstan/phpstan": "2.1.22",
+ "phpstan/phpstan": "2.1.24",
"phpstan/phpstan-deprecation-rules": "2.0.3",
"phpstan/phpstan-phpunit": "2.0.7",
"phpstan/phpstan-strict-rules": "2.0.6",
- "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.36|12.3.8"
+ "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.36|12.3.10"
},
"type": "phpcodesniffer-standard",
"extra": {
@@ -4295,7 +4295,7 @@
],
"support": {
"issues": "https://github.com/slevomat/coding-standard/issues",
- "source": "https://github.com/slevomat/coding-standard/tree/8.22.0"
+ "source": "https://github.com/slevomat/coding-standard/tree/8.22.1"
},
"funding": [
{
@@ -4307,7 +4307,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-06T09:14:48+00:00"
+ "time": "2025-09-13T08:53:30+00:00"
},
{
"name": "spatie/array-to-xml",
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 59f46a9..5380170 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -7,25 +7,133 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ get('config')[AdapterManager::class]]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ get('config')[AdapterManager::class]]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
@@ -116,9 +224,6 @@
-
-
-
@@ -151,9 +256,6 @@
-
-
-
resource->affected_rows]]>
resource->num_rows]]>
@@ -225,9 +327,6 @@
-
-
-
@@ -288,9 +387,6 @@
-
-
-
@@ -303,9 +399,6 @@
-
-
-
@@ -480,14 +573,8 @@
-
-
-
-
-
-
@@ -546,9 +633,6 @@
-
-
-
@@ -585,15 +669,7 @@
-
-
-
-
-
-
-
-
processInfo['paramPrefix']]]>
processInfo['paramPrefix']]]>
diff --git a/psalm.xml.dist b/psalm.xml.dist
index a063019..d0a7d11 100644
--- a/psalm.xml.dist
+++ b/psalm.xml.dist
@@ -35,6 +35,12 @@
+
+
+
+
+
+
diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php
index 9eb4524..d0a9c1d 100644
--- a/src/ConfigProvider.php
+++ b/src/ConfigProvider.php
@@ -14,8 +14,12 @@
use PhpDb\Adapter\Mysql\Metadata\Source\MysqlMetadata;
use PhpDb\Adapter\Platform\PlatformInterface;
use PhpDb\Adapter\Profiler;
+use PhpDb\Container\AdapterAbstractServiceFactory;
use PhpDb\Container\AdapterManager;
+use PhpDb\Container\ConnectionInterfaceFactoryFactoryInterface;
+use PhpDb\Container\DriverInterfaceFactoryFactoryInterface;
use PhpDb\Container\MetadataFactory;
+use PhpDb\Container\PlatformInterfaceFactoryFactoryInterface;
use PhpDb\Metadata\MetadataInterface;
use PhpDb\ResultSet;
@@ -32,13 +36,16 @@ public function __invoke(): array
public function getDependencies(): array
{
return [
- 'aliases' => [
+ 'abstract_factories' => [
+ AdapterAbstractServiceFactory::class,
+ ],
+ 'aliases' => [
MetadataInterface::class => MysqlMetadata::class,
],
- 'factories' => [
+ 'factories' => [
MysqlMetadata::class => MetadataFactory::class,
],
- 'delegators' => [
+ 'delegators' => [
AdapterManager::class => [
Container\AdapterManagerDelegator::class,
],
@@ -49,24 +56,27 @@ public function getDependencies(): array
public function getAdapterManagerConfig(): array
{
return [
- 'aliases' => [
- 'MySqli' => Driver\Mysqli\Mysqli::class,
- 'MySQLi' => Driver\Mysqli\Mysqli::class,
- 'Mysqli' => Driver\Mysqli\Mysqli::class,
- 'mysqli' => Driver\Mysqli\Mysqli::class,
- 'PDO_MySQL' => Driver\Pdo\Pdo::class,
- 'Pdo_MySQL' => Driver\Pdo\Pdo::class,
- 'Pdo_Mysql' => Driver\Pdo\Pdo::class,
- 'pdo_mysql' => Driver\Pdo\Pdo::class,
- 'pdomysql' => Driver\Pdo\Pdo::class,
- 'pdodriver' => Driver\Pdo\Pdo::class,
- 'pdo' => Driver\Pdo\Pdo::class,
- DriverInterface::class => Driver\Mysqli\Mysqli::class,
- PdoDriverInterface::class => Driver\Pdo\Pdo::class,
- Profiler\ProfilerInterface::class => Profiler\Profiler::class,
- ResultSet\ResultSetInterface::class => ResultSet\ResultSet::class,
+ 'aliases' => [
+ 'MySqli' => Driver\Mysqli\Mysqli::class,
+ 'MySQLi' => Driver\Mysqli\Mysqli::class,
+ 'Mysqli' => Driver\Mysqli\Mysqli::class,
+ 'mysqli' => Driver\Mysqli\Mysqli::class,
+ 'PDO_MySQL' => Driver\Pdo\Pdo::class,
+ 'Pdo_MySQL' => Driver\Pdo\Pdo::class,
+ 'Pdo_Mysql' => Driver\Pdo\Pdo::class,
+ 'pdo_mysql' => Driver\Pdo\Pdo::class,
+ 'pdomysql' => Driver\Pdo\Pdo::class,
+ 'pdodriver' => Driver\Pdo\Pdo::class,
+ 'pdo' => Driver\Pdo\Pdo::class,
+ DriverInterface::class => Driver\Mysqli\Mysqli::class,
+ PdoDriverInterface::class => Driver\Pdo\Pdo::class,
+ Profiler\ProfilerInterface::class => Profiler\Profiler::class,
+ ResultSet\ResultSetInterface::class => ResultSet\ResultSet::class,
+ ConnectionInterfaceFactoryFactoryInterface::class => Container\ConnectionInterfaceFactoryFactory::class,
+ DriverInterfaceFactoryFactoryInterface::class => Container\DriverInterfaceFactoryFactory::class,
+ PlatformInterfaceFactoryFactoryInterface::class => Container\PlatformInterfaceFactoryFactory::class,
],
- 'factories' => [
+ 'factories' => [
AdapterInterface::class => Container\AdapterFactory::class,
Driver\Mysqli\Mysqli::class => Container\MysqliDriverFactory::class,
Driver\Mysqli\Connection::class => Container\MysqliConnectionFactory::class,
@@ -80,6 +90,14 @@ public function getAdapterManagerConfig(): array
Profiler\Profiler::class => InvokableFactory::class,
ResultSet\ResultSet::class => InvokableFactory::class,
],
+ 'invokables' => [
+ Container\ConnectionInterfaceFactoryFactory::class
+ => Container\ConnectionInterfaceFactoryFactory::class,
+ Container\DriverInterfaceFactoryFactory::class
+ => Container\DriverInterfaceFactoryFactory::class,
+ Container\PlatformInterfaceFactoryFactory::class
+ => Container\PlatformInterfaceFactoryFactory::class,
+ ],
];
}
}
diff --git a/src/Container/AdapterManagerDelegator.php b/src/Container/AdapterManagerDelegator.php
index 7ee69a7..c93cf39 100644
--- a/src/Container/AdapterManagerDelegator.php
+++ b/src/Container/AdapterManagerDelegator.php
@@ -5,7 +5,7 @@
namespace PhpDb\Adapter\Mysql\Container;
use Laminas\ServiceManager\Factory\DelegatorFactoryInterface;
-use PhpDB\Adapter\Mysql\ConfigProvider;
+use PhpDb\Adapter\Mysql\ConfigProvider;
use PhpDb\Container\AdapterManager;
use Psr\Container\ContainerInterface;
diff --git a/src/Container/ConnectionInterfaceFactoryFactory.php b/src/Container/ConnectionInterfaceFactoryFactory.php
new file mode 100644
index 0000000..d5f0cdf
--- /dev/null
+++ b/src/Container/ConnectionInterfaceFactoryFactory.php
@@ -0,0 +1,48 @@
+get('config')['db']['adapters'] ?? [];
+ if (! isset($adapterConfig[$requestedName]['driver'])) {
+ throw new RuntimeException(sprintf(
+ 'Named adapter "%s" is not configured with a driver',
+ $requestedName
+ ));
+ }
+ $adapterServices = $container->get('config')[AdapterManager::class];
+ $configuredDriver = $adapterConfig[$requestedName]['driver'];
+ if (array_key_exists($configuredDriver, $adapterServices['aliases'])) {
+ $aliasTo = $adapterServices['aliases'][$configuredDriver];
+ } else {
+ $aliasTo = $configuredDriver;
+ }
+ return match ($aliasTo) {
+ Mysqli::class => new MysqliConnectionFactory(),
+ Pdo::class => new PdoConnectionFactory(),
+ default => throw new RuntimeException(sprintf(
+ 'No connection factory found for driver "%s"',
+ $configuredDriver
+ )),
+ };
+ }
+}
diff --git a/src/Container/DriverInterfaceFactoryFactory.php b/src/Container/DriverInterfaceFactoryFactory.php
new file mode 100644
index 0000000..11190a1
--- /dev/null
+++ b/src/Container/DriverInterfaceFactoryFactory.php
@@ -0,0 +1,34 @@
+get('config')['db']['adapters'] ?? [];
+ if (! isset($adapterConfig[$requestedName]['driver'])) {
+ throw new RuntimeException(sprintf(
+ 'Named adapter "%s" is not configured with a driver',
+ $requestedName
+ ));
+ }
+ $adapterServices = $container->get('config')[AdapterManager::class];
+
+ $configuredDriver = $adapterConfig[$requestedName]['driver'];
+ $aliasTo ??= $adapterServices['aliases'][$configuredDriver] ?? $configuredDriver;
+ $driverFactory = $adapterServices['factories'][$aliasTo];
+ return new $driverFactory();
+ }
+}
diff --git a/src/Container/MysqliConnectionFactory.php b/src/Container/MysqliConnectionFactory.php
index 8c084ce..01117eb 100644
--- a/src/Container/MysqliConnectionFactory.php
+++ b/src/Container/MysqliConnectionFactory.php
@@ -4,14 +4,18 @@
namespace PhpDb\Adapter\Mysql\Container;
+use Laminas\ServiceManager\Factory\FactoryInterface;
use PhpDb\Adapter\Driver\ConnectionInterface;
use PhpDb\Adapter\Mysql\Driver\Mysqli\Connection;
use Psr\Container\ContainerInterface;
-final class MysqliConnectionFactory
+final class MysqliConnectionFactory implements FactoryInterface
{
- public function __invoke(ContainerInterface $container): ConnectionInterface&Connection
- {
+ public function __invoke(
+ ContainerInterface $container,
+ string $requestedName,
+ ?array $options = null
+ ): ConnectionInterface&Connection {
/** @var array $config */
$config = $container->get('config');
@@ -23,4 +27,12 @@ public function __invoke(ContainerInterface $container): ConnectionInterface&Con
return new Connection($connectionConfig);
}
+
+ public static function createFromConfig(
+ ContainerInterface $container,
+ string $requestedName
+ ): ConnectionInterface&Connection {
+ $adapterConfig = $container->get('config')['db']['adapters'][$requestedName] ?? [];
+ return new Connection($adapterConfig['connection'] ?? []);
+ }
}
diff --git a/src/Container/MysqliDriverFactory.php b/src/Container/MysqliDriverFactory.php
index 310bd3a..4b87376 100644
--- a/src/Container/MysqliDriverFactory.php
+++ b/src/Container/MysqliDriverFactory.php
@@ -41,4 +41,28 @@ public function __invoke(ContainerInterface $container): Driver\DriverInterface&
$options
);
}
+
+ public static function createFromConfig(
+ ContainerInterface $container,
+ string $requestedName,
+ ): Driver\DriverInterface&Mysqli\Mysqli {
+ /** @var AdapterManager $adapterManager */
+ $adapterManager = $container->get(AdapterManager::class);
+ $connectionFactory = (
+ $adapterManager->get(ConnectionInterfaceFactoryFactory::class)
+ )($container, $requestedName);
+ /** @var array $config */
+ $config = $container->get('config');
+ /** @var array $dbConfig */
+ $dbConfig = $config['db'] ?? [];
+ /** @var array $adapterConfig */
+ $adapterConfig = $dbConfig['adapters'][$requestedName] ?? [];
+
+ return new Mysqli\Mysqli(
+ $connectionFactory::createFromConfig($container, $requestedName),
+ $adapterManager->get(Mysqli\Statement::class),
+ $adapterManager->get(Mysqli\Result::class),
+ $adapterConfig['options'] ?? []
+ );
+ }
}
diff --git a/src/Container/PdoConnectionFactory.php b/src/Container/PdoConnectionFactory.php
index 5b07458..1370281 100644
--- a/src/Container/PdoConnectionFactory.php
+++ b/src/Container/PdoConnectionFactory.php
@@ -23,4 +23,12 @@ public function __invoke(ContainerInterface $container): ConnectionInterface&Con
return new Connection($connectionConfig);
}
+
+ public static function createFromConfig(
+ ContainerInterface $container,
+ string $requestedName
+ ): ConnectionInterface&Connection {
+ $adapterConfig = $container->get('config')['db']['adapters'][$requestedName] ?? [];
+ return new Connection($adapterConfig['connection'] ?? []);
+ }
}
diff --git a/src/Container/PdoDriverFactory.php b/src/Container/PdoDriverFactory.php
index 2d5420b..5e82d45 100644
--- a/src/Container/PdoDriverFactory.php
+++ b/src/Container/PdoDriverFactory.php
@@ -37,4 +37,39 @@ public function __invoke(ContainerInterface $container): PdoDriverInterface&PdoD
$resultInstance
);
}
+
+ public static function createFromConfig(
+ ContainerInterface $container,
+ string $requestedName,
+ ): PdoDriverInterface&PdoDriver {
+ /** @var AdapterManager $adapterManager */
+ $adapterManager = $container->get(AdapterManager::class);
+ $connectionFactory = (
+ $adapterManager->get(ConnectionInterfaceFactoryFactory::class)
+ )($container, $requestedName);
+ /** @var array $config */
+ $config = $container->get('config');
+ /** @var array $dbConfig */
+ $dbConfig = $config['db'] ?? [];
+ /** @var array $adapterConfig */
+ $adapterConfig = $dbConfig['adapters'][$requestedName] ?? [];
+ /** @var array $options */
+ $options = $adapterConfig['options'] ?? [];
+
+ /** @var ConnectionInterface&Connection $connectionInstance */
+ $connectionInstance = $connectionFactory::createFromConfig($container, $requestedName);
+
+ /** @var StatementInterface&Statement $statementInstance */
+ $statementInstance = $adapterManager->get(Statement::class);
+
+ /** @var ResultInterface&Result $resultInstance */
+ $resultInstance = $adapterManager->get(Result::class);
+
+ return new PdoDriver(
+ $connectionInstance,
+ $statementInstance,
+ $resultInstance,
+ $options
+ );
+ }
}
diff --git a/src/Container/PlatformInterfaceFactory.php b/src/Container/PlatformInterfaceFactory.php
index fdac197..7edbefd 100644
--- a/src/Container/PlatformInterfaceFactory.php
+++ b/src/Container/PlatformInterfaceFactory.php
@@ -33,4 +33,9 @@ public function __invoke(ContainerInterface $container): PlatformInterface&Mysql
return new Mysql($driverInstance);
}
+
+ public static function fromDriver(DriverInterface $driverInstance): PlatformInterface&Mysql
+ {
+ return new Mysql($driverInstance);
+ }
}
diff --git a/src/Container/PlatformInterfaceFactoryFactory.php b/src/Container/PlatformInterfaceFactoryFactory.php
new file mode 100644
index 0000000..01b4a36
--- /dev/null
+++ b/src/Container/PlatformInterfaceFactoryFactory.php
@@ -0,0 +1,16 @@
+container);
+ $connection = $factory($this->container, Connection::class);
self::assertInstanceOf(ConnectionInterface::class, $connection);
self::assertInstanceOf(Connection::class, $connection);
diff --git a/test/integration/Container/TestAsset/SetupTrait.php b/test/integration/Container/TestAsset/SetupTrait.php
index 3b728b3..57fd919 100644
--- a/test/integration/Container/TestAsset/SetupTrait.php
+++ b/test/integration/Container/TestAsset/SetupTrait.php
@@ -11,8 +11,8 @@
use PhpDb\Adapter\Driver\DriverInterface;
use PhpDb\Adapter\Mysql\ConfigProvider;
use PhpDb\Adapter\Mysql\Driver\Pdo\Pdo;
+use PhpDb\ConfigProvider as LaminasDbConfigProvider;
use PhpDb\Container\AdapterManager;
-use PhpDb\Container\ConfigProvider as LaminasDbConfigProvider;
use Psr\Container\ContainerInterface;
use function getenv;