连接池列表 */ private static $pools = []; /** * 通过配置文件创建一个 MySQL 连接池 * * @throws DBException */ public static function create(string $name, array $config) { $size = $config['pool_size'] ?? 64; switch ($config['type']) { case 'mysql': $connect_str = 'mysql:host={host};port={port};dbname={dbname};charset={charset}'; $table = [ '{host}' => $config['host'], '{port}' => $config['port'], '{dbname}' => $config['dbname'], '{charset}' => $config['charset'] ?? 'utf8mb4', ]; $connect_str = str_replace(array_keys($table), array_values($table), $connect_str); $args = [$config['username'], $config['password'], $config['options'] ?? []]; self::checkMysqlExtension(); break; case 'sqlite': $connect_str = 'sqlite:{dbname}'; if (FileSystem::isRelativePath($config['dbname'])) { $config['dbname'] = zm_dir(SOURCE_ROOT_DIR . '/' . $config['dbname']); } $table = [ '{dbname}' => $config['dbname'], ]; $args = []; $connect_str = str_replace(array_keys($table), array_values($table), $connect_str); break; default: throw new DBException('type ' . $config['type'] . ' not supported yet'); } switch (Driver::getActiveDriverClass()) { case WorkermanDriver::class: self::$pools[$name] = new WorkermanObjectPool($size, PDO::class, $connect_str, ...$args); break; case SwooleDriver::class: self::$pools[$name] = new SwooleObjectPool($size, PDO::class, $connect_str, ...$args); } } /** * 获取一个数据库连接池 * * @param string $name 连接池名称 * @return SwooleObjectPool|WorkermanObjectPool */ public static function pool(string $name) { if (!isset(self::$pools[$name]) && count(self::$pools) !== 1) { throw new RuntimeException("Pool {$name} not found"); } return self::$pools[$name] ?? self::$pools[array_key_first(self::$pools)]; } /** * 获取所有数据库连接池 * * @return PoolInterface[] */ public static function getAllPools(): array { return self::$pools; } /** * 销毁数据库连接池 * * @param string $name 数据库连接池名称 */ public static function destroyPool(string $name) { unset(self::$pools[$name]); } /** * 检查数据库启动必要的依赖扩展,如果不符合要求则抛出异常 * * @throws DBException */ public static function checkMysqlExtension() { ob_start(); phpinfo(); // 这个phpinfo是有用的,不能删除 $str = ob_get_clean(); $str = explode("\n", $str); foreach ($str as $v) { $v = trim($v); if ($v == '') { continue; } if (mb_strpos($v, 'API Extensions') === false) { continue; } if (mb_strpos($v, 'pdo_mysql') === false) { throw new DBException(zm_internal_errcode('E00028') . '未安装 mysqlnd php-mysql扩展。'); } } } }