【问题标题】:PDO execute in PHPPDO 在 PHP 中执行
【发布时间】:2012-04-26 18:54:42
【问题描述】:

我在使用 PDO 执行语句时遇到了一些问题。我的代码如下所示:

try {

    $stmt = $this->dbh->prepare("INSERT INTO smtp_servers (host, port, ssl, auth, username, password) VALUES(:host, :port, :ssl, :auth, :username, :password)");
    $stmt->bindParam(':host', $serverOptions[0]);
    $stmt->bindParam(':port', $serverOptions[1]);
    $stmt->bindParam(':ssl', $serverOptions[2]);
    $stmt->bindParam(':auth', $serverOptions[3]);
    $stmt->bindParam(':username', $serverOptions[4]);
    $stmt->bindParam(':password', $serverOptions[5]);
    $stmt->execute();

} catch (PDOException $e) {
    print("fail");
}

如果我在 $stmt->execute(); 打印测试之前进行打印,它不会打印“失败”,但如果我在执行行之后打印,它不会打印文本。

有什么想法吗?

更新:

我试图抛出更通用的异常,但没有任何运气,我在使用整数的地方实现了PDO::PARAM_INT。并且还添加了一行:

$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

现在我的代码如下所示:

try {

    $stmt = $this->dbh->prepare("INSERT INTO smtp_servers (host, port, ssl, auth, username, password) VALUES(:host, :port, :ssl, :auth, :username, :password)");
    $stmt->bindParam(':host', $serverOptions[0]);
    $stmt->bindParam(':port', $serverOptions[1], PDO::PARAM_INT);
    $stmt->bindParam(':ssl', $serverOptions[2], PDO::PARAM_INT);
    $stmt->bindParam(':auth', $serverOptions[3], PDO::PARAM_INT);
    $stmt->bindParam(':username', $serverOptions[4]);
    $stmt->bindParam(':password', $serverOptions[5]);
    $stmt->execute();

} catch (PDOException $e) {
    debug("fail");
}

我想看看我的数据库表设计会有所帮助吗?

