11

PHPでは、フィールドと値のペアの連想配列に含まれるデータを使用してデータベースに挿入したいと思います。

例:

$_fields = array('field1'=>'value1','field2'=>'value2','field3'=>'value3');

結果のSQL挿入は次のようになります。

INSERT INTO table (field1,field2,field3) VALUES ('value1','value2','value3');

私は次のPHPワンライナーを思いついた:

mysql_query("INSERT INTO table (".implode(',',array_keys($_fields)).") VALUES (".implode(',',array_values($_fields)).")");

連想配列のキーと値をimplodes区切り、コンマ区切りの文字列を生成します。問題は、データベースに挿入された値をエスケープまたは引用符で囲まないことです。$_fields危険性を説明するために、次のものが含まれていると想像してください。

$_fields = array('field1'=>"naustyvalue); drop table members; --");

次のSQLが生成されます。

INSERT INTO table (field1) VALUES (naustyvalue); drop table members; --;

幸い、複数のクエリはサポートされていませんが、SQLインジェクションの脆弱性を防ぐには、引用符とエスケープが不可欠です。

PHP Mysqlインサートをどのように記述しますか?

注:コードベースはすでにmysqlを広範囲に使用しているため、PDOまたはmysqliで準備されたクエリは現在のところオプションではありません-変更が計画されていますが、変換するには多くのリソースが必要ですか?

4

7 に答える 7

22

私が変更する唯一のことは、読みやすさの目的でsprintfを使用することです

$sql = sprintf(
    'INSERT INTO table (%s) VALUES ("%s")',
    implode(',',array_keys($_fields)),
    implode('","',array_values($_fields))
);
mysql_query($sql);

値がエスケープされていることを確認してください。

于 2009-11-16T19:12:04.310 に答える
3

それは何も悪いことではありません。私も同じです。

ただし、必ずmysql_escape()クエリに固定する値を引用してください。引用しないと、SQLインジェクションの脆弱性が発生します。

または、パラメータ化されたクエリを使用することもできます。その場合、クエリ文字列を作成する代わりに、配列自体を実際に渡すことができます。

于 2009-11-16T19:08:09.203 に答える
1

ベストプラクティスは、ORM(Doctrine 2.0)、ActiveRecord実装(Doctrine 1.0、RedBean)、またはTableGatewayパターン実装(Zend_Db_Table、Propel)のいずれかを使用することです。これらのツールは、あなたの生活をはるかに楽にし、あなたのために多くの重労働を処理し、SQLインジェクションからあなたを保護するのに役立ちます。

それ以外は、実行していることに本質的に問題はありません。クラスまたは関数に抽象化して、さまざまな場所で機能を繰り返すことができるようにすることができます。

于 2009-11-16T19:08:26.830 に答える
0

以前の回答でGalenが言及したsprintfトリックを使用して、次のコードを考え出しました。

$escapedfieldValues = array_map(create_function('$e', 'return mysql_real_escape_string(((get_magic_quotes_gpc()) ? stripslashes($e) : $e));'), array_values($_fields));

$sql = sprintf('INSERT INTO table (%s) VALUES ("%s")', implode(',',array_keys($_fields)), implode('","    ',$escapedfieldValues));

mysql_query($sql);

エスケープおよび引用符で囲まれた挿入を生成します。また、magic_quotes_gpcオンかオフかに関係なく対応します。新しいPHPv5.3.0無名関数を使用した場合、コードはより適切になる可能性がありますが、古いPHPインストールで実行する必要があります。

このコードは元のコードより少し長い(そして遅い)が、より安全である。

于 2009-11-17T17:58:54.520 に答える
0

これを使用して、INSERTのVALUES部分を取得します。しかし、それは物事を行うためのばかげた方法かもしれません。コメント/提案は大歓迎です。

   function arrayToSqlValues($array)
   {
      $sql = "";
      foreach($array as $val)
      {    
         //adding value
         if($val === NULL)
            $sql .= "NULL";
         else
            /*
            useless piece of code see comments
            if($val === FALSE)
               $sql .= "FALSE";
            else
            */
               $sql .= "'" . addslashes($val) . "'";

         $sql .= ", ";
      };

      return "VALUES(" . rtrim($sql, " ,") . ")";
   }
于 2010-03-24T18:41:01.287 に答える
0

(受け入れられた回答の)NULL値が空の文字列""に変換されるという問題があります。したがって、これは修正され、NULLは引用符なしでNULLになります。

function implode_sql_values($vals)
{
    $s = '';
    foreach ($vals as $v)
        $s .= ','.(($v===NULL)?'NULL':'"'.mysql_real_escape_string($v).'"');

    return substr($s, 1);
}

使用法:

implode_sql_values(array_values( array('id'=>1, 'nick'=>'bla', 'fbid'=>NULL) ));
// =='"1","bla",NULL'
于 2012-12-06T13:43:06.130 に答える
0

アプローチを強化し、入力の検証とサニテーションの可能性を追加したい場合は、次のようにすることができます。

function insertarray($table, $arr){
   foreach($arr as $k => $v){
      $col[] = sanitize($k);
      $val[] = "'".sanitize($v)."'";
   }

   query('INSERT INTO '.sanitize($table).' ('.implode(', ', $col).') VALUES ('.implode(', ', $val).')' );
}
于 2016-08-04T11:30:54.943 に答える