求教关于PDO使用的问题

原创
2016-06-23 13:51:13 722浏览

相关的数据库是这样的:

CREATE TABLE `session` (  `skey` char(32) CHARACTER SET ascii NOT NULL,  `data` text COLLATE utf8mb4_bin,  `expire` int(11) NOT NULL,  PRIMARY KEY (`skey`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;


相关的PHP代码大致如下(,我隐藏掉了一些无关的代码):
define('DNS', 'mysql:host=localhost;dbname=db;charset=utf8mb4');define('USR', 'usr');define('PWD', 'pwd');define('MAXLIFETIME', 1440);function write($id, $data) {	try {		$dbh = new PDO(DNS, USR, PWD, array(			PDO::ATTR_PERSISTENT => TRUE,			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,			PDO::ATTR_EMULATE_PREPARES => FALSE		));		try {			$expire = time() + MAXLIFETIME;			$sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) '					. 'VALUES (:skey, :data, :expire) '					. 'ON DUPLICATE KEY UPDATE '					. '`data` = :data, `expire` = :expire';			$stmt = $dbh->prepare($sql);			$stmt->bindValue(':skey', $id, PDO::PARAM_STR);			$stmt->bindValue(':data', $data, PDO::PARAM_STR);			$stmt->bindValue(':expire', $expire, PDO::PARAM_INT);			$stmt->execute();			$dbh = NULL;		} catch (Exception $e) {			echo $e->getTraceAsString();		}	} catch (Exception $e) {		echo $e->getTraceAsString();	}}write('12345678', '87654321');


其中的关键似乎在
PDO::ATTR_PERSISTENT => TRUE,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

这两句上。

只有注释掉这两句,运行OK,这两句中的任何一句生效,则发生异常。
请问,这是什么情况?求指点。


回复讨论(解决方案)

异常信息是什么?看看不就知道了

数据插进去了么,异常信息打印出来看看,还有try 里面 嵌套try 似乎没有这种写法。

异常信息是什么?看看不就知道了


抱歉,是我糊涂了。
异常信息大概是这样的:
#0 /***************/pdo.php(23): PDOStatement->execute() #1 /****************/pdo.php(33): write('12345678', '87654321') #2 {main}

数据插进去了么,异常信息打印出来看看,还有try 里面 嵌套try 似乎没有这种写法。



谢谢您指点,关于异常的处理,刚刚接触 :( 。
异常,主要应该是$stmt->execute();那一句。

以为对异常处理不熟悉,所以,还不大知道怎么打印更详细的异常信息。

你不是在寻求帮助吗?
藏藏匿匿的怎么行?

你不是在寻求帮助吗?
藏藏匿匿的怎么行?



抱歉,隐藏掉的时一些涉及到工程的注释和路径名称。
这些不方便公开又偷懒,抱歉了。
俺重新写一段测试代码上来,请稍等。

你不是在寻求帮助吗?
藏藏匿匿的怎么行?



代码如下:
 TRUE,			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,			PDO::ATTR_EMULATE_PREPARES => FALSE		));		$expire = time() + MAXLIFETIME;		$sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) '				. 'VALUES (:skey, :data, :expire) '				. 'ON DUPLICATE KEY UPDATE '				. '`data` = :data, `expire` = :expire';		$stmt = $dbh->prepare($sql);		$stmt->bindValue(':skey', $id, PDO::PARAM_STR);		$stmt->bindValue(':data', $data, PDO::PARAM_STR);		$stmt->bindValue(':expire', $expire, PDO::PARAM_INT);		$stmt->execute();		$dbh = NULL;	} catch (Exception $e) {		echo $e->getTraceAsString();	}}write('12345678', '87654321');


异常信息如下:
#0 /Library/WebServer/Documents/php/phplearn/pdo.php(28): PDOStatement->execute() #1 /Library/WebServer/Documents/php/phplearn/pdo.php(35): write('12345678', '87654321') #2 {main}

如果注释掉7楼代码的14、15两行,则不再发生异常,也不报错,但运行代码后检查发现数据并没有插入到数据库中。

你的 SQL 指令需要 5 个参数,而你只给了 3 个!
echo $e->getTraceAsString();
改为
echo $e->getMessage() ;
你就可以看到:
Error!: SQLSTATE[HY093]: Invalid parameter number

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
启用异常处理模式
注释掉就是按默认错误处理模式,可通过 errorInfo 取得错误信息

PDO::ATTR_PERSISTENT => TRUE,
启用长连接
只在复用连接时会抛出异常

谢谢您的指点。代码修改成功了。

$sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) '				. 'VALUES (:skey, :data, :expire) '				. 'ON DUPLICATE KEY UPDATE'				. '`data` = :data_updata, `expire` = :expire_updata';		$stmt = $dbh->prepare($sql);		$stmt->bindValue(':skey', $id, PDO::PARAM_STR);		$stmt->bindValue(':data', $data, PDO::PARAM_STR);		$stmt->bindValue(':expire', $expire, PDO::PARAM_INT);		$stmt->bindValue(':data_updata', $data, PDO::PARAM_STR);		$stmt->bindValue(':expire_updata', $expire, PDO::PARAM_INT);

头前以为,insert into 中的:data和on duplicate子句中的:data是同一个变量,只需要一个绑定呢。
看起来不能这么做。

关于原本的错误代码,为啥在初始化PDO对象的时候使用PDO::ATTR_PERSISTENT => TRUE,会导致异常呢?
关于“复用连接”的说法,是啥地方构成了复用连接呢?

再次感谢。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。