DataTables 中的服务器端处理 UTF-8 搜索
Posted
技术标签:
【中文标题】DataTables 中的服务器端处理 UTF-8 搜索【英文标题】:Server-side processing UTF-8 search in DataTables 【发布时间】:2017-06-16 12:42:15 【问题描述】:我将 DataTables 与服务器端处理一起使用
$('#usersTable').DataTable(
responsive: true,
"pageLength": 20,
"processing": true,
"serverSide": true,
"bLengthChange": true,
"bSort" : false,
"bInfo" : false,
"aLengthMenu": [[20, 50, 75, -1], [20, 50, 75, "ყველა"]],
"ajax": "helpers/server_processing.php"
);
我还将ssp.class.php
中的数据库连接更改为
$db = @new PDO(
"mysql:host=$sql_details['host'];dbname=$sql_details['db']",
$sql_details['user'],
$sql_details['pass'],
array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'" )
);
尝试在搜索栏中搜索 UTF-8 字符时仍然遇到问题
有人可以帮忙吗?
查询(从评论中复制)
SELECT COUNT(`id`)
FROM `users`
WHERE (`id` LIKE :binding_0
OR `mac` LIKE :binding_1
OR `ip` LIKE :binding_2
OR `sname` LIKE :binding_3
OR `login` LIKE :binding_4
OR `tariff_plan_id` LIKE :binding_5
OR `now_playing_type` LIKE :binding_6
OR `now_playing_content` LIKE :binding_7
OR `now_playing_start` LIKE :binding_8
OR `keep_alive` LIKE :binding_9
OR `id` LIKE :binding_10
OR `status` LIKE :binding_11
)
SELECT COUNT(`id`)
FROM `users`
SELECT `id`, `mac`, `ip`, `sname`, `login`, `tariff_plan_id`,
`now_playing_type`, `now_playing_content`, `now_playing_start`,
`keep_alive`, `id`, `status`
FROM `users`
WHERE (`id` LIKE :binding_0
OR `mac` LIKE :binding_1
OR `ip` LIKE :binding_2
OR `sname` LIKE :binding_3
OR `login` LIKE :binding_4
OR `tariff_plan_id` LIKE :binding_5
OR `now_playing_type` LIKE :binding_6
OR `now_playing_content` LIKE :binding_7
OR `now_playing_start` LIKE :binding_8
OR `keep_alive` LIKE :binding_9
OR `id` LIKE :binding_10
OR `status` LIKE :binding_11
)
ORDER BY id ASC
LIMIT 0, 20
编辑:附加信息
我发现带有 utf-8 值的 LIKE 查询不适用于 mysql 中的 DateTime 字段
但 DataTables 会自动将每个字段与搜索字符串进行比较。如果字符串包含 utf-8 字符,是否有一种简单的方法可以告诉 DataTables 不要搜索 DateTime 类型的列?
【问题讨论】:
看下面的答案***.com/a/31065121/617373,可能会有帮助 正如您在第二个代码块中看到的,我已经在我的 pdo 连接中插入了“set names utf8” 只是一个疯狂的猜测:数据库/某些表的排序规则设置不好,例如不是utf8。检查这个问题:***.com/questions/1008287/… 所有表的排序规则都设置为 utf8_general_ci 您能否显示 a)show full columns from your-table
的输出和 b) 引发该错误的查询?
【参考方案1】:
使用new PDO('dblib:host=host;dbname=db;charset=UTF8', $user, $pwd);
而不是ATTR_INIT_COMMAND
。
->set_charset
用于mysqli
接口,而不是PDO
。
根据图片,列是CHARACTER SET utf8 COLLATION utf8_general_ci
,对于格鲁吉亚语来说已经足够了。
向我们展示带有 LIKE
的正在抱怨的查询。
问题与LIKE
语句有关。如果它在存储例程中,让我们看看SHOW CREATE ...
; 创建时,可能是错误的字符集/排序规则生效。
正如this 的“最佳实践”部分所述,“html 表单应该以“开头”。检查那里的其他项目。
【讨论】:
以下是我可以从 ssp 记录的查询:pastebin.com/2xtB1DrP “绑定”是如何执行的?也许这就是字符集/排序规则搞砸的地方? 它使用 $stmt->bindValue( $binding['key'], $binding['val'], $binding['type'] );带有绑定数组pastebin.com/fNbhYYN7【参考方案2】:试试这个:
$db_link = new PDO($dsn, $username, $password) // DB-connection
// CHARSET: utf8
$db_link->query('SET NAMES utf8');
【讨论】:
【参考方案3】:如果搜索字符串为 utf-8,我通过更改 ssp.class.php
的 filter
函数以从搜索中排除 DateTime 列来解决此问题
static function filter ( $request, $columns, &$bindings )
$globalSearch = array();
$columnSearch = array();
$dtColumns = self::pluck( $columns, 'dt' );
if ( isset($request['search']) && $request['search']['value'] != '' )
$str = $request['search']['value'];
for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ )
$requestColumn = $request['columns'][$i];
$columnIdx = array_search( $requestColumn['data'], $dtColumns );
$column = $columns[ $columnIdx ];
//**ADDED THIS**
if(mb_detect_encoding($request["search"]["value"])=="UTF-8")
if($column['db']=="keep_alive" || $column['db']=="now_playing_start")
continue;
if ( $requestColumn['searchable'] == 'true' )
$binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
$globalSearch[] = "`".$column['db']."` LIKE ".$binding;
// Individual column filtering
if ( isset( $request['columns'] ) )
for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ )
$requestColumn = $request['columns'][$i];
$columnIdx = array_search( $requestColumn['data'], $dtColumns );
$column = $columns[ $columnIdx ];
$str = $requestColumn['search']['value'];
if ( $requestColumn['searchable'] == 'true' &&
$str != '' )
$binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
$columnSearch[] = "`".$column['db']."` LIKE ".$binding;
// Combine the filters into a single string
$where = '';
if ( count( $globalSearch ) )
$where = '('.implode(' OR ', $globalSearch).')';
if ( count( $columnSearch ) )
$where = $where === '' ?
implode(' AND ', $columnSearch) :
$where .' AND '. implode(' AND ', $columnSearch);
if ( $where !== '' )
$where = 'WHERE '.$where;
return $where;
【讨论】:
以上是关于DataTables 中的服务器端处理 UTF-8 搜索的主要内容,如果未能解决你的问题,请参考以下文章
使用 Datatables v1.10.0 进行服务器端处理
DataTables jQuery插件服务器端处理,通过ajax删除后智能分页
在 DataTables 服务器端处理脚本中运行 MySQL 查询