I’ve tried making a website which has a database connected to it and I’m getting the error message below
INSERT INTO Diák (oktatási_id, vezeték_név, kereszt_név, évfolyam, születési_dátum, város, utca, házszám, irányítószám, szak, kar)
values (:oktatási_id, :vezeték_név, :kereszt_név, :évfolyam, :születési_dátum, :város, :utca, :házszám, :irányítószám, :szak, :kar)
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
This is my PHP code that I have written below
<?php
require "../config.php";
require "../common.php";
if (isset($_POST['submit'])) {
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'])) die();
try {
$connection = new PDO($dsn, $username, $password, $options);
$new_user = array(
"oktatási_id" => $_POST['oktatási_id'],
"vezeték_név" => $_POST['vezeték_név'],
"kereszt_név" => $_POST['kereszt_név'],
"évfolyam" => $_POST['évfolyam'],
"születési_dátum" => $_POST['születési_dátum'],
"város" => $_POST['város'],
"utca" => $_POST['utca'],
"házszám" => $_POST['házszám'],
"irányítószám" => $_POST['irányítószám'],
"szak" => $_POST['szak'],
"kar" => $_POST['kar'],
);
$sql = sprintf(
"INSERT INTO %s (%s) values (%s)",
"Diák",
implode(", ", array_keys($new_user)),
":" . implode(", :", array_keys($new_user))
);
$statement = $connection->prepare($sql);
$statement->execute($new_user);
} catch(PDOException $error) {
echo $sql . "<br>" . $error->getMessage();
}
}
?>
<?php require "templates/header.php"; ?>
<?php if (isset($_POST['submit']) && $statement) : ?>
<blockquote><?php echo escape($_POST['kereszt_név']); ?> adatát sikeresen hozzá adtuk az adatbázishoz.</blockquote>
<?php endif; ?>
<h2>Felhasználó hozzáadása az adatbázishoz</h2>
<form method="post">
<input name="csrf" type="hidden" value="<?php echo escape($_SESSION['csrf']); ?>">
<label for="oktatási_id">oktatási_id</label>
<input type="text" name="oktatási_id" id="oktatási_id">
<label for="vezeték_név">Vezeték Név</label>
<input type="text" name="vezeték_név" id="vezeték_név">
<label for="kereszt_név">Kereszt Név</label>
<input type="text" name="kereszt_név" id="kereszt_név">
<label for="évfolyam">évfolyam</label>
<input type="text" name="évfolyam" id="évfolyam">
<label for="születési_dátum">Születési dátum</label>
<input type="date" name="születési_dátum" id="születési_dátum">
<label for="város">város</label>
<input type="text" name="város" id="város">
<label for="utca">utca</label>
<input type="text" name="utca" id="utca">
<label for="házszám">házszám</label>
<input type="text" name="házszám" id="házszám">
<label for="irányítószám">irányítószám</label>
<input type="text" name="irányítószám" id="irányítószám">
<label for="kar">kar</label>
<input type="text" name="kar" id="kar">
<label for="szak">szak</label>
<input type="text" name="szak" id="szak">
<input type="submit" name="submit" value="Submit">
</form>
<a href="index.php">Vissza a kezdő oldalra</a>
<?php require "templates/footer.php"; ?>
Advertisement
Answer
It took me a while to find, but I believe that PDO::prepare passes the named parameters through a regular expression [:][a-zA-Z0-9_]+
. https://github.com/php/php-src/blob/master/ext/pdo/pdo_sql_parser.re#L48. Your diacritic characters are being clobbered.
The only alternative that I know about it to use unnamed placeholders instead – ?
. Something like:
$sql = sprintf(
"INSERT INTO %s (%s) values (%s)",
"Diak",
implode(", ", array_keys($new_user)),
implode(', ', array_fill(0, sizeof($new_user), '?'))
);
Which will produce:
INSERT INTO Diák (oktatási_id, vezeték_név, kereszt_név, évfolyam, születési_dátum, város, utca, házszám, irányítószám, szak, kar) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
You’ll then have to change your execute method as follows:
$statement->execute(array_values($new_user));