0

I have encountered an array of serialized values like below:

Array
(
    [primary] => Array
        (
            [key_type_0_key_name] => a:1:{i:0;s:5:"27232";}
            [key_type_1_key_name] => a:1:{i:0;s:5:"27231";}
            [key_type_2_key_name] => a:1:{i:0;s:5:"27147";}
            [key_type_3_key_name] => a:1:{i:0;s:5:"27157";}
        )

    [additional] => Array
        (
            [key_type_0_key_othername] => a:1:{i:0;s:5:"27169";}
            [key_type_1_key_othername] => a:1:{i:0;s:5:"27160";}
            [key_type_2_key_othername] => a:1:{i:0;s:5:"27103";}
            [key_type_3_key_othername] => a:1:{i:0;s:5:"27149";}
        )
)

Now I need to apply two functions namely, unserialize and array_shift in specified order to extract the scalar values like 27169 and store in another array, how can I do that in one pass of array_map or I have to run array_map two times compulsorily ?

Also one problem is with recursion, only array_walk_recursive handles recursion properly, but in my case if I try below code, I am getting the given error:

return array_walk_recursive($array, function ( &$value ) {
        $value = array_shift( unserialize( $value ) );
    });

Error:

 Strict Standards: Only variables should be passed by reference in /path/to/file.php on line 367

Expected Result:

Array
(
    [primary] => Array
        (
            27232
            27231
            27147
            27157
        )

    [additional] => Array
        (
            27169
            27160
            27103
            27149
        )
)
4
  • who told you can do that in one pass in first place and why it is that really makes a difference? Commented Sep 4, 2017 at 9:26
  • It was just a thought and try, as I have a large array(lot larger than the one mentioned in question) also read my updated question, if it may help Commented Sep 4, 2017 at 9:28
  • If you store the unserialized value in a variable and then do the array_shift it will fix the should be passed by reference error. Commented Sep 4, 2017 at 9:30
  • As you see, sub-array keys if can be maintained be well and good, but they aren't as important but the values are... Commented Sep 4, 2017 at 9:48

2 Answers 2

2

With no calls to array_map.

<?php

$data = [
    'primary' =>
    [
        'a:1:{i:0;s:5:"27232";}',
        'a:1:{i:0;s:5:"27231";}',
        'a:1:{i:0;s:5:"27147";}',
        'a:1:{i:0;s:5:"27157";}'
    ],
    'additional' =>
    [
        'a:1:{i:0;s:5:"27169";}',
        'a:1:{i:0;s:5:"27160";}',
        'a:1:{i:0;s:5:"27103";}',
        'a:1:{i:0;s:5:"27149";}'
    ]
];



$numbers = [];
foreach($data as $key=>$value) {
    foreach($value as $k=>$v) {
        $unserialized = unserialize($v);
        $numbers[$key][] = (int) array_shift($unserialized);
    }
}

var_dump($numbers);

Output:

array (size=2)
  'primary' => 
    array (size=4)
      0 => int 27232
      1 => int 27231
      2 => int 27147
      3 => int 27157
  'additional' => 
    array (size=4)
      0 => int 27169
      1 => int 27160
      2 => int 27103
      3 => int 27149

Here a mutating array_walk example with three array_map calls. Far uglier and harder to read in my eyes, but each their own:

array_walk($data, function(&$v) {
        $v = array_map('intval', array_map('array_shift', array_map('unserialize', $v)));
    }
);
var_dump($data);

Output:

    array (size=2)
      'primary' => 
        array (size=4)
          0 => int 27232
          1 => int 27231
          2 => int 27147
          3 => int 27157
      'additional' => 
        array (size=4)
          0 => int 27169
          1 => int 27160
          2 => int 27103
          3 => int 27149
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for a foreach based answer, but can this be done with array_map or array_walk_recursive, I have used those functions for most of my array operations and I don't want to break the trend frankly.
@VST, array_walk_recursive works on leaf nodes, so more difficult to associate keys. I've added an array_walk example.
It's ok, as I said, the sub-array keys are not important, thanks for array_walk example.
1

Allow me to answer the question that was asked. Yes, yes you can... and you nearly had it!

You only needed to change the way that you were accessing the value. Replace the array_shift() call with [0] -- this eliminates the Strict Standards error.

Code: (Demo)

$array=[
    'primary' =>
    [
        'a:1:{i:0;s:5:"27232";}',
        'a:1:{i:0;s:5:"27231";}',
        'a:1:{i:0;s:5:"27147";}',
        'a:1:{i:0;s:5:"27157";}'
    ],
    'additional' =>
    [
        'a:1:{i:0;s:5:"27169";}',
        'a:1:{i:0;s:5:"27160";}',
        'a:1:{i:0;s:5:"27103";}',
        'a:1:{i:0;s:5:"27149";}'
    ]
];
array_walk_recursive($array,function(&$v){$v=unserialize($v)[0];});
var_export($array);

Output:

array (
  'primary' => 
  array (
    0 => '27232',
    1 => '27231',
    2 => '27147',
    3 => '27157',
  ),
  'additional' => 
  array (
    0 => '27169',
    1 => '27160',
    2 => '27103',
    3 => '27149',
  ),
)

1 Comment

That's far healthier than my attempt at an array_walk and array_map codge-up.

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.