downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

mysqli::query> <mysqli::poll
Last updated: Fri, 13 Nov 2009

view this page in

mysqli::prepare

mysqli_prepare

(PHP 5)

mysqli::prepare -- mysqli_prepare実行するための SQL ステートメントを準備する

説明

オブジェクト指向型(メソッド)

mysqli_stmt mysqli::prepare ( string $query )

手続き型:

mysqli_stmt mysqli_prepare ( mysqli $link , string $query )

null で終わる文字列から SQL クエリを準備し、後でそのステートメントを操作するために使用する ステートメントハンドルを返します。 クエリは、単一の SQL 文である必要があります。

パラメータマーカは、ステートメントの実行や行の取得の前に mysqli_stmt_bind_param()mysqli_stmt_bind_result() を使用して アプリケーション変数にバインドする必要があります。

パラメータ

link

手続き型のみ: mysqli_connect() あるいは mysqli_init() が返すリンク ID。

query

クエリを表す文字列。

注意: ステートメントの最後にセミコロンや \g を追加してはいけません。

query にはひとつまたは複数のパラメータを 含めることが可能です。そのためには、適切な位置にクエスチョンマーク (?) を埋め込みます。

注意: パラメータのマーカは、それが SQL 文の適切な位置にある場合のみ有効です。 例えば INSERT 文の VALUES() リストの中 (行に登録するカラム値を指定する) や WHERE 句で列のデータと比較する値などが 適切な位置の例です。
しかし、識別子 (テーブルやカラムの名前) や SELECT 文で選択する項目の名前に指定したり、 (等号 = のような) 二項演算子の両側にパラメータを指定したりすることはできません。 後者の制限は、パラメータの型が判断できなくなることによるものです。 また、パラメータのマーカを NULL と比較して ? IS NULL のようにすることもできません。 一般に、パラメータが使用可能なのはデータ操作言語 (DML) ステートメントであり、データ定義言語 (DDL) ステートメントでは使用できません。

返り値

mysqli_prepare() はステートメントオブジェクトを返します。 エラー時には FALSE を返します。

例1 オブジェクト指向型

<?php
$mysqli 
= new mysqli("localhost""my_user""my_password""world");

/* 接続状況をチェックします */
if (mysqli_connect_errno()) {
    
printf("Connect failed: %s\n"mysqli_connect_error());
    exit();
}

$city "Amersfoort";

/* プリペアドステートメントを作成します */
if ($stmt $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

    
/* マーカにパラメータをバインドします */
    
$stmt->bind_param("s"$city);

    
/* クエリを実行します */
    
$stmt->execute();

    
/* 結果変数をバインドします */
    
$stmt->bind_result($district);

    
/* 値を取得します */
    
$stmt->fetch();

    
printf("%s is in district %s\n"$city$district);

    
/* ステートメントを閉じます */
    
$stmt->close();
}

/* 接続を閉じます */
$mysqli->close();
?>

例2 手続き型

<?php
$link 
mysqli_connect("localhost""my_user""my_password""world");

/* 接続状況をチェックします */
if (mysqli_connect_errno()) {
    
printf("Connect failed: %s\n"mysqli_connect_error());
    exit();
}

$city "Amersfoort";

/* プリペアドステートメントを作成します */
if ($stmt mysqli_prepare($link"SELECT District FROM City WHERE Name=?")) {

    
/* マーカにパラメータをバインドします */
    
mysqli_stmt_bind_param($stmt"s"$city);

    
/* クエリを実行します */
    
mysqli_stmt_execute($stmt);

    
/* 結果変数をバインドします */
    
mysqli_stmt_bind_result($stmt$district);

    
/* 値を取得します */
    
mysqli_stmt_fetch($stmt);

    
printf("%s is in district %s\n"$city$district);

    
/* ステートメントを閉じます */
    
mysqli_stmt_close($stmt);
}

/* 接続を閉じます */
mysqli_close($link);
?>

上の例の出力は以下となります。

Amersfoort is in district Utrecht

参考



mysqli::query> <mysqli::poll
Last updated: Fri, 13 Nov 2009
 
add a note add a note User Contributed Notes
mysqli::prepare
sdepouw at NOSPAM dot com
30-Jul-2009 01:03
I don't know how obvious this was for anyone else, but if you attempt to prepare a query for a table that doesn't exist in the database the connection currently points to (or if your query is invalid in some other way, I suppose), an object will not be returned. I only noticed this after doing some digging when I kept getting a fatal error saying that my statement variable was not an set to an instance of an object (it was probably null).

Replace NOSPAM with nimblepros to e-mail me.
rafael at stiod dot com
29-Sep-2008 11:44
All data must be fetched before a new statement prepare
admin at xorath dot com
15-Aug-2007 05:39
Performance note to those who wonder. I performed a test where first of all inserted about 30,000 posts with one PK:id and a varchar(20), where the varchar data was md5-hash for the current iterator value just to fill with some data.

The test was performed on a dedicated ubuntu 7.04 server with apache2/php5/mysql5.0 running on Athlon 64 - 3000+ with 512MB of RAM. The queries where tested with a for-loop from 0 to 30000 first with:

<?php
for ( $i = 0; $i <= 30000; ++$i )
{
   
$result = $mysqli->query("SELECT * FROM test WHERE id = $i");
   
$row = $result->fetch_row();
    echo
$row[0]; //prints id
}
?>

