2014-01-15 2 views
5

私はPerlでの作業に慣れていた方法がPHPではうまくいかないので、私は壁に頭を打っています。これは、基本的なことなので、私は適切に質問する方法がわかりません。要点:Perlの関数への引数としてリストコンテキストで配列を送るのに慣れていますが、PHPでは配列への参照だけを渡しています。PHPで(Perlのように)配列の参照ではなく、値リストを渡したい場合

私はMySQLiを使用してPHPで基本的なSQLクエリを作成しようとしています(例えば、SELECT * FROM my_table WHERE first_name = 'Bob' AND last_name = 'Smith' AND city = 'Akron')。トリックは、私のコードは、どのような用語がクエリに含まれるかを事前には知りません。クエリは、ユーザが使用したい検索語に応じてオンザフライで形成される。 Perlで簡単です。 PHPでは何をすべきかわかりません。言い換えれば、PHPで動的にフォームを作成して値のリストを渡すにはどうすればいいですか?

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

は、それが動作しません私はPHPでやろうとしている:

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

は、それは私の脳はそうであるかもしれません私はすべての常識を忘れてしまったとパールは付け加えました。あなたはおそらく欲しい

+0

いつもmysqliにはDBD :: mysqlがなくても生きることができるのに対し、なぜタイプが必要なのですか? –

+0

私もそうです。この全試練は、私がなぜPHPを使っているのか不思議に思います。 (回答:どのようにすればよいか分かります) – LonelyPilgrim

+0

あなたのコードはSQLインジェクションに対して脆弱であり、できるだけ実行可能ではないことに気付きたいと思います。プレースホルダを使用し、実行する変数を渡すことで、両方を修正できます。 –

答えて

5

call_user_func_array()です:

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

はい、それは一種の醜いです。時にはPerlの柔軟性が利点です。

+0

おそらく醜さを隠すためにmysqliのサブクラス化。 –

+0

ありがとう!それは結局私をそこに連れて行った。 mysqli_stmt :: bind_paramは非常に具体的には値と一連の参照を想定しているので、少し微調整が必​​要でした。これはうまくいきました: – LonelyPilgrim

+0

$ args [] = $ types; ($ i = 0; $ i <カウント($値); $ i ++){ $ args [] =&$ values [$ i]; } call_user_func_array(配列($ sth、 'bind_param')、$ args); – LonelyPilgrim