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)

6
  • 5
    AFAIK PDO's execute() will work correctly even if the keys aren't prefixed by a colon. Commented Oct 1, 2011 at 8:16
  • 2
    check this stackoverflow.com/questions/2607595/… Commented Oct 1, 2011 at 8: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) Commented Oct 1, 2011 at 8:18
  • @Bracketworks: what php version are you using? Tested with 5.2.17 and 5.3.8 here, and working as expected. Commented Oct 1, 2011 at 8:28
  • 1
    @fireeyedboy - Yea, sleep deprivation != working. 5.3.6, and yea, its working :) Sorry NullUser, you were right also. Commented Oct 1, 2011 at 8:30

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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!
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);

Comments

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);

2 Comments

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.
What the function does do is remove a leading : from the values in the array.
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.

1 Comment

Flipping must not be trusted if the values in the array may collide after being coalesced to a scalar-type key.

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.