Как улучшить мой код php sub_array, используя INNER JOIN для отображения данных в DataTables?
Я использую этот учебник CRUD https://www.webslesson.info/2017/01/php-pdo-ajax-crud-with-data-tables-and-bootstrap-modals.html чтобы сделать некоторые тесты, и я хотел бы чтобы улучшить его, включая 2 столбца, связанных с другими таблицами на MySql.
Я работаю с этими учебными файлами ниже:
- Один php-файл, извлекающий данные для отображения в DataTables (fetch.php);
- Один файл index.php;
- Одна таблица, которая называется "Пользователи" и имеет 4 столбца:
Users table
-------------------------------------
id | first_name | last_name | image
Я создал 2 таблицы для связи с таблицей "Пользователи". Они:
- таблица "type_service" со столбцами ("typeID" и "type") и
- таблица категорий с колонками (" categoryID" и "категория ").
В таблицу "пользователи" я включил 2 столбца, которые вызывают "type_fk" и "category_fk", где "fk" - внешний ключ:
Users table
----------------------------------
id | first_name | last_name | image | type_fk | category_fk
Когда столбцы были созданы, они были связаны с таблицей "пользователи", где отношения работают идеально.
После этого я включил INNER JOIN запрос в файл fetch.php, как показано ниже:
$ query. = "ВЫБЕРИТЕ пользователей.*, type_service.type, Categories.category
ОТ пользователей
ВНУТРЕННЕЕ ПРИСОЕДИНЕНИЕ type_service ON users.type_fk = type_service.typeID
ВНУТРЕННЕЕ СОЕДИНЕНИЕ категорий НА users.category_fk = Categories.categoryID ";
Извлечь файл .php:
<?php
include('db.php');
include('function.php');
$query = '';
$output = array();
$query .= "SELECT users.*, type_service.type, categories.category
FROM users
INNER JOIN type_service ON users.type_fk = type_service.typeID
INNER JOIN categories ON users.category_fk = catgories.categoryID
";
if(isset($_POST["search"]["value"]))
{
$query .= 'WHERE first_name LIKE "%'.$_POST["search"]["value"].'%" ';
$query .= 'OR last_name LIKE "%'.$_POST["search"]["value"].'%" ';
}
if(isset($_POST["order"]))
{
$query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';
}
else
{
$query .= 'ORDER BY id DESC ';
}
if($_POST["length"] != -1)
{
$query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$data = array();
$filtered_rows = $statement->rowCount();
foreach($result as $row)
{
$image = '';
if($row["image"] != '')
{
$image = '<img src="upload/'.$row["image"].'" class="img-thumbnail" width="50" height="35" />';
}
else
{
$image = '';
}
$sub_array = array();
$sub_array[] = $image;
$sub_array[] = $row["first_name"];
$sub_array[] = $row["last_name"];
$sub_array[] = $row["type"];
$sub_array[] = $row["category"];
$sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
$sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
$data[] = $sub_array;
}
$output = array(
"draw" => intval($_POST["draw"]),
"recordsTotal" => $filtered_rows,
"recordsFiltered" => get_total_all_records(),
"data" => $data
);
echo json_encode($output);
?>
После включения запроса INNER JOIN в коде выше, я включил 2 sub_array в тот же файл (fetch.php), как показано ниже:
$ sub_array [] = $ row ["type"];
$ sub_array [] = $ row ["category"];
Где код остается таким:
$sub_array = array();
$sub_array[] = $image;
$sub_array[] = $row["type"];
$sub_array[] = $row["category"];
$sub_array[] = $row["first_name"];
$sub_array[] = $row["last_name"];
$sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
$sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
$data[] = $sub_array;
Когда приведенный выше код выполняется, на странице index.php отображаются данные через HTML-код ниже:
<body>
<div class="container box">
<h1 align="center">PHP PDO Ajax CRUD with Data Tables and Bootstrap Modals</h1>
<br />
<div class="table-responsive">
<br />
<div align="right">
<button type="button" id="add_button" data-toggle="modal" data-target="#userModal" class="btn btn-info btn-lg">Add</button>
</div>
<br /><br />
<table id="user_data" class="table table-bordered table-striped">
<thead>
<tr>
<th width="10%">Image</th>
<th width="10%">Type</th>
<th width="15%">Category</th>
<th width="15%">First Name</th>
<th width="15%">Last Name</th>
<th width="10%">Edit</th>
<th width="10%">Delete</th>
</tr>
</thead>
</table>
</div>
</div>
</body>
И когда я обновляю страницу index.php, DataTable возвращает недопустимый ответ JSON, как показано ниже:
В этом случае, если я удалю строку запроса:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ категорий НА users.category_fk = Categories.category
DataTable возвращает все данные, но показывает идентификатор столбца категории вместо имени категории. Изображение ниже может показать это:
Но если я включу:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ категорий НА users.category_fk = Categories.categoryID
В DataTables снова отображается ошибка:
Предупреждение DataTables: таблица id = user_data - Неверный ответ JSON. Для получения дополнительной информации об этой ошибке см. http://datatables.net/tn/1
Я вижу, что когда я включаю только один INNER JOIN-запрос, DataTable отображает все данные, но если я включаю еще один INNER JOIN, DataTable возвращает недопустимый JSON-ответ, даже включая соответствующие sub_arrays.
$ sub_array [] = $ row ["type"];
$ sub_array [] = $ row ["category"];
В этом случае, что я могу сделать, чтобы улучшить этот код, чтобы показать имя вместо идентификатора?
1 ответ
Если вы хотите иметь только 1 таблицу, вы можете объединить type_service и такие категории
type_service_categories
id | тип | название
где тип - сервис или категория, а имя - сервисный тип или название категории
... но это не решит вашу проблему, потому что вы все равно должны написать 2 внутренних оператора соединения в запросе.
Ваша ошибка возможна из $result = $ Statement->fetchAll();
Можете ли вы опубликовать db.php? или вы можете попробовать:
foreach($row as $rkey => $rvalue){
$sub_array[] = $row[$rkey];}
чтобы увидеть, какие поля возвращает ваш запрос при вызове функции fetchAll () или как они выбираются и возвращаются.
Или попробуйте вариант разработчика в Chrome, чтобы увидеть точно ошибку JSON.