-1

I'm populating an Array from a While Loop but am unable to produce the proper array format. I've hit many different variations but not what I am looking for which is included below. The purpose is for 3rd party SMTP, as seen in the variable $to

Desired Array:

array(3) { 
    ["email1@email1.com"]=> array(1) { ["userid"]=> string(1) "6" } 
    ["email2@email2.com"]=> array(1) { ["userid"]=> string(2) "64" } 
    ["email3@email3.com"]=> array(1) { ["userid"]=> string(3) "503" } 
}

Attempt 1:

$str = array();
while($userEmails = $query->fetch(PDO::FETCH_ASSOC)){

    $str[] = '"'.$userEmails['user_email'].'"  => array( 
       "userid" => "'.$userEmails['user_id'].'" 
    )';
}
$to = $str;

Attempt 1 Incorrect Array:

array(3) {
     [0]=> string(54) ""email1@email1.com" => array( "userid" => "6" )"       
     [1]=> string(54) ""email2@email2.com" => array( "userid" => "64" )" 
     [2]=> string(54) ""email3@email3.com" => array( "userid" => "503" )" 
}

Attempt 2:

$str = "";
while($userEmails = $query->fetch(PDO::FETCH_ASSOC)){

    $str .= '"'.$userEmails['user_email'].'"  => array( "userid" => "'.$userEmails['user_id'].'" )';
}

$emails = rtrim($str, ", ");

$to = array($emails);

Attempt 2 Incorrect Array:

array(1) { 
    [0]=> string(162) ""email1@email1.com" => array( "userid" => "6" )"email2@email2.com" => array( "userid" => "64" )"email3@email3.com" => array( "userid" => "503" )" }
Klav
  • 405
  • 1
  • 9
  • 19
  • 1
    imo, It is easier to understand if you do it as separate steps initially? 1) `$userEmail = $userEmails['user_email'];` 2) `$userId = $userEmails['user_id'];`. There are so many ways to do this from here... 3) (one way:) `$str[][$userEmail]['userid'] = $userid;`. – Ryan Vincent Jun 26 '16 at 18:31

3 Answers3

1

You want this, I think:

$str = array();
while($userEmails = $query->fetch(PDO::FETCH_ASSOC)){
    $str[$userEmails['user_email']] = array(
        'user_id' => $userEmails['user_id']
    );
}
rjdown
  • 9,162
  • 3
  • 32
  • 45
1

I personally think using while with fetch forces you into accepting ugly code. I usually have a couple of utility functions for writing more declarative code

function query_reduce(callable $f, $initialValue, $query) {
  $result = $initialValue;
  while($x = $query->fetch(PDO::FETCH_ASSOC))
    $z = call_user_func($f, $x);
  return $result;
}

Now you can write this

$result = query_reduce(function ($acc, $x) {
  $acc[$x['user_email']] = [['user_id'] => $x['user_id']];
  return $acc;
}, [], $query);

var_dump($result);

query_reduce is just one of the helpers I use. Here's one that works like foreach

// use like foreach
function query_foreach(callable $f, $query) {
  query_reduce(function($i, $x) {
    call_user_func($f, $i++);
  }, 0, $query);
}

// $query returns [{id:'a'}, {id:'b'}, {id:'c'}]
query_foreach(function ($x, $i) {
  echo "{$x['id']} is in position {$i}";
});

// output
// a is in position 0
// b is in position 1
// c is in position 2

Or one that is for mapping over the query

// use like array_map
function query_map(callable $f, $query) {
  $i = 0;
  return query_reduce(function ($acc, $x) use ($i) {
    return array_merge($acc, [call_user_func($f, $x, $i++)]);
  }, [], $query);
}

// $query returns [{id:'a'}, {id:'b'}, {id:'c'}]
$ids = query_foreach(function ($x, $i) {
  return ['id'=> $x['id'], 'position'=> $i];
});

print_r($ids);

// output...
// Array
// (
//     Array
//     (
//         [id] => a
//         [position] => 0
//     )
//     Array
//     (
//         [id] => b
//         [position] => 1
//     )
//     Array
//     (
//         [id] => c
//         [position] => 2
//     )
// )
Mulan
  • 129,518
  • 31
  • 228
  • 259
0

Try this way:

$str = array();
while($userEmails = $query->fetch(PDO::FETCH_ASSOC)){
    $str[$userEmails['user_email']] = array('userid' => $userEmails['user_id']);
}

$to = $str;