Reddit Style Comments

Reddit Style Comments

To make a php based comment section like the one on Reddit, a structure for comments needs to be set up in both the database and the web page so the comment tree can be built quickly and displayed properly.

\r\n\r\n

For this site, a LAMP server is in use, and the M stands for mySQL so modify as you need based on your flavour of SQL.

\r\n\r\n

Database Setup

\r\n\r\n

For the database, 2 tables are required to run the comments. The comments table holds the actual comment, votes, post id, user id, creation and edit dates, and depth. The childrenComments table contains only the commentID, childID, and postID. The way this works is that if a child comment is added, its parent will be added to the childrenComments table, along with the id of the newly formed child comment. The depth will be recorded on the child as parent+1. The depth is not mandatory, but may be used to speed up searching when it gets too big. 

\r\n\r\n

PHP Setup

\r\n\r\n

Inside the function to get the comments, the db query for the comments needs the depth of the comment as the depth is used to determine which comment is a post comment, and which are replies. Post comments have no parent, and are put directly under the post. Their children are then needed below, and this is a recursive call.

\r\n\r\n

the getChildren function takes the comment passed in, and runs a query to find children comments by joining the comments table and the childrenComments table together. If there is a childrenComments table entry, there is a child. This is then added to the output and a recursive call is done on each child comment.

\r\n\r\n

Code

\r\n\r\n
\r\n\r\nfunction getComments($id){\r\n	global $conn;\r\n	$sql = "SELECT comments.id\r\n	, comments.postID\r\n	, users.username\r\n	, COMMENT as comment\r\n	, vote\r\n	, date_created\r\n	, date_edited\r\n	, depth\r\n	FROM comments\r\n	\r\n	LEFT JOIN users ON comments.userID = users.id\r\n	WHERE postID = $id\r\nORDER BY depth, vote, date_created DESC";\r\n	$result = mysqli_query($conn, $sql);\r\n\r\n	// fetch query results as associative array.\r\n	$comments =mysqli_fetch_all($result, MYSQLI_ASSOC);\r\n	\r\n	$post_slug = $_GET['post-slug'];\r\n	$post = getPost($post_slug);\r\n	\r\n	$output = "";\r\n	\r\n	\r\n\r\n	foreach($comments as $comment){\r\n		if($comment['depth'] == 0){\r\n			$output .= "
\r\n $output.= commentToHTML($comment, $post) .getChildren($comment, $post, 1) ."\r\n\r\n $output.="\r\n\r\n } \r\n } \r\n //return $comments; \r\n return $output; \r\n} \r\n\r\nfunction getChildren($comment, $post, $depth){ \r\n global $conn; \r\n $commentID = $comment['id']; \r\n $sql = "SELECT comments.id , comments.postID , users.username , COMMENT as comment , vote , date_created , date_edited , depth FROM comments RIGHT JOIN (SELECT * FROM childrenComments WHERE commentID = $commentID) AS cc ON cc.childID = comments.id LEFT JOIN users ON comments.userID = users.id ORDER BY depth, vote ASC, date_created DESC "; \r\n $result = mysqli_query($conn, $sql); // fetch query results as associative array. \r\n $comments = mysqli_fetch_all($result, MYSQLI_ASSOC); \r\n $output = ""; \r\n if($comments){ \r\n foreach($comments as $subComment){ \r\n $output .= \"
"; \r\n $output.= commentToHTML($subComment, $post) .getChildren($subComment, $post, $depth + 1); \r\n $output.="} } return $output; } \r\n\r\n\r\n\r\n

Comments

Log in to add a comment.