oxwilder
oxwilder

Reputation: 757

How can I create an array of variables based on an associative array's value in PHP?

Given the following array

 ( 
 0 => array( 
     'orders_messaging_info_id' => '1',
     'column_name' => 'message_route',
     'column_info' => 'internal',
     ),
 
 1 => array(
     'orders_messaging_info_id' => '2',
     'column_name' => 'message_route',
     'column_info' => 'external',
     ),
 
 2 => array(
     'orders_messaging_info_id' => '3',
     'column_name' => 'message_type',
     'column_info' => 'SMS',
     ),
 
 3 => array(
     'orders_messaging_info_id' => '4',
     'column_name' => 'message_type',
     'column_info' => 'email',
     ),
 
 4 => array(
     'orders_messaging_info_id' => '5',
     'column_name' => 'message_type',
     'column_info' => 'slack',
     ),
 
 5 => array(
     'orders_messaging_info_id' => '6',
     'column_name' => 'message_type',
     'column_info' => 'plaintext',
     ),
 
 6 => array(
     'orders_messaging_info_id' => '10',
     'column_name' => 'message_text',
     'column_info' => 'JSON',
     ),
 )

how can I create three associative arrays named for the value of 'column_name' whose keys are the value at 'orders_messaging_info_id' and values are at 'column_info'?

I tried using extract() in a foreach loop on the value of 'column_name' to create three variables -- one for each distinct value -- but I don't know how to access the other two values per array to assign them. And once I tackle that, I know I'll have to figure out a way to add values to the arrays that extract() creates, such as with the array variable that will be named $message_type[] or $message_route[]

The expected array would look like

$message_route = array('1'=>'internal','2'=>'external');

Upvotes: 0

Views: 97

Answers (2)

mickmackusa
mickmackusa

Reputation: 47864

While PHP makes it possible to generate "variable variables", it is typically considered poor practice to do so. Variable variables are effectively suboptimally structure arrays. You are still packagin array-like data, but in a manner that eliminates the opportunity to enjoy PHP's suite of array functions. It's like forcing yourself to type code with your keyboard super-glued to the underside of your desk -- there's no benefit.

This is a working solution, but it is:

  • Not easy to read
  • Likely to confuse your IDE because it will not be able to trace your subsequently accessed variables ( like message_text, etc.)
  • Individual variables will need to be called by name instead of being accessible inside of a loop or function.
  • You will need to check if each array exists because depending on the payload, some expected variables may not be declared.

Code: (Demo)

foreach ($array as $row) {
    ${$row['column_name']}[$row['orders_messaging_info_id']] = $row['column_info'];
}
 
var_export($message_text);
echo "\n---\n";
var_export($message_route);
echo "\n---\n";
var_export($message_type);

Instead, I recommend that you abandon the notion of using variable variables and use a single result array that has first-level keys with the same intended meaning. Calling extract() on each row will help to improve readability as well. (Demo)

$result = [] ;
foreach ($array as $row) {
    extract($row);
    $result[$column_name][$orders_messaging_info_id] = $column_info;
}
 
var_export($result);

Upvotes: 0

Zoli Szabó
Zoli Szabó

Reputation: 4534

extract() doesn't really help you here. Instead, you should make use of variable variables (https://www.php.net/manual/en/language.variables.variable.php). Something like:

<?php

$array = array(
 0 => array( 
     'orders_messaging_info_id' => '1',
     'column_name' => 'message_route',
     'column_info' => 'internal',
     ),
 1 => array(
     'orders_messaging_info_id' => '2',
     'column_name' => 'message_route',
     'column_info' => 'external',
     ),
 2 => array(
     'orders_messaging_info_id' => '3',
     'column_name' => 'message_type',
     'column_info' => 'SMS',
     ),
 3 => array(
     'orders_messaging_info_id' => '4',
     'column_name' => 'message_type',
     'column_info' => 'email',
     ),
 4 => array(
     'orders_messaging_info_id' => '5',
     'column_name' => 'message_type',
     'column_info' => 'slack',
     ),
 5 => array(
     'orders_messaging_info_id' => '6',
     'column_name' => 'message_type',
     'column_info' => 'plaintext',
     ),
 6 => array(
     'orders_messaging_info_id' => '10',
     'column_name' => 'message_text',
     'column_info' => 'JSON',
     ),
 );
 
 foreach($array as $entry) {
     $name = $entry['column_name'];
     if (!isset($$name)) {
        $$name = [];    
     }
     $$name[$entry['orders_messaging_info_id']] = $entry['column_info'];
 }
 
 var_dump($message_text, $message_route, $message_type);

Upvotes: 2

Related Questions