<?php declare(strict_types=1); ini_set('display_errors', 'On'); error_reporting(-1); /** * PDOi类 */ class PDOi { private ?PDO $pdo = null; private static ?PDOi $instance = null; /** * 将构造方法声明为private防止通过“new PDOi()”创建实例 */ private function __construct() { } /** * 将克隆方法声明为private防止复制实例 */ private function __clone() { } /** * 获取PDOi实例 * * @return PDOi PDOi实例 */ private static function getInstance(): PDOi { if (self::$instance === null) { self::$instance = new self(); $driver = 'mysql'; // 数据库驱动 $host = 'localhost'; // 主机地址,可选值:localhost | 192.168.*.* | 127.0.0.1 $dbname = 'test_db'; // 数据库名 $port = 3308; // 服务端口号 $charset = 'utf8mb4'; // 字符编码 $username = 'ZhangSan'; // 账号 $password = '********'; // 密码 // 构造数据源名称(Data Source Name)字符串 $dsn = "$driver:"; $dsn .= "host=$host:$port;"; // 重要提醒:由于主机地址为localhost,必须使用“localhost:$port”的格式。 $dsn .= "dbname=$dbname;"; // $dsn .= "port=$port;"; // 重要提醒:由于主机地址为localhost,导致port参数失效,必须在host参数就指定port。 $dsn .= "charset=$charset;"; // PDO连接选项 $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset", PDO::ATTR_EMULATE_PREPARES => false, ]; // 创建PDO类实例 try { self::$instance->pdo = new PDO($dsn, $username, $password, $options); } catch (PDOException $e) { exit('创建PDO实例失败:' . $e->getMessage()); } } return self::$instance; } /** * 获取数据库版本号 * * @return string 数据库版本号 */ public static function version(): string { try { $version = (string)self::getInstance()->pdo->getAttribute(PDO::ATTR_SERVER_VERSION); } catch (PDOException $e) { $version = $e->getMessage(); } return $version; } /** * 执行语句 * * @param string $query 要执行的SQL语句模板 * @param array $args 模板参数 * @return PDOStatement|false 执行成功返回PDOStatement实例,否则返回false */ public static function execute(string $query, array $args = []): PDOStatement|false { // 预处理要执行的语句 try { $sth = self::getInstance()->pdo->prepare($query); } catch (PDOException $e) { exit('预处理要执行的语句失败:' . $e->getMessage()); } // 绑定参数 if ($sth instanceof PDOStatement) { foreach ($args as $field => $value) { try { $sth->bindValue(":$field", $value); } catch (PDOException $e) { exit('绑定参数失败:' . $e->getMessage()); } } } // 执行语句 if ($sth instanceof PDOStatement && $sth->execute() === false) { $sth = false; } return $sth; } } echo '当前数据库版本号:' . PDOi::version() . PHP_EOL; // 当前数据库版本号:8.1.0 $query = 'SELECT * FROM `prefix_article` WHERE `aid` = :aid LIMIT 1'; $args = ['aid' => 2]; $sth = PDOi::execute($query, $args); if ($sth instanceof PDOStatement) { $fetchAll = $sth->fetchAll(); $row = $fetchAll[0] ?? []; if ($row) { echo "({$row['aid']}) ☛ {$row['title']} [点击:{$row['click']}]"; // (2) ☛ PHP是世界上最好の语言 [点击:9527] } else { echo '没有符合查询条件的数据'; } } //========== 总结 ==========// // 1、使用PDO连接MySQL8.1服务器时,如果主机地址为localhost,那么DSN的port参数会失效,必须使用“host=localhost:$port”才能正常连接, // 注意这只针对主机地址为localhost的情况,如果主机地址为IP地址(如:192.168.*.* 或 127.0.0.1),那么DSN的port参数依然有效,不需 // 要在host参数里就指定port。 // 2、对于“host=$host:$port”这种写法,不管MySQL服务器使用哪个版本,也不管$host使用localhost还是IP地址,该写法都是有效的,所以最安 // 全的办法就是统一使用“host=$host:$port”,DSN不再额外使用port参数指定端口号。
Copyright © 2024 码农人生. All Rights Reserved