I have a script I wrote I while back for comments, but it is only single threaded. I would like it to be multi-threaded, but only as so a user can reply to a comment, not so a user can reply to a comment of a comment. So the threads would only be two deep.
Currently I store a comment_id
against a user_id
in my database.
The only way I can think of to do the multi threaded comments, is to have a parent
field in the comments table. But if I do this then when I am selecting the comments with PHP, I will have to do another SELECT command to select the comments children (if any) for each comment. Seems like a lot of work on the database.
There has to be a better way. Any ideas on this? Or tutorials?
PHP applications, undoubtedly work effectively with multithreading capabilities. Multithreading is something similar to multitasking, but it enables to process multiple jobs at one time, rather than on multiple processes.
PHP does not give inbuilt multi-threading functionality, we need to add package/extension “threads” to our PHP. Threaded Objects: A class that is a unit of executable instructions (thread), It is what you want to execute asynchronously. the run method in this class has the ability to execute it as a thread.
PHP, like most server-side languages, uses multi-threaded, blocking I/O to carry out multiple tasks in parallel.
A application uses threading if it requires parallelism. In other words by a single program ,we can process multiple unit of instructions parallaly. PHP do not give inbuilt multi-threading functionality, we need to add package/extension “pthreads” to our php.
There are three (four) alternative possibilities:
A recursive query to select all comments based on their parent ids. This is supported by many database products and the syntax depends on the database type. Check the docs for more info (search for 'recursive').
If you store the article id in each (sub-)comment, you can just select all comments with the article id in one regular select query. You can use the parent ids to properly display the comments on the page under the right parent comment:
SELECT * FROM comments WHERE article_id = :article_id
If you only need two levels of comments, you can use an extended where to include both first level and second level comments:
SELECT * FROM comments
WHERE parent_id = :article_id
OR parent_id IN (SELECT id FROM comments WHERE parent_id = :article_id)
It is also possible to use union all to combine two queries that have the same columns, but since I assume that all data are from the same table, there is probably no need for it (see the extended where-clause above):
SELECT * FROM comments WHERE parent_id = :article_id
UNION ALL
SELECT * FROM comments WHERE parent_id IN
(SELECT id FROM comments WHERE parent_id = :article_id)
Personally, I would go for option 2 because it is simple (no exotic SQL construct required), efficient (1 query) and flexible (supports as many levels of comments as you like).
1 query is enough for this, you just need to loop the data and store it into an array correctly, then you loop the array and display the comments.
This is a common use for hierarchical, or tree-structure data. I wrote a popular answer to this Stack Overflow question: What is the most efficient/elegant way to parse a flat table into a tree?
I also wrote a presentation describing alternatives for tree-structured data: Models for Hierarchical Data with SQL and PHP.
Another solution that is not included in my presentation is the way Slashdot does threaded comments. They use a parent
column like you do, so each comment references the comment it replies to. But then they also include a root
column so each comment knows the post it belongs to. There are seldom more than a few hundred comments on a given post, and usually you want to get the whole tree of comments for a given post starting at the top of the comment thread:
SELECT * FROM comments WHERE root = 1234;
Then as you fetch the comments, you can write PHP code to process them into arrays of arrays according to the parent
columns (this is what @JanL's answer alluded to). I posted code to do this in my answer to another Stack Overflow question, Convert flat array to the multi-dimentional.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With