为了让我的生活更轻松,我创建了一个函数DoQuery:
// DoQuery
function DoQuery($sql)
{
global $cm_db_host,$cm_db_user,$cm_db_pass,$cm_db_name;
$con = mysql_connect($cm_db_host,$cm_db_user,$cm_db_pass);
if(!$con) return 1001;
$db = mysql_select_db($cm_db_name);
if(!$db) return 1002;
$res = mysql_query($sql);
if(!$res) return 1003;
return $res;
mysql_close();
}
该功能完美无缺 - 似乎......
以下是我如何使用它:
$res = DoQuery("UPDATE table SET column1='value 1',column2='value 2' WHERE id=1;");
switch($res){
case true:
echo 'Response[success]ENDCMTAG';
break;
case 1001:
die('Response[dberror1001]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1002:
die('Response[dberror1002]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1003:
die('Response[dberror1003]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
}
现在,当我故意搞砸SQL语句时,应该使用case 1003
,case true
就是正在执行的内容。
根据PHP手册(是的,我确实查了!))MySQL INSERT,UPDATE ....将返回true或false。在我的DoQuery函数中,每当MySQL函数返回false时,我输出特定的错误代码,所以我知道它出错的地方。如果没有错误发生,$res
应为true,然后case true
应该执行,对吧?
问题是它总是输出true,即使我将SQL查询更改为垃圾。
如果我将case true
放在开关的底部,case 1001
始终执行当一切正常时 - 我知道因为我检查了{{1} } field,它是空的。
我做错了什么?
答案 0 :(得分:1)
您将返回值1003
,当与布尔值进行比较时,该值将计算为“truthy”值。它将始终评估为TRUE
。
// Essentially it is this:
if (1003) {
// I'm TRUE!!!
}
您也不能使用严格比较===
,因为在真实情况下,您返回的是MySQL结果资源,而不是布尔值TRUE
。
如果您重新安排switch()
以使有效资源案例位于底部,则会首先正确评估您的错误案例。
switch($res){
case 1001:
die('Response[dberror1001]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1002:
die('Response[dberror1002]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1003:
die('Response[dberror1003]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
// Valid result is the default case.
default:
echo 'Response[success]ENDCMTAG';
break;
}
但是,这有点奇怪,如果您的函数返回不同的错误值(如果它已更改)但是交换机未更新,则可能会导致问题。相反,您应首先检查值的真/假返回值,然后将其传递给开关以评估错误代码:
// Check if we have an Integer value. If we do, its an error code!
// If not, it's a result, or true!
if (is_int($res)) {
switch($res){
case 1001:
die('Response[dberror1001]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1002:
die('Response[dberror1002]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case 1003:
die('Response[dberror1003]ENDCMTAG\r\n'.
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
}
// $res was valid. Success!
else {
// handle your valid results
}
答案 1 :(得分:1)
切换语句总是做松散的比较。
因此,任何数字(但0)也将评估为True
。
我对你的代码的另一个改进是使用常量来表示错误代码。
define('QUERY_RESULT_SUCCESS', '1000');
define('QUERY_RESULT_CONNECTION_FAILED', '1001');
define('QUERY_RESULT_SELECTDB_FAILED', '1002');
define('QUERY_RESULT_QUERY_FAILED', '1003');
function DoQuery($sql)
{
global $cm_db_host,$cm_db_user,$cm_db_pass,$cm_db_name;
$con = mysql_connect($cm_db_host,$cm_db_user,$cm_db_pass);
if(!$con) return QUERY_RESULT_CONNECTION_FAILED;
$db = mysql_select_db($cm_db_name);
if(!$db) return QUERY_RESULT_SELECTDB_FAILED;
$res = mysql_query($sql);
if(!$res) return QUERY_RESULT_QUERY_FAILED;
return QUERY_RESULT_SUCCESS;
mysql_close();
}
$res = DoQuery("UPDATE table SET column1='value 1',column2='value 2' WHERE id=1;");
switch($res){
case QUERY_RESULT_SUCCESS:
echo 'Response['.QUERY_RESULT_SUCCESS.']ENDCMTAG';
break;
case QUERY_RESULT_CONNECTION_FAILED:
die('Response['.QUERY_RESULT_CONNECTION_FAILED.']ENDCMTAG'."\r\n".
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case QUERY_RESULT_SELECTDB_FAILED:
die('Response['.QUERY_RESULT_SELECTDB_FAILED.']ENDCMTAG'."\r\n".
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
case QUERY_RESULT_QUERY_FAILED:
die('Response['.QUERY_RESULT_QUERY_FAILED.']ENDCMTAG'."\r\n".
'MySQLError['.mysql_error().']ENDCMTAG\r\n');
break;
}
还要注意\r\n
周围的双引号,因为必须对其进行评估。