CREATE TABLE IF NOT EXISTS `smtp_servers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `host` varchar(50) NOT NULL,
  `port` int(11) DEFAULT NULL,
  `ssl` smallint(11) DEFAULT NULL,
  `auth` smallint(11) DEFAULT NULL,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

现在我收到此错误:

致命错误:未捕获异常 'PDOException' 并带有消息 'SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 13 行的 /var/www/isms/php/communication/Mail.php 的第 1 行的“ssl、auth、用户名、密码 FROM smtp_servers”附近使用正确的语法PDOException: SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 13 行的 /var/www/isms/php/communication/Mail.php 的第 1 行的“ssl、auth、用户名、密码 FROM smtp_servers”附近使用正确的语法堆栈:0.0002 649056 1. {main}() /var/www/isms/index.php:0 0.0023 867336 2. include('/var/www/isms/php/settings/ismsSettings.php') /var/www /isms/index.php:88 0.0065 1091712 3.require_once('/var/www/isms/php/settings/MailSettings.php') /var/www/isms/php/settings/ismsSettings.php:29 0.0147 2288960 4 .require_once('/var/www/isms/php/forms/settings/EditSmtpServer.php') /var/www/isms/php/settings/MailSettings.php:4 0.0155 2290456 5. Mail->getServers() /var /www/isms/php/forms/settings/EditSmtpServer.php:41 0.0156 2291888 6. PDOStatement->execute() /var/www/isms/php/communication/Mail.php:13

【问题讨论】:

  • 尝试将异常更改为通用Exception。 PDO 应该抛出 PDOException,但可能会以某种方式抛出不同的异常。
  • 另外,您的所有字段都是字符串吗? bindParam 的第三个参数是 data_type,默认为 PDO::PARAM_STR。您可能需要 PDO::PARAM_INT 或其他东西。
  • 错误信息很奇特——尤其是这部分:'ssl, auth, username, password FROM smtp_servers'。这看起来像 SELECT 语法,这不是您在这里所做的。 SELECT 是否早些时候失败了,并且在您发布代码之前它不会抛出异常。 `/var/www/isms/php/communication/Mail.php 第 13 行`是什么?

标签: php sql pdo


【解决方案1】:

除了安德鲁西关于“MySQL reserved words”的评论...... [ssl确实是MySQL的保留字!]

就目前而言,您的 create table 语句也按原样失败,但格式如下;没有

CREATE TABLE `smtp_servers` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`host` VARCHAR( 50 ) NOT NULL ,
`port` INT( 11 ) NOT NULL ,
`ssl` SMALLINT( 11 ) NOT NULL ,
`auth` SMALLINT( 11 ) NOT NULL ,
`username` VARCHAR( 50 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL
) ENGINE = MYISAM ;

虽然我一直在写这篇文章,但我注意到StackOverflow 使用spacing grave 进行格式化! ( ` )(`)

因此,最后将您的准备语句行更改为以下内容:

$stmt = $this->dbh->prepare("INSERT INTO `smtp_servers` 
    (`host`, `port`, `ssl`, `auth`, `username`, `password`) 
    VALUES(:host, :port, :ssl, :auth, :username, :password)");

注意: 为了便于阅读,仅以这种方式格式化 :)

【讨论】:

  • sql create 语句直接取自 mysql 导出文件,所以我猜它可以吗?回家后我会试试你的说法。
  • 我在查询中尝试了不使用 ssl,现在它可以工作了,非常感谢!
  • 请注意,如果您确实在列名周围使用了这些字符,您仍然可以使用列 `ssl` :) 很高兴您对其进行了排序并祝您工作顺利
【解决方案2】:

在您的代码示例中,fail 打印应该仅在出现问题时发生,即 try 块内的脚本抛出异常。

假设一切顺利并且查询成功,那么看不到这条线是一个好兆头。


如果查询没有成功,但您仍然没有看到错误消息,请尝试告诉 PDO 仅在出现错误时抛出 PDOExceptions:

$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

在实例化 PDO 对象之后。

【讨论】:

  • @Mathias:这是一个愚蠢的问题:查询有效吗?当你查看数据库时,它是否发生了变化?
  • 不,数据库没有更新,如果我不清楚,对不起:)
【解决方案3】:

您是否尝试过打印查询的 SQL,用您尝试插入的实际参数替换命名参数,然后从命令行运行它?

异常文本暗示 SQL 语句存在问题,而不是 PDO 连接存在问题,从命令行运行它会让您知道 SQL 本身是否有效。

【讨论】:

  • 你说得对,命令行也失败了(与我在网站上尝试使用的输入相同):mysql> INSERT INTO smtp_servers (host, port, ssl, auth, username, password) VALUES("hostname", 123, "1", "1", "user", "HKJ");ERROR 1064 (42000): 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以了解在 'ssl, auth, username, password) 附近使用的正确语法 VALUES("hostname", 123, "1", "1", "user", "HKJ") ' 在第 1 行 mysql>
  • 那些应该是单引号而不是双引号。
  • 我想知道您的某个字段名称是否是 SQL 保留字 - 看起来数据库在 INSERT 的第一部分抱怨列“port”或“ssl”。如果第一个有效,您可以再次从命令行尝试 INSERT,不使用端口列及其数据,然后不使用 ssl?
  • 我回家后试试看。但是,如果它是保留字,当我创建表时,MySQL 不应该抱怨吗?
  • 这是一个好点 - 我宁愿认为它会。我刚刚尝试创建一个包含名为 port 和 ssl 的字段的表,但当其中有一个名为 ssl 的字段时,我无法创建它。这是在 PHP 5.1.61 中;不过,我的 SQL 中可能有错字,因为我还没有喝过咖啡……
【解决方案4】:

这可能是因为您现在处于特定的命名空间中。尝试将} catch (PDOException $e) { 替换为} catch (\PDOException $e) {,看看是否有变化。

【讨论】:

  • @Mathias,你确定你添加了$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);?没看到……
  • 这是因为在这个文件中扩展的另一个类中连接到 mysql(并实例化 PDO)。
  • 你能复制连接和所有的东西吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 2012-09-11
  • 1970-01-01
  • 2015-11-15
  • 2012-07-02
  • 2012-12-29
  • 2017-04-15
相关资源
最近更新 更多