Stiflerus
@Stiflerus
Саморазвитие мое все.

Как правильно сделать лимит уровней вложенности древовидных комментариев на php + mysqli?

Хочу сделать свои комментарии чистом php + mysqli, чтобы поучиться и более вникнуть в тему php. Буду очень благодарен за помощь.
Суть проблемы возникла уже на последнем этапе: "ограничения уровня вложенности комментариев".
Выложу весь код сайта возможно поможете найти решение, а то уж очень много времени потратить на поиски этой задачи.
www.dropbox.com/s/uow5elv0ys5g8s4/comments.zip

Сделал струкуту сайту:
-css
-js
-images
-libs
-views
-config.php
-index.php
-model.php

Так выглядит index.php
<?
include('config.php');
include('model.php');

/* =============================
	Распечатка массива
================================ */
function print_arr($arr){echo "<pre>"; print_r($arr); echo "</pre>";}

/* =============================
	Функция очистки данных
================================ */
function cleardata($data){
	$mysqli = connect_db(); 
	$res =  $mysqli->real_escape_string(htmlspecialchars(strip_tags(trim($data)), ENT_QUOTES, 'UTF-8'));
	return $res;
}

/* =============================
	Функция для формирования иерархического дерева
================================ */
function build_tree($data){
    $tree = array();
    foreach($data as $id => &$row){
        if(empty($row['parent_id'])){
            $tree[$id] = &$row;
        }
        else{
            $data[$row['parent_id']]['reply'][$id] = &$row;
        }
    }
    return $tree;
}

function getCommentsTemplate($comments){
    $html = '';
    foreach($comments as $comment){
        ob_start(); 
        include 'views/comments_template.php';          
        $html .= ob_get_clean();
    }
    return $html;
}

$comments = get_all_comments(); //Выводим все комментарии
$comments = getCommentsTemplate($comments); //Формируем дерево с массива простого результата всех комментариев
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    
    <div class="container">
        <div class="wrapper-comments">
            <ul class="media-list">
				<li><?=$comments?></li>         
				<li class="row">
				   
				   <?php if(isset($_SESSION['answer']['res'])){
						echo $_SESSION['answer']['res'];
						unset($_SESSION['answer']);
					}?>
				   
					<form id="form" class="col-xs-4" method="post" action="index.php">
					   <input type="hidden" name="parent_id" id="parent_id" value="0">
						<div class="form-group">
							<label for="author">Ім'я:</label>
							<input name="author" type="text" class="form-control" id="author">
						</div>
						
						<div class="form-group">
							<label for="comment">Ваш коментар:</label>
							<textarea name="comment" class="form-control" rows="3"></textarea>
						</div>
						
						<button type="submit" class="btn btn-info">Відправити</button>
					</form>
				</li>
            </ul> <!-- .media-list -->
        </div> <!-- .wrapper-comments -->
    </div> <!-- .container -->
    

<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>


Так выглядит config.php
<?
//Доступ до бази данних
define("HOST", "localhost");
define("USER", "root");
define("PASS", "");
define("DB", "lessons_comments");

error_reporting(E_ALL); //E_ERROR | E_WARNING | E_PARSE
?>


Так выглядит model.php
<?
/* =============================
Підключення до бази данних
================================ */
function connect_db(){
	$mysqli = new mysqli(HOST,USER,PASS,DB);
	
	if($mysqli->connect_error)
		die("Виникла помилка з базою данних!"); //Більш точний опис помилки die("Виникла помилка з базою данних! ".$mysqli->connect_error);
	$mysqli->set_charset("utf8");
    
	return $mysqli;
}

function get_all_comments() {
    $mysqli = connect_db();

    $_comments = array();
    $sql = "SELECT * FROM comments WHERE post_id = 2";
    $res = $mysqli->query($sql) or die ($mysqli->error);
    if($res->num_rows){
      while($row = $res->fetch_assoc()){
         $_comments[$row['id']] = $row;
      }
    }
    
    $comments = build_tree($_comments);
    return $comments;
}

function add_comment(){
    $mysqli = connect_db();
    
    $parent_id = (int) $_POST['parent_id'];
	$author = cleardata($_POST['author']);
	$comment = cleardata($_POST['comment']);
    
    $res = $mysqli->prepare("INSERT INTO comments (parent_id, author, comment, post_id) VALUES (?, ?, ?, 2)" );
			$res->bind_param('iss', $parent_id, $author, $comment);
			$mysqli->error;
			$res->execute();
			if($res->affected_rows > 0){
                // если запись добавлена
                $_SESSION['answer']['res'] = 'Коментар успішно добавлено.';
              return true;
			}
			$res->close();
}


Последний важный файл view/comments_template.php
<div class="media">
    <div class="media-left">
      <a href="#">
        <img class="media-object" src="images/avatar.png" alt="...">
      </a>
    </div>
    <div class="media-body">
        <p class="h4 media-heading"><?=$comment['author']?> | <small><?=$comment['addtime']?></small></p>
        <p class="text-comment"><?=$comment['comment']?></p>
        <a href="#form" class="add-reply" data-id="<?=$comment['id']?>" data-name="<?=$comment['author']?>">Відповісти</a>
        
        <?
        if(!empty($comment['reply'])) echo getCommentsTemplate($comment['reply']);
        ?>
        
    </div>
</div>


Файл js/script.js
$("a.add-reply").click(function(){
    var id = $(this).attr('data-id'),
        name = $(this).attr('data-name'),
        add_id_to_form = $('#parent_id');
    add_id_to_form.attr('value', id);
});


Файл css/styles.css
.wrapper-comments {padding: 20px 0;}
.media-object {width: 64px; height: 64px;}
.text-comment {min-height: 25px;}


Картинку аватарки уже можна взять кокую угодно=)
И несколько последних скриншотов:
Структура бази данних:
7ea9e14244c14b78882cd63746358f24.png

Структура файлов:
0223355078c44eee92c9c8cec19f7940.png

Финальный вид:
ff33928ba4cc4bd7ba3b3349302b3fb1.png
  • Вопрос задан
  • 1002 просмотра
Решения вопроса 1
sergpenza
@sergpenza
Рекомендую посмотреть в сторону Nested Set
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
trevoga_su
@trevoga_su
ограничения уровня вложенности комментариев
это разве проблема и что за ограничение? в чем суть задачи?

$mysqli->real_escape_string(htmlspecialchars(strip_tags(trim($data)), ENT_QUOTES, 'UTF-8'));

убить мало за этот код. быстро читать - phpfaq.ru/slashes
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы