【问题标题】:PHP PDO - can connect but query not workingPHP PDO - 可以连接但查询不起作用
【发布时间】:2012-01-12 00:41:26
【问题描述】:

我想摆脱旧 mysql 扩展的束缚,我只是对数据库中的表进行测试 PDO 连接和简单查询。我似乎能够连接,(“连接成功”回响)但这就是美好时光结束的地方。我现在花了太多时间尝试开始使用 PDO。

<?php
$host = 'localhost';
$port = '3306'; 
$username = 'user';
$password = 'blabla';
$database = 'workslist';

try {
    $db = new PDO("mysql:host=$host; port = $port; dbname = $database", $username, $password);
    echo 'connection successful<br />';

    $query = 'SELECT * FROM main';
    $statement = $db->prepare($query);
    $statement->execute();
    $results = $statement->fetchAll();
    $statement->closeCursor();      

    foreach($results as $r){
            echo $r['work'] . '<br />';
    }

} catch (PDOException $e) {
    echo 'Error!: ' . $e->getMessage() . '<br />';
    die();
} 
?>

上面有什么问题吗?

数据库名称是“workslist”,表名称是“main”,“work”是该表中的列之一。我使用的 PHP 版本是 5.3.4,并且在 win7 上使用 wamp。我运行了phpinfo(),在 PDO 标题下,启用了 PDO 驱动程序 mysql、sqlite。为了确保数据库和表确实存在,我已经使用 MySQL 进行了尝试,并且可以使用旧的 mysql_fetch_array() 方法返回行。我检查了 php.ini 文件以确保 "extension=php_pdo..." 行都未注释。

干杯

【问题讨论】:

  • 请注意,示例中的某些内容在学习时很好,但不应出现在生产代码中。不要使用SELECT *;仅选择您需要的列。数据访问和显示代码应保存在separate 模块中。
  • 谢谢 outis - 我只在他的问题中使用了SELECT * 以使查询尽可能简单。
  • &lt;br/&gt; 不是semantic。对于生产代码,请确保使用更合适的内容,例如段落或 list 元素。输出 HTML 时不要使用or die。您将获得无效的 HTML。
  • 确保在生产代码中不向非管理员用户输出数据库错误消息;这样做discloses too much informationPDOStatement::fetchAll 是资源密集型的;相反,使用foreach 循环遍历实现Traversable 的PDOStatement 对象。 “语句”更好地描述了SQL“语句”; “查询”更好地描述了您为获得结果而执行的操作。

标签: php pdo


【解决方案1】:

这应该可行。

请仔细检查您在该数据库中是否确实有一个名为“main”的表。

请注意,在您execute() 查询之前,PDO 不会发现此错误,如果您的查询有问题,默认行为是返回空结果,抛出一个例外。

要使 PDO 更嘈杂,请在构造 PDO 时添加PDO::ERRMODE_EXCEPTION 选项:

$db = new PDO("mysql:host=$host;port=$port;dbname=$database", $username, $password, 
              array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)
);

现在检查您是否看到以下内容:

Error!: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'workslist.main' doesn't exist

【讨论】:

  • 谢谢弗朗西斯 - 我收到了大约 100 个这样的错误:'注意:未定义的变量:第 25 行 C:\wamp\www\PDOtest.php 中的 r'。
  • 我正在查看该数据库的 phpmyadmin 页面,并且表 'main' 肯定在那里,该表中有一个名为 'work' 的列。谢谢 - 很高兴确定
  • 这很奇怪。 var_dump($results) 揭示了什么?
  • 啊哈!我认为@outis 有答案!我没有发现这一点,因为当我将 DSN 设置为我自己的 DB 值进行测试时,我自动从 DSN 中删除了空格。
  • 我把 DSN 中的所有空格都去掉了(还是不行)。不过我会记住的 - 谢谢
【解决方案2】:

特别的问题是DSN 字符串中不允许有空格。使用空格,不处理“dbname”指令,因此没有默认数据库。除了删除空格外,在语句中显式指定数据库可以帮助防止此类问题:

SELECT `work` FROM `workslist`.`main`

这样,如果由于某种原因没有默认数据库,查询仍然会成功。

【讨论】:

  • 现在我很困惑 - 我刚试过这个?? $query = $db->prepare("SELECT 'work' FROM 'workslist'.'main'"); $query->execute();
  • @berzerk:单引号表示字符串;反引号表示标识符。数据库、表和列名是标识符,因此您应该使用反引号,而不是单引号。
  • 所以我尝试了这个(不确定?) $query = $db->prepare("SELECT work FROM workslist.main"); “注意:未定义的变量:C:\wamp\www\PDOtest.php 中的 r...”(此评论不包括我的新反引号 - 顺便说一句,它也不起作用)
  • @berzerk:SO 的问答形式不适合讨论。发布的示例中唯一不正确的方面是 DSN 中的空格。如果您遇到其他问题,请在 SO 中搜索有关同一问题的现有问题(您遇到的错误是一个很好的起点),然后仅在找不到现有问题时才发布新问题。跨度>
  • 感谢您的回复 - 空间已超出 DSN 且仍无法正常工作...稍后我将在其他服务器上尝试。干杯
【解决方案3】:

PDO 不会抛出错误,除非您将其配置为:

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-09
    • 2018-11-28
    • 2013-10-04
    • 2012-10-22
    • 2011-05-17
    • 2017-12-18
    • 1970-01-01
    • 2014-07-12
    相关资源
    最近更新 更多