我正在使用带有PHP服务器端脚本的JQuery Datatables,它从MySQL获取数据。我从Datatables站点获取了PHP脚本示例并稍微更改了一下,以便将其从旧的mysql更改为mysqli。该脚本接受几个papameters,如分页,排序和过滤。没有关注前两个,因为它们总是数字,并且可以在将其传递给MySQL请求之前使用intval函数进行中文化。但Filtering应该具有文本值,我想使用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 );
问题是Filtering是可选参数,我无法弄清楚如何在那上做预备语句。如果该请求总是存在,我会这样做:
$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.
那会安全吗?