1

Having issues trying to perform a foreach within a while loop in PHP. I'm extracting build names from a database table. Those build names happen to be folder names. Within those folders is a folder (either Client or Clients) and within those are folders named after the clients business name. I want the script to show me the build name (accomplished already with an echo) and then list each folder below the build name.

$build_grab = mysql_query("SELECT b_id,b_name FROM builds", $link);
while($build_row = mysql_fetch_array($build_grab))
{
  $b_id = $build_row['b_id'];
  $b_name = $build_row['b_name'];

  $client_dir = is_dir("/somepath/builds/$b_name/Client/");
  $clients_dir = is_dir("/somepath/builds/$b_name/Clients/");

  if ($client_dir == '1') {
    $client_folders = explode(",", exec("ls -1 /somepath/builds/$b_name/Client/"));
  } elseif ($clients_dir == '1') {
    $client_folders = str_replace("\n","", explode(",", exec("ls -1 /somepath/builds/$b_name/Clients/")));
  };

  echo $b_name;
  echo "\r\n";

  foreach($client_folders as $folder)
  {
    echo $folder;
    echo "\r\n";
  }
}

Unfortunately this seems to only give me one (1) client folder name per build and it's always the last client (a-z) in the folder.

Example Output:

build-4.0.0.0
Client-f
build-4.0.0.1
Client-d
build-4.0.0.2
Client-j

What am I missing here or better yet, is there a more efficient way of doing this? Any help is greatly appreciated!

5
  • 1
    Don't use the mysql_* library. Use either mysqli_* or PDO. Commented Oct 18, 2013 at 17:51
  • I did not check your code but you probably initialize the variable in the for loop ( or the while loop ) so all the other is overriden every time you enter the for or the while loop. Commented Oct 18, 2013 at 17:51
  • foreach($folder as $subfolder) { // ... stuff ... } Commented Oct 18, 2013 at 17:52
  • 1
    Please, if you decide to ask your question on StackOverflow, take a few minutes to format your code properly. It is soo much easier to read code if it has proper indentation. Commented Oct 18, 2013 at 17:52
  • Chris - Thanks for your msyqli suggestion, I'll take that into consideration however at this time extracting data from the DB isn't an issue. Koray - If you would please elaborate and point out any errors I would really appreciate the help. Amal - I'm already using that syntax, thanks. Sumurai8 - Sorry for the format issues. Commented Oct 18, 2013 at 19:06

4 Answers 4

1

You're replacing the $client_folders variable each time. You want to create it as an array before you enter the while loop, then do this

if ($client_dir == '1') {
  $client_folders[] = explode(",", exec("ls -1 /somepath/builds/$b_name/Client/"));
} elseif ($clients_dir == '1') {
  $client_folders[] = str_replace("\n","", explode(",", exec("ls -1 /somepath/builds/$b_name/Clients/")));
};

By the way, this will only enter the first IF, since the second is exactly the same

Sign up to request clarification or add additional context in comments.

2 Comments

It is intended to be repeated in the while loop because there is a possibility of either a Client or Clients (with s) within each build folder. Apparently standardization of folder structures wasn't strong in this environment. The purpose of the if is to muddle through that.
Ah, I missed the s on the if. Gotcha
0

Rather than using

$client_folders = str_replace("\n","", explode(",", exec("ls -1 /somepath/builds/$b_name/Clients/")));

I would recommend using the following code to list the folders.

if ($folderHandle = opendir(clients_dir)) {
    while ($file = readdir($folderHandle) {
        echo "$file\n";
    }
    closedir($folderHandle);
}

You can change that code to be conditional, but it should give you a good list.

1 Comment

Or $client_folders = glob("/somepath/builds/$b_name/Client/*", GLOB_ONLYDIR)
0

exec() only returns the last line of output from the command. You should use the native PHP functions to read the directory list - either opendir/readdir or glob will work.

if ($client_dir == '1') {
  $client_folders = glob("/somepath/builds/$b_name/Client/*", GLOB_ONLYDIR);
} elseif ($clients_dir == '1') {
  $client_folders = glob("/somepath/builds/$b_name/Clients/*", GLOB_ONLYDIR);
};

1 Comment

If you must use exec() You could do this: unset $client_folders; exec("ls -1 ...", $client_folders); to capture each line of output in an array.
0

Thanks much to mcrumley, your suggestion of using 'glob' fixed it! Sorry crumley, I am apparently to newb to vote up your response. Perhaps other users can help with that.
Thanks also Chris for suggesting mysqli, I will code with it from here out, late adopter here.

Below the new code that resolved the issue.

$build_grab = $mysqli->query("SELECT b_id,b_name FROM builds");
  while($build_row = $build_grab->fetch_array())
{
  $b_id = $build_row['b_id'];
  $b_name = $build_row['b_name'];

  $client_dir = is_dir("/somepath/builds/$b_name/Client/");
  $clients_dir = is_dir("/somepath/builds/$b_name/Clients/");

  if ($client_dir == '1') {
    $client_folders = glob("/somepath/builds/$b_name/Client/*", GLOB_ONLYDIR);
  } elseif ($clients_dir == '1') {
    $client_folders = glob("/somepath/builds/$b_name/Clients/*", GLOB_ONLYDIR);
  };

  echo $b_name;
  echo "\r\n";

  foreach($client_folders as $folder)
  {
    echo $folder;
    echo "\r\n";
  }
}

Thanks again for everyones help!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.