6

Quick one; I know a solution, but I'm looking for something more elegant if it exists.

I'm using PDO for prepeared statements:

$sql = "INSERT INTO my_table (foo, bar, baz) VALUES (:foo, :bar, :baz)";

$source->execute($sql, array(
    ':foo' => $foo,
    ':bar' => $bar,
    ':baz' => $baz,
));

This is fine, but I want to pass in a previously created array, however the keys contained aren't prefixed by the colon (:), and I figure there must be an elegant way to take:

$array = array(
    'foo' => 'some',
    'bar' => 'random',
    'baz' => 'value',
);

And translate it into:

$array = array(
    ':foo' => 'some',
    ':bar' => 'random',
    ':baz' => 'value',
);

Without doing:

$temp = array();
foreach($array as $key => $value){
    $temp[':' . $key] = $value;
}
$array = $temp;

I've browsed the PHP docs, but I can't find a function (or sequence of) that suits the purpose.

Any ideas?


Addendum

Leaving the accepted answer, but +1 @chim for his clever 1-liner; solves the X in my XY problem. Reformatted solution:

$format = ':%s';
$values = array_flip(array_map(function ($key) use($format) {
    return sprintf($format, $key);
}, array_flip($values)));

Wrapped in a function, perhaps array_keys_format(array $array, $format)

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174
  • 5
    AFAIK PDO's `execute()` will work correctly even if the keys aren't prefixed by a colon. – NullUserException Oct 01 '11 at 08:16
  • 2
    check this http://stackoverflow.com/questions/2607595/fastest-way-to-add-prefix-to-array-keys – Mithun Satheesh Oct 01 '11 at 08:17
  • @NullUserException - I thought that too, but its kicking back invalid SQL state, complaining about the query parameters (*other than the colon prefix, it would run given its unnecessary*) – Dan Lugg Oct 01 '11 at 08:18
  • @Bracketworks: what php version are you using? Tested with `5.2.17` and `5.3.8` here, and working as expected. – Decent Dabbler Oct 01 '11 at 08:28
  • 1
    @fireeyedboy - Yea, sleep deprivation != working. `5.3.6`, and yea, its working :) Sorry NullUser, you were right also. – Dan Lugg Oct 01 '11 at 08:30

4 Answers4

8
$source->execute($sql, array(
    'foo' => $foo,
    'bar' => $bar,
    'baz' => $baz
));

This is presuming the above calls PDOStatement::execute() under the hood, with the above array as its argument.1

:)


1) Tested with version 5.2.17 and 5.3.8 here, and working as expected.
Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106
  • You know, perhaps it's late, but its working now. I'm going to bed, but first I'm accepting this answer because it fixes the problem, just as NullUser had said too. +1's all around. Thanks @fireeyedboy! – Dan Lugg Oct 01 '11 at 08:28
3

It has already been answered but this is what I came up with anyway.

$arr = array('foo'=>1,'bar'=>2);

$arr = array_flip($arr);

array_walk($arr,create_function('&$v,$k', '$v = ":$v";'));

$arr = array_flip($arr);

print_r($arr);
lsl
  • 4,371
  • 3
  • 39
  • 54
2

One liner...

$array = array('test'=>'55','yest'=>'66');

$array = array_flip(array_map(function($v){return ':' . $v;},array_flip($array)));

// array(':test'=>'55',':yest'=>'66');

However this isn't safe as array_flip relies on all values being unique.

So one of the looping solutions is probably the best, or alternatively array_keys with array_combine.

chim
  • 8,407
  • 3
  • 52
  • 60
2

use the php map-function: http://php.net/manual/en/function.array-map.php

function reduce($key)
{
if(strpos($key,":")===0)
return substr($key,1);
return $key;
}

$array = array_map("reduce",$array);
0xDEADBEEF
  • 3,401
  • 8
  • 37
  • 66
  • Doesn't work array_map doesn't affect the keys of an array, and the reduce function above doesn't prepend a : to the beginning of anything. – chim Apr 09 '13 at 15:45
  • What the function does do is remove a leading : from the values in the array. – chim Apr 09 '13 at 15:46