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));