如何在 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-&gt;pickDatabase('main')-&gt;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”子句的值

PHP:如何让我的 IF 语句与 PDO 选择一起使用?

如何在 Flutter Web 中选择要上传的文件夹/文件夹?

如何从 XML Android 开发中选择要显示的内容 [重复]

在Redhat上使用PDO进行SQL Server安装

将 PDO 与 PostgreSQL 一起使用时如何忽略问号作为占位符