在使用ajax实时搜索实现PHP和MySQL的最后阶段,我需要一些建议。
我让实时搜索工作得很完美,它会按照我想要的方式显示结果。我甚至通过URL传递搜索值并在页面加载时搜索来实现它。
我遇到的问题是,当它打印结果时,它不打印列的名称,只显示例如值:
<table data-role="table" id="customer" data-mode="reflow" class="border_radius">
<thead>
<tr class="">
<td>ID</td>
<td>Name</td>
<td>Address</td>
<td>Post Code</td>
<td></td>
</tr>
</thead>
<tbody>
<td id="" class="151">151</td>
<td id="" class="Brain">Brain</td>
<td id="" class="Apartado 81">Apartado 81</td>
<td id="" class="2584">2584</td>
<td>
<a href="cart/?tele=" class="btn btn-success btn-lg text-center" id="order_link" '="">Order</a></td></tbody>
</table>
这个问题是我想将值发布到下一页的网址,但不知道如何实现这一点。我试图发布列名,但它会为每个id发布所有列名,如下所示:
<table data-role="table" id="customer" data-mode="reflow" class="border_radius">
<thead>
<tr class="">
<td>ID</td>
<td>Name</td>
<td>Address</td>
<td>Post Code</td>
<td></td>
</tr>
</thead>
<tbody>
<td id="AUTO_ID, NAME, ADDRESS, ZIP_CODE" class="151">151</td>
<td id="AUTO_ID, NAME, ADDRESS, ZIP_CODE" class="Brain">Brain</td>
<td id="AUTO_ID, NAME, ADDRESS, ZIP_CODE" class="Apartado 81">Apartado 81</td>
<td id="AUTO_ID, NAME, ADDRESS, ZIP_CODE" class="2584">2584</td>
<td>
<a href="cart/?tele=" class="btn btn-success btn-lg text-center" id="download_link" '="">Order</a></td></tbody>
</table>
我的PHP代码如下所示:
namespace AjaxLiveSearch\core;
file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'DB.php') ? require_once(__DIR__ . DIRECTORY_SEPARATOR . 'DB.php') : die('There is no such a file: DB.php');
file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'Config.php') ? require_once(__DIR__ . DIRECTORY_SEPARATOR . 'Config.php') : die('There is no such a file: Config.php');
if (count(get_included_files()) === 1) {
exit("Direct access not permitted.");
}
if (session_id() == '') {
session_start();
}
/**
* Class Handler
*/
class Handler
{
/**
* returns a 32 bits token and resets the old token if exists
*
* @return string
*/
public static function getToken()
{
// create a form token to protect against CSRF
$token = bin2hex(openssl_random_pseudo_bytes(32));
return $_SESSION['ls_session']['token'] = $token;
}
/**
* receives a posted variable and checks it against the same one in the session
*
* @param $session_parameter
* @param $session_value
*
* @return bool
*/
public static function verifySessionValue($session_parameter, $session_value)
{
$white_list = array('token', 'anti_bot');
if (in_array($session_parameter, $white_list) &&
$_SESSION['ls_session'][$session_parameter] === $session_value
) {
return true;
} else {
return false;
}
}
/**
* checks required fields, max length for search input and numbers for pagination
*
* @param $input_array
*
* @return array
*/
public static function validateInput($input_array)
{
$error = array();
foreach ($input_array as $k => $v) {
if (!isset($v) || (trim($v) == "" && $v != "0") || $v == null) {
array_push($error, $k);
} elseif ($k === 'ls_current_page' || $k === 'ls_items_per_page') {
if ((int)$v < 0) {
array_push($error, $k);
}
} elseif ($k === 'ls_query' && strlen($v) > Config::getConfig('maxInputLength')) {
array_push($error, $k);
}
}
return $error;
}
/**
* forms the response object including
* status (success or failed)
* message
* result (html result)
*
* @param $status
* @param $message
* @param string $result
*/
public static function formResponse($status, $message, $result = '')
{
$css_class = ($status === 'failed') ? 'error' : 'success';
$message = "<tr><td class='{$css_class}'>{$message}</td></tr>";
echo json_encode(array('status' => $status, 'message' => $message, 'result' => $result));
}
/**
* @param $query
* @param int $current_page
* @param int $items_per_page
*
* @return array
*/
public static function getResult($query, $current_page = 1, $items_per_page = 0)
{
// get connection
$db = DB::getConnection();
$dbInfo = Config::getConfig('db');
$sql = "SELECT COUNT(AUTO_ID) FROM {$dbInfo['table']}";
// append where clause if search column is set in the config
$whereClause = '';
if (!empty($dbInfo['searchColumn'])) {
$whereClause .= " WHERE {$dbInfo['searchColumn']} LIKE :query";
$sql .= $whereClause;
}
// get the number of total result
$stmt = $db->prepare($sql);
if (!empty($whereClause)) {
$search_query = $query . '%';
$stmt->bindParam(':query', $search_query, \PDO::PARAM_STR);
}
$stmt->execute();
$number_of_result = (int)$stmt->fetch(\PDO::FETCH_COLUMN);
// initialize variables
$HTML = '';
$number_of_pages = 1;
if (!empty($number_of_result) && $number_of_result !== 0) {
if (!empty($dbInfo['filterResult'])) {
$fromColumn = implode(',', $dbInfo['filterResult']);
} else {
$fromColumn = '*';
}
$baseSQL = "SELECT {$fromColumn} FROM {$dbInfo['table']}";
if (!empty($whereClause)) {
$baseSQL .= "{$whereClause} ORDER BY {$dbInfo['searchColumn']}";
}
if ($items_per_page === 0) {
// show all
$stmt = $db->prepare($baseSQL);
if (!empty($whereClause)) {
$stmt->bindParam(':query', $search_query, \PDO::PARAM_STR);
}
} else {
/*
* pagination
*
* calculate total pages
*/
if ($number_of_result < $items_per_page) {
$number_of_pages = 1;
} elseif ($number_of_result > $items_per_page) {
$number_of_pages = floor($number_of_result / $items_per_page) + 1;
} else {
$number_of_pages = $number_of_result / $items_per_page;
}
/*
* pagination
*
* calculate start
*/
$start = ($current_page > 0) ? ($current_page - 1) * $items_per_page : 0;
$stmt = $db->prepare(
"{$baseSQL} LIMIT {$start}, {$items_per_page}"
);
if (!empty($whereClause)) {
$stmt->bindParam(':query', $search_query, \PDO::PARAM_STR);
}
}
// run the query and get the result
$stmt->execute();
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
// generate HTML
foreach ($results as $result) {
foreach ($result as $column) {
foreach ($dbInfo['filterResult'] as $colid) { //Trying to get the ID of each column
$HTML .= "<td id='{$colid}' class='{$column}'>{$column}</td>"; // Table column names just paste as one i.e AUTO_ID, NAME, ADDRESS, ZIP_CODE
}
}
$tele = $_GET['tele'];
{
$HTML .= "<td><a href='cart/?tele={$tele}' class='btn btn-success btn-lg text-center' id='download_link''>Order</a></td>";
$HTML .= '</tr>';
}
}
} else {
// To prevent XSS prevention convert user input to HTML entities
$query = htmlentities($query, ENT_NOQUOTES, 'UTF-8');
// there is no result - return an appropriate message.
$HTML .= "<tr><td colspan='5'>There are no customer with telephone number\"{$query}\" <a href='#customerimport' class='btn btn-success btn-lg text-center' id='download_link'>ADD</a></td></tr>";
}
// form the return
return array(
'html' => $HTML,
'number_of_results' => (int)$number_of_result,
'total_pages' => $number_of_pages
);
}
/**
* @return string
*/
public static function getJavascriptAntiBot()
{
return $_SESSION['ls_session']['anti_bot'] = Config::getConfig('antiBot');
}
/**
* Calculate the timestamp difference between the time page is loaded
* and the time searching is started for the first time in seconds
*
* @param $page_loaded_at
*
* @return bool
*/
public static function verifyBotSearched($page_loaded_at)
{
// if searching starts less than start time offset it seems it's a Bot
return (time() - $page_loaded_at < Config::getConfig('searchStartTimeOffset')) ? false : true;
}
}
我的Config.php看起来像这样
namespace AjaxLiveSearch\core;
if (count(get_included_files()) === 1) {
exit("Direct access not permitted.");
}
/**
* Class Config
*/
class Config
{
/**
* @var array
*/
private static $configs = array(
// ***** Database ***** //
'db' => array(
'host' => 'localhost',
'database' => 'user',
'username' => 'name',
'pass' => '*******',
'table' => 'table',
// specify the name of search column
'searchColumn' => 'TELEPHONE_NO',
// filter the result by entering table column names
// to get all the columns, remove filterResult or make it an empty array
'filterResult' => array(
'AUTO_ID, NAME, ADDRESS, ZIP_CODE'
)
),
// ***** Form ***** //
// This must be the same as form_anti_bot in script.min.js or script.js
'antiBot' => "Ehsan's guard",
// Assigning more than 3 seconds is not recommended
'searchStartTimeOffset' => 0,
// ***** Search Input ***** /
'maxInputLength' => 20
);
/**
* @param $key
*
* @return mixed
* @throws \Exception
*/
public static function getConfig($key)
{
if (!array_key_exists($key, static::$configs)) {
throw new \Exception("Key: {$key} does not exist in the configs");
}
return static::$configs[$key];
}
}
我的HTML看起来像这样
<form accept-charset="UTF-8" class="search" method="post" action="../cart/index.php" id="ls_form" name="ls_form">
<?php // Set javascript anti bot value in the session Handler::getJavascriptAntiBot(); ?>
<input type="hidden" name="ls_anti_bot" id="ls_anti_bot" value="">
<input type="hidden" name="ls_token" id="ls_token" value="<?php echo Handler::getToken(); ?>">
<input type="hidden" name="ls_page_loaded_at" id="ls_page_loaded_at" value="<?php echo time(); ?>">
<input type="hidden" name="ls_current_page" id="ls_current_page" value="1">
<input type="text" name="ls_query" id="ls_query" placeholder="Type to start search (e.g., 02071234567)" autocomplete="off" value='<?php echo $tele; ?>' maxlength="<?php echo Config::getConfig('maxInputLength'); ?>">
<!-- Result -->
<div id="ls_result_div">
<div id="ls_result_main">
<script type="text/javascript">
$(document).ready(function() {
$.post({
url: "/include/banner-home.php?tele=1234",
type: "POST",
data: {
tableId: customer
},
success: function(data) {}
})
});
</script>
<table data-role="table" id="customer" data-mode="reflow">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Address</td>
<td>Post Code</td>
<td></td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<!-- Pagination -->
<div id="ls_result_footer">
<div class="col page_limit">
<select id="ls_items_per_page" name="ls_items_per_page">
<option value="5" selected>5</option>
<option value="10">10</option>
<option value="0">All</option>
</select>
</div>
<div class="col navigation"> <i class="icon-left-circle arrow" id="ls_previous_page"></i>
</div>
<div class="col navigation pagination">
<label id="ls_current_page_lbl">1</label>/
<label id="ls_last_page_lbl"></label>
</div>
<div class="col navigation"> <i class="icon-right-circle arrow" id="ls_next_page"></i>
</div>
</div>
</div>
</form>
如果有人可以告诉我哪里出错了,或者指出我正确的方向并且不止感激。
由于