PDOStatement::execute() always converts all arguments to string as shown in the latest php 8.2.0 RC3 source:
https://github.com/php/php-src/blob/615b8006c42715b5ea9ec61f9368582eeef8467f/ext/pdo/pdo_stmt.c#L411-L425
So what actually happens, is that the whole array values are converted to string which causes the SQL statement to fail.
$statement = $pdo->prepare('INSERT INTO `test` (SomeText, TestBool) VALUES (?, ?)'); $statement->execute([ 'TEST', false, // converted to string ]);
It can be fixed using PDOStatement::bindValue() as bind value allows to set the argument type.
$statement = $pdo->prepare('INSERT INTO `test` (SomeText, TestBool) VALUES (?, ?)'); $statement->bindValue('SomeText', 'TEST', PDO::PARAM_STR); $statement->bindValue('TestBool', false, PDO::PARAM_BOOL); $statement->execute();
As manual binding is cumbersome, libraries such as Nette make the process much easier as shown in the sample below:
$database = new Nette\Database\Connection("mysql:host={$params['host']};dbname={$params['database']};charset=utf8", $params['user'], $params['pass']); $staff = [ [ 'birthday' => new DateTime('1995-05-01'), 'name' => 'Sharon', 'salary' => '200', 'management' => true, ], ]; $database->query('INSERT INTO test', $staff);
OLD ANSWER:
Obviously, it's more cumbersome than passing the array to execute that's why I created a quick and dirty helper to simplify the task.
Note: As mentioned in the comments, do not use it on not validated user input as it can cause havoc with queries like:
$sql = <<<SQL DELETE FROM table WHERE email = :email SQL;
:email is meant to be a string, but if instead false is passed, it will delete all emails from the table.
$values = [ 'SomeTest' => 'TEST', 'testBool' => false, ]; bind($query, $values)->execute(); /** * Variable to PDO type * * @param mixed $value * * @return int PDO type */ function typeToParam(mixed $value) : int { switch ($type = gettype($value)) { case 'boolean': return PDO::PARAM_BOOL; case 'integer': return PDO::PARAM_INT; case 'NULL': return PDO::PARAM_NULL; case 'string': return PDO::PARAM_STR; default: throw new Exception("unsupported type - {$type}"); } } /** * Bind values to PDO statement * * @param PDOStatement $statement * @param array $data * * @return PDOStatement */ function bind(PDOStatement $statement, array $data) : PDOStatement { foreach ($data as $key => $value) { $statement->bindValue($key, $value, typeToParam($value)); } return $statement; }