sql >> Databáze >  >> RDS >> Mysql

Chyba vložení PHP/SQL při použití pojmenovaných zástupných symbolů

Vaše $userData musí mít přesně stejné zástupné symboly vázané vaším prohlášením, ne více ani méně. Viz PDOStatement::execute dokumentaci , část, která říká „Nemůžete svázat více hodnot, než je zadáno“.

Musíte připravit svůj argument na execute() aby přesně odpovídaly vašim vazbám. To je snadné pomocí array_intersect_key() pokud správně uspořádáte pole. Obvykle to zabalím do funkce, která se také postará o předponu, jako níže:

// Adds a prefix to a name for a named bind placeholder
function prefix($name) {
    return ':'.$name;
}

// like 'prefix()', but for array keys
function prefix_keys($assoc) {
    // prefix STRING keys
    // Numeric keys not included
    $newassoc = array();
    foreach ($assoc as $k=>$v) {
        if (is_string($k)) {
            $newassoc[prefix($k)] = $v;
        }
    }
    return $newassoc;
}

// given a map of datakeyname=>columnname, and a table name, returns an
// sql insert string with named bind placeholder parameters.
function makeInsertStmt($tablename, $namemap) {
    $binds = array_map('prefix', array_keys($namemap));
    return 'INSERT INTO '.$tablename.' ('.implode(',',$namemap).') VALUES ('
    .implode(',',$binds).')';
}

// returns an array formatted for an `execute()`
function makeBindData($data, $namemap) {
    // $data assoc array, $namemap name->column mapping
    return prefix_keys(array_intersect_key($data, $namemap));
}

// example to demonstrate how these pieces fit together
function RunTestInsert(PDO $pdo, $userData) {
    $tablename = 'UserDetails';
    // map "key in $userData" => "column name"
    // do not include ':' prefix in $userData
    $namemap = array(
      'firstName'       => "FirstName",
      'lastName'        => "LastName",
      'address'         => "Address",
      'city'            => "City",
      'county'          => "County",
      'postCode'        => "PostCode",
      'phone'           => "Phone",
      'mobile'          => "Mobile",
      'sex'             => "Sex",
      'DOB'             => "DOB",
      'fundraisingAim'  => "FundraisingAim",
      'weeksAim'        => "WeeksAim",
      'lengthsAim'      => "LengthsAim",
      'hearAbout'       => "HearAboutID",
      'motivation'      => "MotivationID",
      'welcomePackPref' => "WelcomePackID",
      'contactPref'     => "ContactPrefID",
      'title'           => "TitleID",
    );
    $sql = makeInsertStmt($tablename, $namemap);
    $binddata = makeBindData($userData, $namemap);

    $pstmt = $pdo->prepare($sql);
    $pstmt->execute($binddata);
}

Výhodou abstrakce, jako je tato, je, že se nemusíte starat o samotné parametry vazby.



  1. generovat prázdné řádky, i když jsou prázdné mezi 2 daty

  2. Jak nainstalovat SQL Server na Mac

  3. mysql vlastní globální definovaná proměnná

  4. MySQL přímé INSERT INTO s klauzulí WHERE