【问题标题】:PHP: foreach inside while loop returning only one resultPHP:foreach在while循环中只返回一个结果
【发布时间】:2013-10-27 16:07:54
【问题描述】:

在 PHP 的 while 循环中尝试执行 foreach 时遇到问题。我正在从数据库表中提取构建名称。这些构建名称恰好是文件夹名称。这些文件夹中有一个文件夹(客户端或客户端),其中有以客户公司名称命名的文件夹。我希望脚本向我显示构建名称(已通过回显完成),然后在构建名称下方列出每个文件夹。

$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";
  }
}

不幸的是,这似乎每次构建只给我一 (1) 个客户端文件夹名称,并且它始终是文件夹中的最后一个客户端 (a-z)。

示例输出:

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

我在这里缺少什么或更好的是,有没有更有效的方法来做到这一点?非常感谢任何帮助!

【问题讨论】:

  • 不要使用mysql_* 库。使用mysqli_*PDO
  • 我没有检查您的代码,但您可能在 for 循环(或 while 循环)中初始化了变量,因此每次进入 for 或 while 循环时都会覆盖所有其他变量。
  • foreach($folder as $subfolder) { // ... stuff ... }
  • 如果您决定在 StackOverflow 上提问,请花几分钟时间来正确格式化您的代码。如果代码有适当的缩进,阅读代码会容易得多。
  • Chris - 感谢您的 msyqli 建议,我会考虑到这一点,但此时从数据库中提取数据不是问题。 Koray - 如果您能详细说明并指出任何错误,我将非常感谢您的帮助。 Amal - 我已经在使用这种语法了,谢谢。 Sumurai8 - 很抱歉格式问题。

标签: php mysql foreach while-loop


【解决方案1】:

您每次都在替换 $client_folders 变量。您想在进入 while 循环之前将其创建为数组,然后执行此操作

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/")));
};

顺便说一句,这只会输入第一个 IF,因为第二个是完全相同的

【讨论】:

  • 它打算在 while 循环中重复,因为每个构建文件夹中都可能存在一个客户端或多个客户端(带有 s)。显然,在这种环境下,文件夹结构的标准化并不强。 if 的目的是为了解决这个问题。
  • 啊,我错过了 if 上的 s。明白了
【解决方案2】:

而不是使用

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

我建议使用以下代码列出文件夹。

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

您可以将该代码更改为有条件的,但它应该会给您一个很好的列表。

【讨论】:

  • $client_folders = glob("/somepath/builds/$b_name/Client/*", GLOB_ONLYDIR)
【解决方案3】:

exec() 只返回命令的最后一行输出。您应该使用原生 PHP 函数来读取目录列表 - opendir/readdirglob 都可以。

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);
};

【讨论】:

  • 如果您必须使用exec(),您可以这样做:unset $client_folders; exec("ls -1 ...", $client_folders); 捕获数组中的每一行输出。
【解决方案4】:

非常感谢 mcrumley,您使用 'glob' 的建议解决了这个问题!对不起,克鲁姆利,我显然要让 newb 投票赞成你的回应。也许其他用户可以提供帮助。
也感谢 Chris 对 mysqli 的建议,我将从这里开始使用它进行编码,这里是后来者。

在解决问题的新代码下方。

$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";
  }
}

再次感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 2013-12-18
    • 2011-09-26
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2012-11-15
    • 2020-05-07
    相关资源
    最近更新 更多