1

I have a PHP object that I would like to convert to a multidimensional array but I can't seem to work it out.

This is my data structure...

Array (
    [0] => stdClass Object (
        [code] => 63205RMVF
        [vq_ref] => 60001689
        [start] => 2012-01-10
        [done_elm] =>
        [unitref] => D5027581
        [vqdesc] => Diploma in Dental Nursing
        [descrip] => Scientific principles in the management of oral health diseases and dental procedures
        [credit_val] => 5
        [achieve] =>
    )
    [1] => stdClass Object (
        [code] => 63205RMVF
        [vq_ref] => 60001689
        [start] => 2012-01-10
        [vq_exp] => 2014-01-09
        [enddate] =>
        [vq_act] =>
        [done_elm] =>
        [unitref] => D5027600
        [vqdesc] => Diploma in Dental Nursing (
            QCF
        )
        [bodynum] => Unit 306
        [descrip] => Provide chairside support during the assessment of patients\' oral health
        [credit_val] => 1
        [start_1] => 2013-03-19
        [expect] =>
        [achieve] => 2013-11-29
        [status] => A
        [done_elm_1] => 100
    )
    [2] => stdClass Object (
        [code] => 63205RMVF
        [vq_ref] => 60001689
        [start] => 2012-01-10
        [vq_exp] => 2014-01-09
        [enddate] =>
        [vq_act] =>
        [done_elm] =>
        [unitref] => DN317
        [vqdesc] => Diploma in Dental Nursing (
            QCF
        )
        [bodynum] => DN317
        [descrip] => Level 3 Principles and theory of Dental Nursing
        [credit_val] =>
        [start_1] =>
        [expect] =>
        [achieve] => 2013-09-19
        [status] => A
        [done_elm_1] =>
    )

And I want to convert it to an array pattern like this...

[aim] = [
    [code]
    [vq_ref]
    [units] => [
        [start]
        [vq_exp]
        [enddate]
        [vq_act]
        [done_elm]
        [unitref]
        [vqdesc]
        [bodynum]
        [descrip]
        [credit_val]
        [start_1]
        [expect]
        [achieve]
        [status]
        [done_elm_1]
    ]
]

At the moment I have scrambled together this, I just can't work it out!

foreach($results as $result)
{
    $unit['aim'][$result->vq_ref]['unit'] = array()
        'unit_ref'   => $result->unitref,
        'unit_title' => $result->descrip,
        'start'      => $result->start,
        'achieved'   => $result->achieve,
        'value'      => $result->credit_val
    );
}

foreach($results as $result)
{
    $data['aim'][$result->vq_ref] = array(
        'aim_ref'   => $result->vq_ref,
        'aim_title' => $result->vqdesc,
        'units'     => array($unit['aim'][$result->vq_ref]['unit'])
    );
}
4
  • Why are the vq_ref values all the same? Commented Jan 3, 2014 at 14:52
  • can't you cast object to array explicitly; The following code $obj = new x(); var_dump($obj); var_dump((array)$obj); without any problems makes the object into associative array. You would just need to cast each object that is contained into your primary array. Commented Jan 3, 2014 at 14:54
  • @RocketHazmat this is just a few of the records from the data set, there could be several though Commented Jan 3, 2014 at 14:54
  • So, then what's the issue with the code you have? Does it work? What does it output? Commented Jan 3, 2014 at 14:55

3 Answers 3

2

The function you're searching for is called get_object_vars

 $unit['aim'] = array_map('get_object_vars',$yourArray);

EDIT : misunderstanding of the subject

One way of doing that can be mapping your array with this function and splitting the properties in two set as you want :

function split_collection($object){
   $array = get_object_vars($object);
   $newArray = [$array['code'],$array['vqref'],"units"=>[]];
   unset($array['code']);
   unset($array['vq_ref']);
   $newArray['units'] = $array;
   return $newArray;
 }
 $unit['aim'] = array_map('split_collection',$yourCollection);
Sign up to request clarification or add additional context in comments.

2 Comments

I'd suggest using array_map here instead of array_walk. Like this: $data = array_map(function($x){ return get_object_vars($x); }, $results);. Because array_walk expects you to update the reference it passes to the callback, it doesn't care about the callback's return value.
True enough. I also updated the whole answer because it did not fit the format he wanted.
0

I actually solved it by using this. I wasn't far off in the first instance but this seems to do the trick just fine for me...

foreach($results as $result)
{
    $units[$result->vq_ref][] = array(
        'unit_ref'   => $result->unitref,
        'unit_title' => $result->descrip,
        'start'      => $result->start,
        'achieved'   => $result->achieve,
        'value'      => $result->credit_val
    );
}

foreach($results as $result)
{
    $data['aim'][$result->vq_ref] = array(
        'aim_ref'   => $result->vq_ref,
        'aim_title' => $result->vqdesc,
        'units'     => $units[$result->vq_ref]
    );
}

Comments

0

Based on the asker's self-answering post, this grouping task can be simplified to just one loop. There is no need to convert each object to a temporary array for the sake of accessing data. The aim_ref and aim_title values are free to overwrite themselves on each iteration of the same group. Each set of "unit" data can be pushed as a new child of units. Demo

$data = [];
foreach ($results as $result) {
    $data['aim'][$result->vq_ref]['aim_ref'] = $result->vq_ref;
    $data['aim'][$result->vq_ref]['aim_title'] = $result->vqdesc;
    $data['aim'][$result->vq_ref]['units'][] = [
        'unit_ref'   => $result->unitref,
        'unit_title' => $result->descrip,
        'start'      => $result->start,
        'achieved'   => $result->achieve,
        'value'      => $result->credit_val,
    ];
}

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.