【问题标题】:Concatenating values from one array to another in PHP在 PHP 中将值从一个数组连接到另一个数组
【发布时间】:2012-03-30 14:23:54
【问题描述】:

我有一个主数组,它是 MySQL 查询用户表返回的数据,如下所示:

array(36) {
  [0]=>
  array(4) {
    ["id"]=>
    string(1) "101"
    ["email"]=>
    string(15) "kkkk@gggg.com"
    ["firstname"]=>
    string(8) "aaaaa"
    ["lastname"]=>
    string(12) "bbbbb"

  }
  [1]=>
  array(4) {
    ["id"]=>
    string(1) "102"
    ["email"]=>
    string(17) "mmmmm@hhhhh.com"
    ["firstname"]=>
    string(12) "vvvv"
    ["lastname"]=>
    string(12) "zzzzz"

  }
  [2]=>
  array(4) {
    ["id"]=>
    string(2) "103"
    ["email"]=>
    string(17) "eeee@gmail.com"
    ["firstname"]=>
    string(6) "ggggg"
    ["lastname"]=>
    string(12) "zzzzz"

等等…… 第二个数组也是 MySQL 查询,它来自具有两个外键的表,使关系 b/w 两个表多对多,如下所示:

array(7) {
  [0]=>
  array(2) {
    ["user_id"]=>
    string(3) "101"
    ["group_id"]=>
    string(1) "1"
  }
  [1]=>
  array(2) {
    ["user_id"]=>
    string(3) "102"
    ["group_id"]=>
    string(1) "1"
  }
  [2]=>
  array(2) {
    ["user_id"]=>
    string(3) "103"
    ["group_id"]=>
    string(1) "1"
  }

最终目标是在第一个数组中创建第 5 个键,类似于:

[“组”]=>...

我可以用每个用户参与的组的 id 来填充,最后看起来像这样:

[“组”]=>“1,2,3,4”

换句话说,因为关系是多对多的,所以当我推送新值时,用户可能参与多个组,我不想创建具有值的新键,而是连接现有值带有新 ID 的密钥。

到目前为止,我得到了这样的东西:

$query = $this->mUsers->getAll(); //Main query to get users data
          $results = $this->mUsers->getGroupsAndUsers(); //Query for getting the group_id and user_id
        //  Looping both arrays to find matching ID's

          foreach($query as $key=>$value){ //$value['id'] returns the value of the users id from table users
              foreach($results as $row){
                  if ($value['id']==$row['user_id'])
               {
                          array_push($value,"groups",$row['group_id']);

                }

              } 

}

但我不工作。我尝试了其他一些东西,但现在什么都没有。

谢谢 勒隆

【问题讨论】:

    标签: php sql codeigniter


    【解决方案1】:

    你最好用 SQL 做繁重的工作,而不是用 PHP。

    所以,如果你的用户表是这样的:

    ...您的组表是这样的:

    ...你的 users_groups 表是这样的:

    ...那么您可以使用以下查询:

    SELECT id,email,firstname,lastname, GROUP_CONCAT(users_groups.group_id) as groups
    FROM `users`
    JOIN users_groups on users.id = users_groups.user_id
    GROUP BY users.id;
    

    (或者这个,如果你在 phpMyAdmin 中测试)

    SELECT id,email,firstname,lastname, GROUP_CONCAT(CAST(users_groups.group_id AS CHAR)) as groups
    FROM `users`
    JOIN users_groups on users.id = users_groups.user_id
    GROUP BY users.id;
    

    ...产生这个输出:

    感谢this post 提供有关如何从 SQL 生成逗号分隔值的信息,以及有关使用 CAST AS CHAR 的评论。

    【讨论】:

    • 嘿,如果你仍然关注这个。这个非常好,但实际上,它只获取组列不为空的行。有没有办法列出所有用户,无论他们是否在一个组中?
    • 这应该是SQL中'join'的设置之一。让我检查一下,我会用我的发现更新我的帖子......
    • 如果您将“JOIN”替换为“LEFT JOIN”,那么这将包括所有用户。如果用户不在任何组中,那么您将在组列中获得 NULL。希望有帮助。如有必要,很高兴使用 LEFT JOIN 更新我的原始帖子...
    • 是的,泰。我尝试使用 IFNULL 和 LEFT JOIN 并且它有效,我将尽快尝试仅使用 LEFT JOIN,希望它也能以这种方式工作。不过非常有用的帖子。谢谢。
    【解决方案2】:

    尝试构造一个逗号分隔的字符串会让您的生活变得更加困难,并使数据变得不那么有用。创建一个值的子数组更有意义,如果您需要字符串表示形式,您可以implode(',', $arr)。如果您的用户数据数组与user_id 字段具有相同的键,它还会使工作变得更容易,并且数据更有用:

    // First, get the array of users and format it with sensible keys
    $users = array();
    foreach ($this->mUsers->getAll() as $user) $users[$user['id']] = array_merge($user, array('groups' => array()));
    
    // Now assign group relationships
    foreach ($this->mUsers->getGroupsAndUsers() as $group) {
      $users[$group['user_id']]['groups'][] = $group['group_id'];
    }
    
    print_r($users);
    

    【讨论】:

    • 这是最接近我需要的,但对我来说是最难理解的。通过一个简单的问题,我得到:["groups"]=> array(0) {,但我需要一个字符串,可以更改它吗,因为我需要时间阅读您的示例?
    • @Leron 当然,最后再循环一次数据,然后implode() it:foreach ($users as &$user) $user['groups'] = implode(',', $user['groups']);。顺便说一下,我对上面的代码做了一个小修复,它不太正确。如果你想玩它,看看here
    • 谢谢,我想进一步研究一下!
    【解决方案3】:

    现在,您传递的是克隆值,而不是对 foreach 的引用。如果您运行 foreach($array as $value),则 $value 是一个副本。您必须将其作为 foreach($array as &$value) 运行才能实际编辑 $value。 & 表示您将参数作为引用传递,而不仅仅是克隆它。

    让我用一个简单的例子来演示一下。

    $names = array("bob", "joe", "mustafa", "ghandi");
    foreach($names as $name) {
        $name = "name: " . $name; 
    }
    print_r($names);
    /** prints:
    Array
    (
        [0] => bob
        [1] => joe
        [2] => mustafa
        [3] => ghandi
    )
    */
    
    
    $names = array("bob", "joe", "mustafa", "ghandi");
    foreach($names as &$name) {
        $name = "name: " . $name; 
    }
    print_r($names);
    /** prints:
    Array
    (
        [0] => name: bob
        [1] => name: joe
        [2] => name: mustafa
        [3] => name: ghandi
    )
    */
    

    【讨论】:

    • 是的,但问题是它应该是 - [0]=>name: bob, Joe, Mustafa
    【解决方案4】:

    你已经接近了!

    试试:

    foreach($query as $key=>$value ) {
        foreach($results as $row) {
            if( $value['id'] == $row['user_id'] ) {
                $query[$key]['groups'][] = $row['group_id'];
            }
        }
    }   
    

    空括号[] 附加到数组

    【讨论】:

    • 我尝试了这种方式,因为它更接近我的方法,但它不能按原样工作:(
    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多