which gave a page-load time of about 3.3seconds avarage, then with this loop:

<?php
$stmt
= $mysqli->prepare("SELECT * FROM test WHERE id = ?");
for (
$i = 0; $i <= 30000; ++$i )
{
   
$stmt->bind_param("i", $i);
   
$stmt->execute();
   
$stmt->bind_result($id, $md5);
   
$stmt->fetch();
    echo
$id;
}
$stmt->close();
?>

and the avarage page-load was lowered by 1.3sec, which means about 2.0 sec avarage! Guess the performance difference could be even greater on a more complex/larger table and more complex SQL-queries.
nom0ny at yahoo dot com
25-May-2007 07:30
It must be noted in the Description whether developers should call mysqli_stmt_close prior to executing mysqli_prepare again on the same statement variable.

Example, Script A calls mysqli_stmt_close twice:
<?php
/* Script A -- We are already connected to the database */

$stmt = mysqli_prepare($link, "INSERT INTO table VALUES (?, ?, 100)"); /* Query 1 */
mysqli_stmt_bind_param($stmt, "si", $string, $integer);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt

$stmt = mysqli_prepare($link, "INSERT INTO table VALUES ('PHP', ?, ?)"); /* Query 2 */
mysqli_stmt_bind_param($stmt, "ii", $integer, $code);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt

/* Script A -- Continues on... */
?>

Next, we have Script B, calling mysqli_prepare again before issuing mysqli_stmt_close on the prior statement.
<?php
/* Script B -- We are already connected to the database */

$stmt = mysqli_prepare($link, "INSERT INTO table VALUES (?, ?, 100)"); /* Query 1 */
mysqli_stmt_bind_param($stmt, "si", $string, $integer);
mysqli_stmt_execute($stmt);

$stmt = mysqli_prepare($link, "INSERT INTO table VALUES ('PHP', ?, ?)"); /* Query 2 */
mysqli_stmt_bind_param($stmt, "ii", $integer, $code);
mysqli_stmt_execute($stmt);

mysqli_stmt_close($stmt); // CLOSE $stmt

/* Script B -- Continues on... */
?>

Which method is more efficient and should be used by developers?
Adam
10-Aug-2006 10:03
The purpose of prepared statements is to not include data in your SQL statements. Including them in your SQL statements is NOT safe. Always use prepared statements. They are cleaner to use (code easier to read) and not prone to SQL injections.

Escaping strings to include in SQL statements doesn't work very well in some locales hence it is not safe.
codeFiend <aeontech at gmail dot com>
05-May-2006 09:47
Note that single-quotes around the parameter markers _will_ prevent your statement from being prepared correctly.
Ex:

<?php
$stmt
= $mysqli->prepare("INSERT INTO City (District) VALUES ('?')");
echo
$stmt->param_count." parameters\n";
?>
will print 0 and fail with "Number of variables doesn't match number of parameters in prepared statement" warning when you try to bind the variables to it.

But

<?php
$stmt
= $mysqli->prepare("INSERT INTO City (District) VALUES (?)");
echo
$stmt->param_count." parameters\n";
?>
will print 1 and function correctly.

Very annoying, took me an hour to figure this out.
Ulf Wostner
23-Jan-2006 04:53
Here is an example using bind_param and bind_result, showing iteration over a list of cities.

Note that there's some bug-potential in cases where the query returns NULL for some parameter value,
but the bind_result variables still might be bound.  So, we use a conditional to spray the spot first.

$mysqli->select_db("world");

$template = "SELECT District, CountryCode FROM City WHERE Name=?";
printf("Prepare statement from template: %s\n",  $template);

$cities = array('San Francisco', 'Lisbon', 'Lisboa', 'Marrakech', 'Madrid');
printf("Cities: %s\n", join(':', $cities));

if ($stmt = $mysqli->prepare($template)) {

   foreach($cities as $city) {
     // bind the string $city to the '?'
     $stmt->bind_param("s", $city);
     $stmt->execute();
     // bind result variables
     $stmt->bind_result($d,$cc);
     // 'Lisbon' is not found in the world.City table, but 'Lisboa' is.
     // Using a conditional we avoid putting Lisbon in California.
     if($stmt->fetch()) {
       printf("%s is in  %s, %s\n", $city, $d, $cc);
     }

   }
   $stmt->close();
}

With the conditional statement we get the desired result:

Prepare statement from template: SELECT District,CountryCode FROM City WHERE Name=?
Cities: San Francisco:Lisbon:Lisboa:Marrakech:Madrid

San Francisco is in  California, USA
Lisboa is in  Lisboa, PRT
Marrakech is in  Marrakech-Tensift-Al, MAR
Madrid is in  Madrid, ESP

But, without the conditional statement we would put Lisbon in California:

San Francisco is in  California, USA
Lisbon is in  California, USA
Lisboa is in  Lisboa, PRT
Marrakech is in  Marrakech-Tensift-Al, MAR
Madrid is in  Madrid, ESP
David Kramer
20-Dec-2005 08:50
I don't think these are good examples, because the primary use of prepared queries is when you are going to call the same query in a loop, plugging in different values each time.  For instance, if you were generating a report and needed to run the same query for each line, tweaking the values in the WHERE clause, or importing data from another system.

mysqli::query> <mysqli::poll
Last updated: Fri, 13 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites