web-dev-qa-db-ja.com

MySQLのinsertステートメント内にPHP変数を含める方法

目次に値を挿入しようとしています。 VALUES内にPHP変数がない場合は正常に動作します。変数$typeをVALUESに入れると、これは機能しません。私は何を間違えていますか?

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')");
45
Pinkie

クエリに文字列を追加するルールは単純明快です。

  1. 文字列は引用符で囲む必要があります。
  2. したがって、これらの引用符は、mysql_real_escape_string()を使用して、データおよび他の文字でエスケープする必要があります

だから、あなたのコードは

$type     = 'testing';
$type     = mysql_real_escape_string($type);
$reporter = "John O'Hara";
$reporter = mysql_real_escape_string($reporter);

$query    = "INSERT INTO contents (type, reporter, description) 
             VALUES('$type', '$reporter', 'whatever')";
mysql_query($query) or trigger_error(mysql_error()." in ".$query);
// note that when running mysql_query you have to always check for errors

ただし、クエリの別の部分に変数を追加する場合は、ルールが変更されます。

  • 数値を追加するには、明示的にその型にキャストする必要があります。

例えば:

$limit = intval($_GET['limit']); //casting to int type!
$query = "SELECT * FROM table LIMIT $limit";
  • 識別子を追加するには、何らかの種類のホワイトリストから選択することをお勧めします。これはハードコードされた値で構成されます

例えば:

if ($_GET['sortorder'] == 'name') {
  $sortorder = 'name';
} else {
  $sortorder = 'id';
}
$query = "SELECT * FROM table ORDER BY $sortorder";

すべてを単純化するため、安全性を保証するには、何らかのプレースホルダーシステムを使用する必要がありますここで、変数は直接ではなく、プレースホルダーと呼ばれるプロキシ経由でクエリに入力されます。

したがって、クエリ呼び出しは次のようになります。

$type     = 'testing';
$reporter = "John O'Hara";
pquery("INSERT INTO contents (type, reporter, description) VALUES(?s, ?s, ?s)",
        $type, $reporter,'whatever');

そして、これらすべての問題を心配する必要はまったくありません。

プレースホルダーの限定セットでは、 PDO を使用できます。実際の使用には、いくつかのライブラリで提供される拡張セットが必要ですが、そのうちの1つは SafeMysql です。

85

文字列である限り-引用符で囲む必要があります

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

そして、はい、ダニが助言したように:mysql_real_escape_string()でクエリに入れたevery文字列をサニタイズする必要があります

7
zerkms

それは簡単な答えです:

$query="SELECT * FROM CountryInfo WHERE Name = '".$name."'";

$nameを自由に定義します。
別の方法、複雑な方法は次のとおりです。

$query = " SELECT '" . $GLOBALS['Name'] . "' .* " .
         " FROM CountryInfo " .
         " INNER JOIN District " .
         " ON District.CountryInfoId = CountryInfo.CountryInfoId " .
         " INNER JOIN City " .
         " ON City.DistrictId = District.DistrictId " .
         " INNER JOIN '" . $GLOBALS['Name'] . "' " .
         " ON '" . $GLOBALS['Name'] . "'.CityId = City.CityId " .
         " WHERE CountryInfo.Name = '" . $GLOBALS['CountryName'] .
         "'";
3
Baloomba

$ type内のテキストは挿入文字列に直接置換されるため、MySQLは次のようになります。

... VALUES(testing, 'john', 'whatever')

テストの周りに引用符がないことに注意してください。次のように入力する必要があります。

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

SQLインジェクション を読むこともお勧めします。使用しているデータをサニタイズしないと、この種のパラメーターの受け渡しがハッキングの試みになりやすいためです。

3
Spencer Rose

これを試して:

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

$ typeだけでなく'$type'を置く必要があります

2
Chris Ghenea

変数に信頼できないユーザー入力またはその他のデータが含まれている場合は、必ずデータをエスケープしてください。このような:

$query = sprintf("INSERT INTO contents (type) VALUES ('%s')", mysql_real_escape_string($type));
$result = mysql_query($query);
1
Harri

ここに

$type='testing' //it's string

mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");//at that time u can use it(for string)


$type=12 //it's integer
mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')");//at that time u can use $type
1
user962293

この質問にはいくつかの答えがあったことは知っていますが、次の構文に従えば、エラーの問題は二度とないと思います。どのテーブルを使用していて、どの列を追加しているのかは疑いありません。

$query    = "INSERT INTO contents (type, reporter, description) 
         VALUES('".$type."', '".$reporter."', '"$whatever."')";
1
villeguy

sQLインジェクションを回避するには、insert文をbe

$type = 'testing';

$stmt = $con->prepare("INSERT INTO   contents (type, reporter, description) VALUES (?, ?, ?)");
         $stmt->bind_param("sss", $type , 'john', 'whatever');
         $stmt->execute();
    $stmt->close();
0
Stefan

最良のオプションは準備されたステートメントです。引用符とエスケープをいじるのは、最初から難しい作業であり、維持するのが困難です。遅かれ早かれ、何かを引用するのを誤って忘れたり、同じ文字列を2回エスケープしたり、そのようなものを台無しにしたりすることになります。これらのタイプのバグを見つけるまでに数年かかるかもしれません。

http://php.net/manual/en/pdo.prepared-statements.php

0
Tel

変数を一重引用符または二重引用符で囲み、次に中かっこで囲み、次に変数名(例:$ abc)で囲みます。

例:

SELECT * FROM log WHERE id = '{$id}';
0
Astjan Selimaj