数据表服务器端处理阿拉伯语搜索无法正常工作

时间:2017-08-31 20:58:53

标签: php ajax codeigniter datatables

我正在使用Codeigniter和Data table server-side processing从数据库中获取数据

我的控制器功能

{
  "speech": "OCAS means Online Credit Approval System. Check your phone for more information.",
  "displayText": "OCAS means Online Credit Approval System. Click here for more information: http://www.erainfotechbd.com/product/ocas-online-credit-approval-system/",
  "data": {
    "facebook": {
      "attachment": {
        "type": "template",
        "payload": {
          "template_type": "button",
          "text": "OCAS means Online Credit Approval System",
          "buttons": [
            {
              "type": "web_url",
              "url": "http://www.erainfotechbd.com/product/ocas-online-credit-approval-system/",
              "title": "Click here for more information"
            }
          ]
        }
      }
    }
  }
}

我的模型功能

public function all_list()
{
    $this->load->model('courses_model');
    $list = $this->courses_model->get_all_datatables();
    $data = array();
    $no = $_POST['start'];
    foreach ($list as $courses) {
        $no++;
        $row = array();
        $row[] = $no;
        $row[] = '<img alt="course"  src="'.base_url('assets/template_files/images/courses/thumb/'.$courses->GeneralPhoto). '" width="150" height="100">';
        $row[] = $courses->CourseName;
        $row[] = $courses->TeacherName;
        $row[] =  date('Y-m-d',strtotime($courses->CourseStartDate));
        $row[] =  date('Y-m-d',strtotime($courses->CourseEndDate));
        $row[] = $courses->PeriodWeekly;
        $row[] = $courses->CategoryName;
        $row [] ="<a href='$courses->CourseID' ><button type='button' class='btn btn-xs btn-primary'>عرض الدورة</button></a>";

        $data[] = $row;
    }

    $output = array(
                    "draw" => $_POST['draw'],
                    "recordsTotal" => $this->courses_model->count_all(),
                    "recordsFiltered" => $this->courses_model->count_filtered(),
                    "data" => $data,
            );
    //output to json format
    echo json_encode($output);
}

我的剧本

//All
var $table = '(
   SELECT
        courses.*
        ,(SELECT CourseCategoryName FROM coursecategories WHERE coursecategories.CourseCategoryID=courses.CourseCategoryID) AS CategoryName
        ,(SELECT GROUP_CONCAT(gu.Name) AS TeacherName
        FROM (SELECT ct.CourseID AS CourseID, GROUP_CONCAT(t.StaffID) AS StaffID
        FROM courseteachers AS ct
        INNER JOIN staff AS t ON ct.StaffTeacherID = t.StaffID
        GROUP BY CourseID) as res
        INNER JOIN generaluser AS gu ON gu.GeneralUserID = res.StaffID
        WHERE CourseID=courses.CourseID) AS TeacherName
        FROM  courses
) temp';
var $column_search = array('CourseID','GeneralPhoto','CourseName','TeacherName','CourseStartDate','CourseEndDate','PeriodWeekly','CategoryName'); //set column field database for datatable searchable
var $order = array('CourseID' => 'desc'); // default order
private function _get_datatables_query($term='')
{
    //the query
    $this->db->from($this->table);
    $i = 0;

    foreach ($this->column_search as $item) // loop column
    {
        if($term) // if datatable send POST for search
        {

            if($i===0) // first loop
            {
                 // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
                $this->db->like($item,$term);
            }
            else
            {
                $this->db->or_like($item, $term);
            }
        }
        $i++;
    }

    if(isset($this->order))
    {
        $order = $this->order;
        $this->db->order_by(key($order), $order[key($order)]);
    }
}

function get_all_datatables()
{
    $term = $_POST['search']['value'];
    $this->_get_datatables_query($term);
    if($_POST['length'] != -1)
    $this->db->limit($_POST['length'], $_POST['start']);
    $query = $this->db->get();
    return $query->result();

}

function count_filtered()
{
    $term = $_POST['search']['value'];
    $this->_get_datatables_query($term);
    $query = $this->db->get();
    return $query->num_rows();
}

public function count_all()
{
    $this->db->from($this->table);
    return $this->db->count_all_results();
}

它工作正常,我得到了结果 enter image description here

