これを行う関数があります:
function registerUser($firstName, $lastName, $address, $postcode, $email, $password)
{
$params = array($firstName, $lastName, $address, $postcode, $email, $password);
$result = $this->db->bind("INSERT INTO Users VALUES (?, ?, ?, ?, ?, ?)", 'ssssss', $params);
}
これは私のデータベースクラスに送信され、これはこれを行います:
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, $param);
$stmt->execute;
}
問題は、これが機能しないことです。
私が望んでいたことは、$params
リストを取得し、$type
の後にそれらをリストして、クエリが次のようになるようにすることでした。
$stmt->bind_param('ssssss', $firstName, $lastName, $address, $postcode, $email, $password);
しかし、明らかに私はそれを間違った方法で行っています。
配列を...bind_param
クエリステージで出力されるリストに変換する方法はありますか?
call_user_func_array "パラメータの配列でコールバックを呼び出します"
call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params));
仕事をすべき
[〜#〜] update [〜#〜]:params配列も変更する必要があります:
$params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password);
なので mysqli_stmt::bind_param
は、参照によって2番目以降のパラメーターを想定しています。
編集:あなたのクエリは間違っているようです。たぶん、あなたはそこにある変数よりもフィールドが少ないでしょう。行う:
"INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)"
フィールドの名前を正しい名前に置き換えます
PHP 5.6以降では、call_user_func_arrayの代わりに引数のアンパックを使用でき、多くの場合3〜4倍高速です。
<?php
function foo ($a, $b) {
return $a + $b;
}
$func = 'foo';
$values = array(1, 2);
call_user_func_array($func, $values);
//returns 3
$func(...$values);
//returns 3
?>
here から取得。
したがって、コードは次のようになります。
public function bind($query, $type, $params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
$stmt->bind_param($type, ...$params);
$stmt->execute;
}
$ this-> mysqli-> prepareでなんらかのエラーが発生するため、「非オブジェクトでメンバー関数bind_param()を呼び出す」というエラーが発生する可能性が高くなります。 ( http://php.net/manual/de/mysqli.prepare.php)を参照 -エラーの場合にFALSEを返します。
その問題を解決したら、$ stmt-> bind_paramを呼び出す代わりにこれを試してください。
call_user_func_array(array($stmt, 'bind_param'), array_merge($type, $params));
easiestの方法は明らかにmysqliから [〜#〜] pdo [〜#〜] に切り替わります
それはあなたがあなたが望む方法でそれをすることを可能にし、追加の機能なしでさえも:
function registerUser($firstName, $lastName, $address, $postcode, $email, $password)
{
$sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute(func_get_args());
}
今日、prepareステートメントを使用するより短い方法を作成するために、私はいくつか自分で調査しました。回答@bwoebiは非常に役立ちますが、不明な量のパラメーターに対しては機能しないため、これは彼の回答への追加です。
例えば:
public function bind($query, $type, &...$params)
{
$this->query = $query;
$stmt = $this->mysqli->prepare($this->query);
call_user_func_array(array($stmt, "bind_param"), array_merge([$type], $params));
$stmt->execute();
}
このスレッドを使用する: PHP:可変長引数リスト(参照)?
不明な量のパラメーターをクラス内のバインド関数に渡すことができました。次に、$ type変数の配列マージを使用して、call_user_func_array(...)を使用してbind param関数を呼び出します...(マージのために配列内に配置する必要があります)
これで、$ emailと$ passwordが参照されているこの関数を呼び出すことができます。
$myClass->bind($query, "ss", $email, $password);
mysqli_stmt_bind_param()
ではパラメーターを参照で渡す必要があるため、call_user_func_array()
のパラメーターは参照である必要があることに注意してください。クラスコンテキストからの例:
function execute( string $query, string $type, array $params )
{
if ( !$stmt = $this->mysqli->prepare( $query ) )
throw new \Exception( 'Prepare failed: ' . $query . PHP_EOL . $this->mysqli->error );
// call stmt->bind_param() with variables to bind passed as a reference
call_user_func_array(
array( $stmt, 'bind_param' ),
array_merge(
array( $type ),
array_map( function( &$item ) { return $item; }, $params )
)
);
if ( !$stmt->execute() )
throw new \Exception( 'Execute failed: ' . PHP_EOL . $stmt->error );
}
}