Reputation: 141
I'm wondering if it's possible to add values to a foreach array to keep it going until it can't go anymore. It's for a simple threaded-style message board system that, when a post is deleted it also deletes all posts under it.
I figured a foreach loop that pulls posts under it and adds them to the end of the array to keep it going until it runs of out rows would work but I can't seem to get it to keep going through all of them.
Current code is:
foreach ($deleterows as $key => &$value) {
$sql = "SELECT id FROM posts WHERE replyto='$value'";
$query = mysqli_query($con,$sql) or die("cannot select next posts");
while ($newrow = mysqli_fetch_array($query)) {
array_push($deleterows,$newrow['id']);
}
}
The first $deleterows is an array with the ID's of all posts that are replying to the post of the one I'm trying to delete. Then for each one it should be searching the DB to find replies for THAT post and adding it to the end of the $row array to keep it going until it has a full list of all posts that are to be deleted.
The test post I'm trying to do this on is as follows:
Post 53
-Post 54
--Post 55
---Post 56
-Post 57
--Post 58
Posts 54 and 57 are replies to the main post and the others are replies to them.
When I try to delete post 53 the $row array will have 53, 54, 55, 56 in it but still won't get row 57 or 58. Googled and such and just can't figure it out.
Upvotes: 1
Views: 191
Reputation: 141
After fiddling around with a couple of the answers I got and not being able to get them to work I took a combination of them and some other answers I found on Google and came up with a short script that seems to be working perfectly.
$deleterows = array();
$sql = "SELECT id FROM posts WHERE replyto='$postid'";
$query = mysqli_query($con,$sql) or die("Cannot select replies");
while($row = mysqli_fetch_array($query)) array_push($deleterows,$row['id']); #Get list of next level replies.
for($i=0; $i < count($deleterows); $i++) #loop through them and keep adding any further replies to the list to loop through.
{
$currentpost = $deleterows[$i];
$sql = "SELECT id FROM posts WHERE replyto='$currentpost'";
$query = mysqli_query($con,$sql) or die("Cannot select next post");
$count = mysqli_num_rows($query);
while($row = mysqli_fetch_array($query)) array_push($deleterows,$row['id']);
}
array_push($deleterows,$postid); #Add the original post to the deleterows array.
Then I just do a foreach loop on the deleterows array to actually update the row for each of those posts to 'deleted'.
Seems to be working great. I'm not sure if it's the BEST route to go so any additional pointers on cleaning that up to make it more efficient would be great. Thanks for the help, everyone.
Upvotes: 0
Reputation: 29
Hi you can use this code, this is working on my end
$con = mysql_connect('SERVER_NAME', 'USERNAME', 'PASSWORD') or die();
mysql_select_db('DB_NAME', $con) or die();
$out = array();
$sql = mysql_query("SELECT id FROM posts WHERE replyto='53'");
while($result = mysql_fetch_assoc($sql)){
$ids[] = $result['id'];
}
// the main function to loop thru the IDs
$callback = function($value, $key) use (&$con, &$callback, &$out){
$sql = mysql_query("SELECT id FROM posts WHERE replyto='$value'");
$res = mysql_fetch_assoc($sql);
if($res){
array_walk_recursive($res, $callback);
}
$out[] = $value;
};
array_walk_recursive($ids, $callback);
echo "<pre>"; print_r($out);
it will output
Array
(
[0] => 56
[1] => 55
[2] => 54
[3] => 58
[4] => 57
)
you can replace the $out[] = $value into the delete sql statement
Upvotes: 2
Reputation: 156
You could try something recursive like the following:
function delete($deleterows) {
global $con;
foreach ($deleterows as $key => &$value) {
$sql = "SELECT id FROM posts WHERE replyto='$value'";
$query = mysqli_query($con,$sql) or die("cannot select next posts");
$tmpdeleterows = array();
while ($newrow = mysqli_fetch_array($query)) {
$tmpdeleterows[]=$newrow['id'];
}
if(!empty($tmpdeleterows)) {
delete($tmpdeleterows);
}
}
}
All your IDs are added to a temporary array and then sent into the same function to be processed. I have added the global $con line assuming that your database connection is in the global scope, if not you could always pass it as a parameter.
Upvotes: 2