表的所有功能都完美地工作(分页,服务器处理....),甚至搜索与英语单词完美配合但不是阿拉伯语,当我输入单词的第一个字母时出现错误信息

enter image description here

我尝试了很多选项,例如添加

<script>
    $(function () {
        $("#allData").DataTable({

            "processing": true, //Feature control the processing indicator.
            "serverSide": true, //Feature control DataTables' server-side processing mode.
            "order": [], //Initial no order.

            // Load data for the table's content from an Ajax source
            "ajax": {
                "url": "<?php echo site_url('Course/all_list')?>",
                "type": "POST",
            },

            //Set column definition initialisation properties.
            "columnDefs": [
            {
                "targets": [ 0 ], //first column / numbering column
                "orderable": false, //set not orderable
            },

            ],
            "language":
            {
                "sProcessing": "جارٍ التحميل...",
                "sLengthMenu": "أظهر _MENU_ مدخلات",
                "sZeroRecords": "لم يعثر على أية سجلات",
                "sInfo": "إظهار _START_ إلى _END_ من أصل _TOTAL_ مدخل",
                "sInfoEmpty": "يعرض 0 إلى 0 من أصل 0 سجل",
                "sInfoFiltered": "(منتقاة من مجموع _MAX_ مُدخل)",
                "sInfoPostFix": "",
                "sSearch": "ابحث:",
                "sUrl": "",
                "oPaginate": {
                    "sFirst": "الأول",
                    "sPrevious": "السابق",
                    "sNext": "التالي",
                    "sLast": "الأخير"
                }
            },
            });
    });
</script>

 header( 'Content-Type: application/json; charset=utf-8' );  

在控制器中,但它不起作用我该怎么办?

控制台输出

echo json_encode($output,JSON_UNESCAPED_UNICODE);

网络标签 enter image description hereenter image description here

标题中的搜索值为阿拉伯语

enter image description here

4 个答案:

答案 0 :(得分:1)

对我来说,这听起来很像你没有为数据库连接设置正确的utf8字符集:

<强> https://www.codeigniter.com/user_guide/database/connecting.html

$config['char_set'] = 'utf8';
$config['dbcollat'] = 'utf8_general_ci';
$this->load->database($config);

足够阿拉伯语。如果你需要JSON_UNESCAPED_UNICODE,那就错了。

检查coursescourseteacherscoursecategories以及您正在使用的其他表格所设置的字符集和排序规则。如果他们没有utf8utf8_general_ci,您可以更新:

alter table courses convert to character set utf8 collate utf8_general_ci;

但请先备份表格!

我没有使用codeigniter的实际经验,但是您的错误似乎非常熟悉,当json_encode从PHP后端到dataTables的语言特定字母时,很容易重现确切的行为,其中连接charset与utf8不同,或者数据库或表没有正确的charset和collat​​ion设置。

答案 1 :(得分:1)

我从here得到了解决方案,这是因为表中的日期字段所以我遇到了问题

Illegal mix of collations for operation 'like' while searching

更改行

var $column_search = array('CourseID','GeneralPhoto','CourseName','TeacherName','CourseStartDate','CourseEndDate','PeriodWeekly','CategoryName'); 

 var $column_search = array('CourseName','TeacherName','CategoryName');

解决了这个问题。

答案 2 :(得分:0)

如果你期待$ _POST数据,你可能需要在设置UTF-8时使用:

headers: {
  'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}

而不是application/jsonThis is all per this answer

答案 3 :(得分:0)

您收到JavaScript错误,因为响应无效(错误)。看起来$_POST['search']未定义会导致问题,这意味着search变量未被发布到服务器,或者服务器将其过滤掉,这可能是由答案中描述的内容引起的this question

另外,请确保您使用$this->input->post('search')代替$_POST['search']

最后,要消除所有可能性,请考虑在数据表初始化的contentType条目中添加ajax,如果您使用的是jQuery&gt; = 1.5或beforeSend,如果您是使用旧版本,如下所示:

 $("#allData").DataTable({
...
            // Load data for the table's content from an Ajax source
            "ajax": {
                "url": "<?php echo site_url('Course/all_list')?>",
                "type": "POST",
                "contentType": 'application/x-www-form-urlencoded; charset=UTF-8',
            },
...