db2_connect() returns 资源 ID 尽管失败

db2_connect() returns resource ID despite failing

我 运行 在 AS/400 V7R2 上使用来自 PHP 脚本的 ibm_db2 驱动程序。

我注意到,如果我使用 i5_libl 选项将无效的库列表传递给 db2_connect(),并且连接字符串的其余部分有效,它仍然会 return 一个资源 ID,尽管ini_set("display_errors", 1); 报告错误。此外,db2_conn_error()db2_conn_errormsg() 不包含任何内容。另一方面,当我提供有效的库列表时,我的 IF 语句以完全相同的方式计算,唯一的区别是 ini_set("display_errors", 1);[=20= 不会将错误输出到屏幕上]

我意识到,不是由于无效的库列表而失败,而是使用提供的数据库用户名的默认库列表建立连接。这对我来说可能很可怕,因为如果由于某种原因我的库列表无效,它将默认为错误的列表(主要问题是开发和生产环境的混合)。

其他人可以重现此行为吗?我不知道这是否只是我的系统,我需要一个 PTF,或者这是否是典型的。您如何验证是否使用预期选项建立了 DB2 连接?

重现代码(相应地替换系统名称、用户名和密码):

<?php
ini_set("display_errors", 1);
$systemName = 'yourSystemName';
$userID = 'yourUserID';
$password = 'yourPassword';
$options['i5_libl'] = implode('Z', array(
    'INVALID',        
    'LIB',       
    'LIST',   
    'IMPLODED',  
    'WITH',   
    'THE',      
    'LETTER',       
    'Z'
));
$options['i5_naming'] = DB2_I5_NAMING_ON;

$conn = db2_connect($systemName,$userID,$password,$options);
//The error output to the screen at this point from `ini_set("display_errors", 1);` is:
//Warning: db2_connect(): Statement Execute Failed in /PATH/TO/FILE/test.php on line 58 

echo "<br />|".db2_conn_error()." ||| ".db2_conn_errormsg()."|<br />"; //This displays as "| ||| |"
print_r($conn); //This prints out a resource ID
echo "<br />";

if(isset($conn) && $conn === true){ 
    //Expected to not pass since either false or a resource ID is supposed to be returned.
    //Evaluated to false.
    echo "Boolean true<br />";
}
if(isset($conn) && $conn == true){ 
    //Despite the connection failing according to `ini_set("display_errors", 1)` and a resource ID being reportedly returned
    //this evaluates to true and "Non-Boolean true 2" echos out to the screen.
    echo "Non-Boolean true 2<br />";  
}
if(isset($conn) && $conn == "true"){ 
    //Evaluates to false. db2_connect() returns a resource ID on success, so I did not expect this to evaluate to true.
    echo "String true";
}
if(isset($conn) && $conn === false){ 
    //Expected for this to evaluate to true since an error was logged by ini_set("display_errors", 1)
    //This did not evaluate to true.
    echo "Boolean false<br />";
}
if(isset($conn) && $conn == false){ 
    //Just checking to see if a non-Boolean false was returned.  Evaluates to false.
    echo "Non-Boolean false 2<br />";
}
if(isset($conn) && $conn == "false"){ 
    //Just checking to see if the string "false" was returned.  Evaluates to false.
    echo "String false";
}
?>

我最终用 Zend 开了一张票,结果证明这是有意的行为。

我们知道 i5_libl 选项根据 http://php.net/manual/en/function.db2-connect.php 调用 qsys2/qcmdexc('cmd',cmdlen)。但逻辑上必须建立连接,以便它知道要为哪个 QSQSRVR 作业更改库列表。它不会在失败时关闭连接,而是发出警告并且 db_conn_error()db2_connerrormsg() 报告一切正常。

幸运的是,这注册为语句错误,可以通过以下方式检测到:

if (db2_stmt_error()) {
    echo "error ID: " . (db2_stmt_error());
    echo "<br>error message: " . (db2_stmt_errormsg());
}

我建议 Zend 关闭连接或者强制连接错误什么的。我想不出任何我想在没有任何警告或明显通知的情况下使用我指定的库列表连接到数据库的实例。如果开发和生产数据相互交织在一起,这可能会导致灾难。