虽然我对php和ajax比较陌生,但我一定会彻底研究这个问题。我有一个PHP脚本(Environment.php)调用我的数据库并成功填充导航面板与我的所有环境。点击环境(这是一个指向javascript函数的超链接)后,环境信息应该通过ajax填充导航菜单旁边的div,调用另一个php脚本(GetEnvironment.php)。此脚本与之前的脚本具有相同的数据库和代码,具有不同的查询。
现在,任何理智的人都会说,“一定是查询。”当我打印出查询并在SSMS中运行它时,我得到了我想要的那一行。当我检查sqlsrv_has_rows()时,它返回true。当我运行sqlsrv_fetch_array()时,它返回一个空字符串。当我从查询中删除WHERE子句时,它返回环境数组就好了。 “那么它必须是查询中的where子句!”你是这么认为的,但是 - 就像我说的那样,打印出我的php正在使用的查询,并将此查询粘贴到SSMS中时,它会完美地返回。
如果我将where子句更改为“WHERE is_active = 1”或“WHERE e.env_type_id = 1”,我会得到结果。如果我将where子句更改为“WHERE e.id = 102”或“WHERE e.short_desc ='ABB'”,我会遇到同样的问题。重要的是要注意is_active有点,env_type_id是tinyint,而id是int,short_desc是varchar。
请记住,所有这些查询都在SSMS中进行了双重检查,因为它们会返回结果。我对id进行了硬编码,但没有区别,所以它不应该是$ _GET ['id']。
在我打电话的同时在数据库上运行跟踪时,没有记录任何错误,它似乎工作正常。在安装netbeans并尝试调试问题可能时,我仍然找不到根本原因。
Environment.php
<!DOCTYPE html>
<html>
<head>
<link href='../CSS/Primary.css' rel='stylesheet' type='text/css' />
<script>
function loadEnvInfo(id)
{
var xmlhttp;
<!-- The XMLHttpRequest object is used to exchange data with a server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page. -->
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState===4 && xmlhttp.status===200)
{
document.getElementById("envInfo").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("GET","GetEnvironment.php?id="+id,true);
xmlhttp.send();
}
</script>
</head>
<body>
<div id="pagewidth">
<div id="header">
<h2><a href="../index.php">Home</a>
<a href="Environment.php">Environments</a>
</div>
<div id="wrapper">
<div id="nav">
<?php
$serverName = "myServer\myInstance";
$connectionInfo = array( "Database"=>"myDatabase");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if ($conn === false)
{
echo "Connection could not be established.<br />";
die( print_r( sqlsrv_errors(), true));
}
$query = "SELECT e.id,e.long_desc,et.short_desc FROM myTable e INNER JOIN myOtherTable et ON e.env_type_id = et.id";
$returnedValue = sqlsrv_query($conn, $query);
if ($returnedValue === false)
{
die(print_r(sqlsrv_errors(),true));
}
if (sqlsrv_fetch_array($returnedValue) === false)
{
echo "fetch error";
}
$envTypes = array();
while ( $row = sqlsrv_fetch_array( $returnedValue, SQLSRV_FETCH_ASSOC) )
{
$env_type = $row['short_desc'];
if (array_key_exists($env_type, $envTypes) == false)
{
$envTypes[$env_type] = array($row['id']=>$row['long_desc']);
}
$envTypes[$env_type][$row['id']] = $row['long_desc'];
}
echo "<ul>";
foreach($envTypes as $et=>$et_value)
{
echo "<li>".$et;
if(count($et_value) > 0)
{
echo "<ul>";
foreach($et_value as $id=>$long_desc)
{
echo "<li><a href=\"javascript:loadEnvInfo(".$id.")\">".$long_desc."</a></li>";
}
echo "</ul>";
}
echo "</li>";
}
echo "</ul>";
/* Close the connection. */
sqlsrv_free_stmt( $returnedValue);
sqlsrv_close( $conn);
?>
</div>
<div id="maincol">
<div id="envName"><h1>Environment</h1></div>
<div id="envInfo"><h2>Environment Info</h2></div>
</div>
</div>
</div>
</body>
</html>
GetEnvironment.php
<?php
$serverName = "myServer\myInstance";
$connectionInfo = array( "Database"=>"myDatabase");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if ($conn === false)
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
$query = "SELECT e.[id]
,e.[short_desc]
,e.[long_desc]
,e.[is_active]
,et.[short_desc] as env_type
FROM [myTable] e
INNER JOIN [myOtherTable] et on e.[env_type_id] = et.[id]
WHERE e.[id] = ".$_GET['id'];
// Returns SELECT e.[id] ,e.[short_desc] ,e.[long_desc] ,e.[is_active]
// ,et.[short_desc] as env_type
// FROM [myTable] e
// INNER JOIN [myOtherTable] et on e.[env_type_id] = et.[id]
// WHERE e.[id] = 102
echo "Query: ".$query."<br />";
$returnedValue = sqlsrv_query($conn, $query);
// $returnedValue returns "Resource id #3"
if ($returnedValue === false)
{
echo "Error in query preparation/execution.<br />";
die(print_r(sqlsrv_errors(),true));
}
if (sqlsrv_fetch_array($returnedValue) === false)
{
echo "fetch error";
die(print_r(sqlsrv_errors(),true));
}
// Returns "Has Rows!"
if (sqlsrv_has_rows($returnedValue))
{
echo "Has Rows!";
}
else
{
echo "No Rows!";
}
// Returns "empty string"
if (sqlsrv_fetch_array($returnedValue) == "")
{
echo "empty string";
}
else if (sqlsrv_fetch_array($returnedValue) == null)
{
echo "null";
}
// Does not enter the while loop, skips over it to close the connection
while ( $row = sqlsrv_fetch_array( $returnedValue, SQLSRV_FETCH_ASSOC ))
{
echo "Inside While loop!";
}
/* Close the connection. */
sqlsrv_free_stmt( $returnedValue);
sqlsrv_close( $conn);
?>
答案 0 :(得分:1)
通常情况下,最好改变查询方式,使其更加“安全”。
$query = sprintf(
"SELECT e.[id]
,e.[short_desc]
,e.[long_desc]
,e.[is_active]
,et.[short_desc] as env_type
FROM [myTable] e
INNER JOIN [myOtherTable] et on e.[env_type_id] = et.[id]
WHERE e.[id] = '%s'",
addslashes($_GET['id']));
这样可以防止对数据库造成任何类型的攻击,并在您的ID周围添加单个刻度可能会解决您遇到的问题。
答案 1 :(得分:1)
删除if语句(检查我的returnedValue是否有任何值)后,脚本开始工作。这是工作的PHP。我将继续研究这个问题,看看我是否能找到这个脚本的工作原理,而我的原始脚本却没有。对此问题的任何其他见解将非常感激。
我建议的答案:通过在if语句中调用sqlsrv_fetch_array($ returnedValue),我从返回的值中删除了数组。我已经拿出了信息,并试图再次调用相同的引用,它返回给我一个空字符串,因为它不再包含该数组。
使用php:
<?php
$serverName = "myServer\myInstance";
$connectionInfo = array( "Database"=>"myDatabase");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if ($conn === false)
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
$query = "SELECT e.[id]
,e.[short_desc]
,e.[long_desc]
,e.[is_active]
,et.[short_desc] as env_type
FROM [myTabel] e
INNER JOIN [myOtherTable] et on e.[env_type_id] = et.[id]
WHERE e.[id] = ".$_GET['id'];
$returnedValue = sqlsrv_query($conn, $query);
if( $returnedValue === false)
{
echo "Error in query preparation/execution.\n";
die( print_r( sqlsrv_errors(), true));
}
while ( $row = sqlsrv_fetch_array( $returnedValue, SQLSRV_FETCH_ASSOC ))
{
echo "Inside loop!";
}
/* Free statement and connection resources. */
sqlsrv_free_stmt($returnedValue);
sqlsrv_close( $conn);
?>
答案 2 :(得分:0)
正如提问者的回答所述,脚本在if语句中使用:
获取一个数组 if (sqlsrv_fetch_array($returnedValue) === false)
如果您想检查sqlsrv_fetch_array()
的结果并成功获取所有结果,那么我的建议如下:
$row = sqlsrv_fetch_array( $returnedValue, SQLSRV_FETCH_ASSOC );
if( $row === false ) {
echo "Error while fetching array.\n";
die( print_r( sqlsrv_errors(), true));
} else if( $row === null ) {
echo "No results were found.\n";
} else {
do {
echo "Inside loop!";
} while( $row = sqlsrv_fetch_array( $returnedValue, SQLSRV_FETCH_ASSOC ) );
}
sqlsrv_free_stmt( $returnedValue);
sqlsrv_close( $conn);
使用这种方法,您可以在至少在开始时获取数组时检查错误并控制空结果。