sql >> データベース >  >> RDS >> Mysql

PHPMysqlPDOのバインドされた変数の数がトークンの数と一致しません

    マークベイカーはすでにあなたの質問に答えているようですが、私は私を大いに助けてくれたいくつかのヒントを追加したいと思いました。

    PDOはmysql_escape_stringを必要としません
    ユーザー入力を処理するクエリに入るすべてがプリペアドステートメントを使用している限り(上記のように)、mysql_real_escape_stringで入力をエスケープする必要はありません。 [1]。

    // Don't worry about SQL injection since all of the user 
    // defined inputs are being escaped by the PDO package
    $sql = "INSERT INTO "
         .   "`users` "
         . "SET "
         .   "`name` = :name";
    
    $query = $pdo->prepare($sql);
    $query->bindParam(':name', $name);
    $query->execute();
    

    ただし、ユーザー入力をバインドしていない場合でもSQLインジェクションが可能であることに注意してください:

    // SQL injection can totally happen here
    $sql = "INSERT INTO "
         .   "`users` "
         . "SET "
         .   "`name` = $name";
    
    $query = $pdo->prepare($sql);
    $query->execute();
    

    [1] http://www.php.net/manual/ en / pdo.prepared-statements.php




    SQLをできるだけ短くするようにしてください
    単純なSQLステートメントの場合、短いほど保守が容易になり、間違いを犯しにくくなります。別のINSERT構文を使用できます[2]:

    INSERT INTO 
      `users`
    SET
      `name` = 'Steve';
    

    と同等です:

    INSERT INTO 
      `users`
      (
        `name`
      )
      VALUES
      (
        'Steve'
      );
    

    つまり、あなたのような大きな声明の場合、効果的に半分 すべての列名を繰り返す必要がないため、そのサイズ:

    $sql  = "INSERT INTO "
          .   "`records_rec` "
          . "SET "
          .   "`oldid_rec`       = :oldid_rec, "
          .   "`firstname_rec`   = :firstname_rec, " 
          .   "`artist_rec`      = :artist_rec, " 
          .   "`aside_rec`       = :aside_rec, "
          .   "`bside_rec`       = :bside_rec, "
          .   "`label_rec`       = :label_rec, "
          .   "`condition_rec`   = :condition_rec, " 
          .   "`genere_rec`      = :genere_rec, "
          .   "`price_rec`       = :price_rec, "
          .   "`collection_rec`  = :collection_rec, "
          .   "`active_rec`      = :active_rec, "
          .   "`info_rec`        = :info_rec, "
          .   "`notes_rec`       = :notes_rec, "
          .   "`order_rec`       = :order_rec, "
          .   "`alabelimage_rec` = :alabelimage_rec, "
          .   "`blabelimage_rec` = :blabelimage_rec, "
          .   "`asound_rec`      = :asound_rec, "
          .   "`bsound_rec`      = :bsound_rec, "
          .   "`featured_rec`    = :featured_rec, "
          .   "`format_rec`      = :format_rec";
    
    $dbh = new PDO(<info goes here>);
    $stmt = $dbh->prepare($sql); 
    
    // Bind your params here...
    

    [2] http://dev.mysql.com/doc/ refman / 5.5 / en / insert.html




    SQLステートメントを複数行できれいにする

    私はSQLステートメントを(上記のように)複数行になるようにフォーマットし始めましたが、それ以来、このようなエラーははるかに少なくなっています。 します かなりのスペースを取りますが、最終的にはそれだけの価値があると思います。すべてを揃えることで、親指のようにエラーが目立つようになります。

    ハッピーコーディング!



    1. pg_trgmを使用したPostgresの類似関数

    2. PHP、php変数によるSQL制限クエリ

    3. CodeIgniter Select Query

    4. SQLSELECTステートメント