Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Want to pass a list of values in PHP (as in Perl), not reference to array

I'm hitting my head against a wall because the way I'm used to doing things in Perl doesn't work in PHP. This is most likely something so basic I don't know how to properly ask the question. The crux: I'm used to sending an array in list context as the argument to a function in Perl, but in PHP I'm only passing a reference to the array.

I'm trying to make a basic SQL query in PHP using MySQLi, for example, SELECT * FROM my_table WHERE first_name = 'Bob' AND last_name = 'Smith' AND city = 'Akron'. The trick is, my code doesn't know beforehand what terms will be in the query. The query is formed on the fly depending on what search terms the user wants to use. In Perl that's easy. In PHP I'm not sure what to do. Asked another way: how can I dynamically form and pass a list of values in PHP?

What I'm used to doing in Perl:

my %terms = (
    'first_name' => 'Bob',
    'last_name' => 'Smith',
    'city' => 'Akron'
);

my @keys = keys %terms;
my $where_string = join(' AND ', map("$_ = ?", @keys));
my @values = @terms{@keys};

my $sql = "SELECT * FROM my_table WHERE $where_string";
# Should give me 'SELECT * FROM my_table WHERE first_name = ? AND last_name = ? AND city = ?'
my $sth = $dbh->prepare($sql);
$sth->execute(@values);

What I'm trying to do in PHP that doesn't work:

foreach ($terms as $key => $value) {
    $keys[] = "$key = ?";
    $values[] = $value;
    $types .= (is_numeric($value) ? "i" : "s");
}
$where_string = implode(' AND ', $keys);
$sql = "SELECT * FROM my_table WHERE $where_string";
$sth = $dbh->prepare($sql);
$sth->bind_param($types, $values);  # Only I need to pass @values,
                                    #   the list of the elements of the array,
                                    #   not a reference to the array
$result = $sth->execute();

It could be my brain is so Perl-addled that I've forgotten all common sense.

like image 316
Joseph T. Richardson Avatar asked Jan 15 '14 20:01

Joseph T. Richardson


1 Answers

What you probably want is call_user_func_array():

$args = array_merge( array( $types ), $refs_to_values );
call_user_func_array( array( $sth, 'bind_param' ), $args );

Yes, it's kind of ugly; sometimes the flexibility of Perl is an advantage.

like image 90
Ilmari Karonen Avatar answered Sep 18 '22 17:09

Ilmari Karonen