Я создаю сайт с архитектурой MVC и без фреймворка. Есть комментарии как в блоге. Я хотел бы иметь возможность ответить на комментарий. Но функция ответа не работает (когда я хочу ответить на комментарий, это то же самое, что и первый комментарий), и мне трудно понять, почему? Не могли бы вы помочь мне? Вот адрес сайта: cedricjager.com/stream
Вот connection.php:
class Connection {
// Connection
private function getBdd() {
try {
$bdd = ConfigDB::database();
$pdo = new PDO("mysql:host = {$bdd['host']}; dbname = {$bdd['db_name']}", "{$bdd['username']}", "{$bdd['password']}");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
return $pdo;
}
// Query
public function query($sql, $params = array(), $fetch = null) {
try {
$req = self::getBdd()->prepare($sql);
$req->execute($params);
if ($fetch == 'one') {
return $req->fetch();
} else if ($fetch == 'all') {
return $req->fetchAll();
} else {
return $req;
}
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
Вот модель:
<?php
require_once 'Connection.php';
class Critics extends Connection{
//Récupère les critiques selon l'id de l'article.
public function findAllById($post_id) {
$sql = "SELECT *, DATE_FORMAT(date, '%d/%m/%Y à %H:%i') AS date
FROM critics
WHERE id_movie = ?";
$params = [$post_id];
$comms = $this->query($sql,$params,'all');
$critics_by_id = [];
foreach ($comms as $comm) {
$critics_by_id[$comm['id']] = $comm;
}
return $critics_by_id;
}
//Récupèrer les critiques qui ont des enfants.
public function findAllWithChildren($post_id, $unset_children = true) {
$comms = $critics_by_id = $this->findAllById($post_id);
foreach ($comms as $id => $comm) {
if ($comm['parent_id'] != 0) {
$critics_by_id[$comm->parent_id]->children[] = $comm;
if ($unset_children) {
unset($comms[$id]);
}
}
}
return $comms;
}
//récupèrer une critique signalée.
public function findCritics() {
$sql = "SELECT *,DATE_FORMAT(date, '%d/%m/%Y à %H:%i') AS date FROM critics WHERE report=1";
$req = $this->query($sql);
return $req;
}
public function noCritic() {
if ($this->findCritics() == false) {
$msg = '<div class = "alert alert-warning">Il n\'y a pas de critiques signalées.</div>';
return $msg;
}
}
//insérer une critique.
public function insertCritic(){
if (isset($_POST['content']) && !empty($_POST['content'])){
$parent_id = isset($_POST['parent_id']) ? $_POST['parent_id'] : 0;
$depth = 0;
if ($parent_id != 0){
$sql = 'SELECT id, depth FROM critics WHERE id = ?';
$params = [$parent_id];
$comm = $this->query($sql,$params, 'one');
if ($comm == false) {
throw new Exception("Ce parent n'existe pas");
}
$depth = $comm->depth + 1;
}
if ($depth >= 3) {
echo "Impossible de rajouter une critique";
}
else {
$sql = 'INSERT INTO critics SET content = ?, author = ?, id_movie = ?, parent_id = ?, date = NOW(), depth = ?';
$params = array($_POST['content'], $_POST['nom'], $_GET['id'], $parent_id, $depth);
$req = $this->query($sql,$params);
}
}
}
}
}
Контроллер:
public function single() {
if (isset($_GET['id'])) {
$id = $_GET['id'];
$msg = $this->comment->reportCritic();
$this->comment->insertCritic();
$critics = $this->comment->findAllWithChildren($_GET['id']);
$view = require 'Views/single.php';
} else {
header('Location:index.php?p=404');
}
}
Взгляды
<div class = "sectioncomments" id = "comments">
<?php foreach($critics as $critic): ?>
<?php require('comments.php'); ?>
<?php endforeach; ?>
</div>
<hr>
<div class = "row">
<div class = "col-lg-12">
<div id = "form-comment" class = " panel panel-default formComment">
<div class = "panel panel-heading">
<h4>Poster une critique</h4>
<br>
<a href = "#"><span class = "return"></span></a>
</div>
<div class = "panel panel-body">
<form method = "post" class = "form-group form-horizontal">
<div class = "form-group">
<div class = "col-sm-9">
<input type = "text" class = "form-control" id = "nom" placeholder = "Votre nom..." name = "nom">
</div>
</div>
<div class = "form-group">
<div class = "col-sm-9">
<textarea class = "form-control" id = "content" placeholder = "Votre critique..." name = "content"></textarea>
</div>
</div>
<p class = "text-right"><button type = "submit" class = "btn btn-success">Publier</button></p>
<input type = "hidden" name = "parent_id" id = "parent_id" value = "0" >
</form>
</div>
</div>
</div>
</div>
</div>
Comments.php
<div id = "comment-<?= $critic['id'] ?>">
<p>
<b><?= $critic['author'] ?></b>
<span class = "text-muted">le <?= $critic['date'] ?></span>
</p>
<div class = "blockquote">
<blockquote>
<?= htmlentities($critic['content']) ?>
</blockquote>
</div>
<div class = "formulaire">
<form class = "form-group" method = "post">
<p class = "text-left">
<input type = "hidden" name = "valeur" value = "<?= $critic['id_movie'] ?>">
<input type = "hidden" name = "idval" value = "<?= $critic['id'] ?>">
<?php if ($critic['depth'] <= 1): ?>
<button type = "button" class = "reply btn btn-default" data-id = "<?= $critic['id'] ?>"><i class = "fas fa-comments"></i></button>
<?php endif; ?>
<button type = "submit" name = "signal" class = "btn btn-default"><i class = "fas fa-bolt"></i></span></button>
</p>
</form>
</div>
</div>
<div id = "answer">
<?php if (isset($critic['children'])): ?>
<?php foreach($critic['children'] as $critic): ?>
<?php require('comments.php'); ?>
<?php endforeach; ?>
<?php endif; ?>
</div>






Во-первых, я считаю, что вы никогда не устанавливали индекс children, упомянутый в вашем представлении comment.php:
<?php if (isset($critic['children'])): ?>
<?php foreach($critic['children'] as $critic): ?>
<?php require('comments.php'); ?>
<?php endforeach; ?>
<?php endif; ?>
Тогда вам не следует вызывать findAllById два раза подряд для служебных целей.
Если я там, где вы, возможно, я получу все один раз, а затем построю дерево на основе данных, которые вы получите из своего запроса. Это позволяет получить бесконечные возможности вложенных комментариев. Сделать это можно так:
$critics = $this->getAllById($id);//movie id
$childs = []; //Will contain all childs indexed by parent_id
$index = []; //will contain all root critics (no parent)
foreach($critics as &$v){
if ($v['parent_id'] === 0){ //if no parent, then add to $index
$indexes[$v['id']] = $v;
} else{ //else create an array in $childs at index parent_id
if (!isset($childs[$v['parent_id']])) $childs[$v['parent_id']] = [];
$childs[$v['parent_id']][] = $v;
}
}
//Then you can build your result :
foreach($childs as $id=>&$child){
$parent= $index[$id] ?? $child[$id] ?? null; // search for the parent of the current child
if (is_null($parent)) continue; // a parent doesn't exists anymore, we ignor it, but you can throw an exception instead
if (!isset($parent['children'])) $parent['children'] = [];
$parent['children'][] = $child;
}
return $index;
Теперь у критика должен быть указатель «дети», в котором перечислены все дети. Это позволяет вам строить дерево комментариев без ограничений. Все, что вам нужно иметь в виду, это правильно установить parent_id при публикации нового комментария.
Сообщите мне, если это решит вашу проблему.