如何在 PHP 中选择要与 PDO 一起使用的 MySQL 数据库?
Posted
技术标签:
【中文标题】如何在 PHP 中选择要与 PDO 一起使用的 MySQL 数据库?【英文标题】:How do I select a MySQL database to use with PDO in PHP? 【发布时间】:2012-02-01 01:48:22 【问题描述】:我想在创建 php PDO 对象后选择要使用的 mysql 数据库。我该怎么做?
// create PDO object and connect to MySQL
$dbh = new PDO( 'mysql:host=localhost;', 'name', 'pass' );
// create a database named 'database_name'
// select the database we just created ( this does not work )
$dbh->select_db( 'database_name' );
是否有等效于 mysqli::select_db 的 PDO?
也许我试图不正确地使用 PDO?请帮忙或解释一下。
编辑
我不应该使用 PDO 创建新数据库吗?我知道使用 PDO 的大部分好处都在一个很少使用的操作上丢失了,它不插入像 CREATE DATABASE
这样的数据,但是必须使用不同的连接来创建数据库,然后创建一个 PDO 连接来创建似乎很奇怪其他电话。
【问题讨论】:
您可能需要创建一个新的 PDO 对象来连接到另一个数据库。 您可以使用select table.field from database.table
,假设您连接的任何用户 ID 都对其他数据库/表具有适当的权限。
创建新对象有什么问题?一旦你运行像“CREATE DATABASE”这样的查询,你就可以轻松地销毁它并继续使用新的连接。我真的看不出有什么问题。
这似乎是一件愚蠢的事情,这通常意味着我做错了其他事情。也许这只是一个边缘案例。 PDO 可能不常用于创建新数据库。
@Ignas:在我的测试中打开与数据库的连接(实例化 PDO)大约需要 23 毫秒。我实际上有数百个数据库;它使我的脚本花费的时间比使用 use
语句的时间长 4 倍。
【参考方案1】:
您应该在创建 PDO 对象时设置数据库。一个例子(来自here)
<?php
$hostname = "localhost";
$username = "your_username";
$password = "your_password";
try
$dbh = new PDO("mysql:host=$hostname;dbname=mysql", $username, $password);
echo "Connected to database"; // check for connection
catch(PDOException $e)
echo $e->getMessage();
?>
【讨论】:
【参考方案2】:据我所知,您必须为每个连接创建一个新对象。您始终可以使用连接到多个数据库的方法来扩展 PDO 类。然后随心所欲地使用它:
public function pickDatabase($db)
if($db == 'main')
return $this->db['main']; //instance of PDO object
else
return $this->db['secondary']; //another instance of PDO object
并像$yourclass->pickDatabase('main')->fetchAll('your stuff');
一样使用它
【讨论】:
为什么在PDO中创建对象时必须设置它而不是在MySQLi中? 好吧,我无法回答这个问题,因为 PHP 的人就是这样做的:)【参考方案3】:通常您会在连接时在 DSN 中指定数据库。但是,如果您正在创建一个新数据库,显然您不能在创建之前将该数据库指定为 DSN。
您可以使用USE
语句更改默认数据库:
$dbh = new PDO("mysql:host=...;dbname=mysql", ...);
$dbh->query("create database newdatabase");
$dbh->query("use newdatabase");
随后的CREATE TABLE
语句将在您的新数据库中创建。
@Mike 的回复:
当您像这样切换数据库时,它似乎会强制 PDO 模拟准备好的语句。将 PDO::ATTR_EMULATE_PREPARES 设置为 false,然后尝试使用另一个数据库将失败。
我只是做了一些测试,但我没有看到这种情况发生。更改数据库只发生在服务器上,它不会更改客户端中 PDO 的任何配置。这是一个例子:
<?php
// connect to database
try
$pdo = new PDO('mysql:host=huey;dbname=test', 'root', 'root');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
catch(PDOException $err)
die($err->getMessage());
$stmt = $pdo->prepare("select * from foo WHERE i = :i");
$result = $stmt->execute(array("i"=>123));
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
$pdo->exec("use test2");
$stmt = $pdo->prepare("select * from foo2 WHERE i = :i AND i = :i");
$result = $stmt->execute(array("i"=>456));
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
如果你说的是真的,那么这应该可以正常工作。只有当 PDO::ATTR_EMULATE_PREPARES 为真时,PDO 才能多次使用给定的命名参数。因此,如果您说此属性设置为 true 作为更改数据库的副作用,那么它应该可以工作。
但它不起作用——它得到一个错误“无效的参数号”,这表明非模拟的准备好的语句仍然有效。
【讨论】:
真的吗?询问?我很确定您正在寻找执行官 @TomvanderWoerdt:我测试了 query() 和 exec(),它们都可以工作。 query() 返回一个 PDOStatement 对象,而 exec() 返回受影响的行数(1 表示创建,0 表示使用)。对于这些语句,返回值几乎无关紧要。 关键是在打开的数据库句柄上更改默认数据库很容易;无需打开第二个数据库连接。 @Mike,我认为你错了。见上面的测试用例。 PDO::query() 在内部执行 prepare() 后跟 execute()。并非所有 MySQL 语句都可以使用 prepare 运行。请参阅“准备好的语句中允许的 SQL 语法”部分下的 dev.mysql.com/doc/refman/5.6/en/…。【参考方案4】:或者,您可以在创建 PHP PDO 对象后选择要使用的 MySQL 数据库,如下所示:
使用 USE 语句。但是记住这里 USE STATEMENT 是 mysql 命令
try
$conn = new PDO("mysql:host=$servername;", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("use databasename");
//application logic
catch(PDOException $e)
echo $sql . "<br>" . $e->getMessage();
$conn = null;
我希望我的代码对请求有帮助
【讨论】:
你只是在重复别人 5 年前所说的话。以上是关于如何在 PHP 中选择要与 PDO 一起使用的 MySQL 数据库?的主要内容,如果未能解决你的问题,请参考以下文章
在 PHP 中,当将 PDO 与 pgSQL 一起使用时,如何在原始 INSERT sql 查询中获取“RETURNING”子句的值
如何在 Flutter Web 中选择要上传的文件夹/文件夹?