我将 JQuery Datatables 与 PHP 服务器端脚本一起使用,该脚本从 MySQL 中获取数据。我从 Datatables 站点获取了 PHP 脚本示例,并对其进行了一些更改,以便将其从旧 mysql 更改为 mysqli。该脚本接受多个参数,例如分页、排序和过滤。前两个不必担心,因为它们始终是数字,并且可以在将其传递给 MySQL 请求之前使用 intval 函数进行初始化。但是过滤应该有文本值,我想使用 mysqli 准备好的语句来清理它。这是代码:
require_once "mysqli_conection.php"
$aColumns = array( 'engine', 'browser', 'platform', 'version', 'grade' );
/*
* Paging
*/
$sLimit = "";
if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
{
$sLimit = "LIMIT ".intval( $_GET['iDisplayStart'] ).", ".
intval( $_GET['iDisplayLength'] );
}
/*
* Ordering
*/
$sOrder = "";
if ( isset( $_GET['iSortCol_0'] ) )
{
$sOrder = "ORDER BY ";
for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
{
if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
{
$sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
".($_GET['sSortDir_'.$i]==='asc' ? 'asc' : 'desc') .", ";
}
}
$sOrder = substr_replace( $sOrder, "", -2 );
if ( $sOrder == "ORDER BY" )
{
$sOrder = "";
}
}
/*
* Filtering
*/
$sWhere = "";
if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" )
{
$sWhere = "WHERE (";
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" )
{
$sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string( $_GET['sSearch'] )."%' OR ";
}
}
$sWhere = substr_replace( $sWhere, "", -3 );
$sWhere .= ')';
}
/*
* SQL queries
*/
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
FROM $sTable
$sWhere
$sOrder
$sLimit
";
$rResult = $mysqli->query( $sQuery, $gaSql['link'] );
/* Data set length after filtering */
$sQuery = "
SELECT FOUND_ROWS()
";
$rResultFilterTotal = $mysqli->query( $sQuery, $gaSql['link'] );
$aResultFilterTotal = $rResultFilterTotal->fetch_array(MYSQLI_NUM);
$iFilteredTotal = $aResultFilterTotal[0];
/* Total data set length */
$sQuery = "
SELECT COUNT(".$sIndexColumn.")
FROM $sTable
";
$rResultTotal = $mysqli->query( $sQuery, $gaSql['link'] );
$aResultTotal = $rResultTotal->fetch_array(MYSQLI_NUM);
$iTotal = $aResultTotal[0];
/*
* Output
*/
$output = array(
"sEcho" => intval($_GET['sEcho']),
"iTotalRecords" => $iTotal,
"iTotalDisplayRecords" => $iFilteredTotal,
"aaData" => array()
);
while ( $aRow = $rResult->fetch_array(MYSQLI_NUM) )
{
$row = array();
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
if ( $aColumns[$i] != ' ' )
{
$row[] = $aRow[ $aColumns[$i] ];
}
}
$output['aaData'][] = $row;
}
echo json_encode( $output );
问题是过滤是可选参数,我不知道如何做准备好的声明。如果该请求始终存在,我会这样做:
$stmt = $mysqli->prepare( $dataQuery );
$stmt->bind_param("sssss", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%")
$stmt->execute();
$rResult = $stmt->get_result();
我会把它放在 /* Output */ 部分之前。我是否应该根据 sSearch 请求集在准备好的或通常的语句之间切换,例如:
if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" ) {
$stmt = $mysqli->prepare( $dataQuery );
$stmt->bind_param("%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%", "%".$_GET['sSearch']."%")
$stmt->execute();
$rResult = $stmt->get_result();
} else {
$rResult = $mysqli->query($dataQuery);
}
/*
* Output
*/
//etc.
那会安全吗?