Php 将常规数组重建为多维数组

Php 将常规数组重建为多维数组,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,我有一个数组,它从单个表中输出DB的信息,如下所示: Array ( [0] => stdClass Object ( [users_info_id] => 1 [user_id] => 374 [user_email] => foos@foo.com [address_type] => BT [firstname] =&g

我有一个数组,它从单个表中输出DB的信息,如下所示:

Array
(
    [0] => stdClass Object
        (
            [users_info_id] => 1
            [user_id] => 374
            [user_email] => foos@foo.com
            [address_type] => BT
            [firstname] => Foo
            [lastname] => Faa
            [vat_number] => 
            [country_code] => US
            [address] => Jajajaja
            [city] => KOKOKOKOKOKO
            [state_code] => MD
            [zipcode] => 20745
            [phone] => 2401111111
        )
    [1] => stdClass Object
        (
            [users_info_id] => 1
            [user_id] => 374
            [user_email] => foos@foo.com
            [address_type] => ST
            [firstname] => Foos
            [lastname] => Faas
            [vat_number] => 
            [country_code] => US
            [address] => JSUSUSUS
            [city] => LASOSLSL
            [state_code] => DC
            [zipcode] => 1234
            [phone] => 1234567895
        )
        // ... about 500 records...
)
我想要的是重新构建该数组的每个块,以便输出如下所示:

Array
(
    [0] => stdClass Object
        (
            [users_info_id] => 1
            [user_id] => 374
            [user_email] => foos@foo.com
            [phone] => 3213213213
            [bt] => array (
                [firstname] => Foo
                [lastname] => Faa
                [vat_number] => 
                [country_code] => US
                [address] => Jajajaja
                [city] => KOKOKOKOKOKO
                [state_code] => MD
                [zipcode] => 20745
                [phone] => 2401111111
              )
            [st] => array (
                [firstname] => Foos
                [lastname] => Faas
                [vat_number] => 
                [country_code] => US
                [address] => JSUSUSUS
                [city] => LASOSLSL
                [state_code] => DC
                [zipcode] => 1234
                [phone] => 1234567895
              )
        )
   ...
   ...
   // Create a suitable address subarray and fill it.
   if ($row->address_type == 'BT') {
       // If the array that collects several bts has not been created, create it.
       if (!isset($outputRow['bt']) {
           $outputRow['bt'] = array();
       }

       // Create an array with the bt address data
       $addressData = array();
       $addressData['firstname'] = $row->firstname;
       $addressData['lastname'] = $row->lastname;
       ...

       // Add the bt address data to the collection of bts. 
       $outputRow['bt'][] = $addressData;
   } 
   if ($row->address_type == 'ST') {
      // dito, but for ['st']
      // ...
   }
我甚至不知道如何启动代码来实现这一点,而且,如果您注意到,ST和BT密钥来自第一个数组中显示的密钥地址类型,ST表示“配送地址”,BT表示账单地址,有些用户有一个配送地址和一个账单地址,但有些用户有3个或更多配送地址…

任何帮助都将不胜感激。

在这种情况下,我将使用以下循环:

$outputArray = array();

$previousUserId = -1;

// Loop through all source records.
foreach ($inputRows as $row) {

   // If the current row has a different user id thn the row before,
   // add the output row to the final output array and prepare a new output row. 
   // If the current row has the same user id as the row before, 
   // just add further address information.
   // This handles also the start situation, $previousUserId = -1.
   if ($previousUserId != $row->user_id) {
       if ($previousUserId >= 0) {
           $outputArray[] = $outputRow;
       }
       $outputRow = array();

       // Copy main attributes
       $outputRow['users_info_id'] = $row->users_info_id;
       $outputRow['user_id'] = $row->user_id;
       $outputRow['user_email'] = $row->user_email;
       $outputRow['phone'] = $row->phone;
   }

   $previousUserId = $row->user_id;

   // Create a suitable address subarray and fill it.
   if ($row->address_type == 'BT') {
       $outputRow['bt'] = array();
       $outputRow['bt']['firstname'] = $row->firstname;
       $outputRow['bt']['lastname'] = $row->lastname;
       ...
   } 
   if ($row->address_type == 'ST') {
      // dito, but for ['st']
      // ...
   }
}
这只是一个结构,你必须完成它

代码在输入表的每条记录中循环,我们称之为
$inputRows
。如果
用户id
发生更改,这一点很重要,因为这将启动一个新的输出行。只要
user\u id
保持不变,代码只会向当前输出行添加更多地址类型。因此,多个输入行被分组为一个输出行。然后在
$outputArray
中收集所有输出行

请注意:

1) 您在问题中显示的转储显示包含对象的数组。在我的回答中,我创建了一个包含数组作为输出的数组。通常,我更喜欢只使用关联数组,因为它们在选择名称时提供了更多的自由。如果要处理对象,只需相应地修改代码即可。(
$outputObject->name=…
而不是
$outputObject['name']
=…)

2) 我假设user_id标准与将输入行分组到新的输出行相关。我希望这是正确的-D

编辑:如果地址类型有多条记录,可以添加一个额外的数组层,如下所示:

Array
(
    [0] => stdClass Object
        (
            [users_info_id] => 1
            [user_id] => 374
            [user_email] => foos@foo.com
            [phone] => 3213213213
            [bt] => array (
                [firstname] => Foo
                [lastname] => Faa
                [vat_number] => 
                [country_code] => US
                [address] => Jajajaja
                [city] => KOKOKOKOKOKO
                [state_code] => MD
                [zipcode] => 20745
                [phone] => 2401111111
              )
            [st] => array (
                [firstname] => Foos
                [lastname] => Faas
                [vat_number] => 
                [country_code] => US
                [address] => JSUSUSUS
                [city] => LASOSLSL
                [state_code] => DC
                [zipcode] => 1234
                [phone] => 1234567895
              )
        )
   ...
   ...
   // Create a suitable address subarray and fill it.
   if ($row->address_type == 'BT') {
       // If the array that collects several bts has not been created, create it.
       if (!isset($outputRow['bt']) {
           $outputRow['bt'] = array();
       }

       // Create an array with the bt address data
       $addressData = array();
       $addressData['firstname'] = $row->firstname;
       $addressData['lastname'] = $row->lastname;
       ...

       // Add the bt address data to the collection of bts. 
       $outputRow['bt'][] = $addressData;
   } 
   if ($row->address_type == 'ST') {
      // dito, but for ['st']
      // ...
   }

对于更多的需求,我建议将收集地址数据的部分外包给自己的函数,以便整个代码保持可读性

您是否考虑过使用多个查询?抓取每个唯一的
users\u info\u id
,并将它们存储在一个数组中。然后循环该数组并查询唯一的地址类型,并将这些输出存储在同一数组中?因此,如果使用数据库查询条件的
$user['users\u info\u id']
循环使用
$users[$addressTypeFromDB]=$dbRow谢谢,这是我的出发点,正在工作,但是,如果用户有超过1个ST或BT,它不会显示,只会覆盖其中的内容,所以我为每个添加了一个“计数器”$cst=0和$cbt=0,并且在每个if type='BT'或ST中添加了“sum”$cst++。。。按照代码中的逻辑,如果用户id相同,它将添加另一个键[0]、[1]。。。依此类推,直到用户id不同,“计数器”被重置为0,但不工作,在第一个循环中,它显示[bt]=>array([7]…),然后对于下一个用户,它工作正常。。。有点奇怪…很抱歉回答晚了。。。我不确定您是否需要计数器(或者我是否正确理解要求)。请看我在代码中的建议。