将 PHP PDO 迁移到 Laravel PDO 会导致参数编号无效
Migrating PHP PDO to Laravel PDO causes Invalid parameter number
我正在将 PHP PDO 实例转换为 Laravel 5.5。我更改了数据库连接 from/to:
//$dbc = new PDO ('mysql:host='. $DB_HOST .';dbname='. $DB_NAME, $DB_USER, $DB_PASS);
$dbc = \Illuminate\Support\Facades\DB::connection('foobardb')->getPdo();
出于某种原因,这导致我的 SELECT 查询失败。
$query = "SELECT *
FROM foobartable
WHERE date_created > :sunday
AND date_created <= :monday
AND date_updated > :sunday
AND date_updated <= :monday";
$stmt = $dbc->prepare($query);
$stmt->bindValue(':monday', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday', $sunday, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
根据堆栈跟踪,该错误专门在 $stmt->execute();
上触发
SQLSTATE[HY093]: Invalid parameter number
我显然有 ,使用 PHP 的 PDO 实例效果很好,那么为什么它不适用于 Laravel?
出于某种原因,Laravel 个连接不会自动使用 PDO::ATTR_EMULATE_PREPARES
。即使一个mysql连接。只需在连接数组中添加选项即可解决此问题。
'foobardb' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => 'foobardb',
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
//add addition options here
'options' => [PDO::ATTR_EMULATE_PREPARES => true]
],
不知道是不是只限于Laravel 5.5,还是说之前的版本也需要加入这个选项
解决此问题的另一种方法是执行以下操作:
$query = "SELECT *
FROM foobartable
WHERE date_created > :sunday
AND date_created <= :monday
AND date_updated > :sunday2
AND date_updated <= :monday2";
然后:
$stmt->bindValue(':monday', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday', $sunday, PDO::PARAM_STR);
$stmt->bindValue(':monday2', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday2', $sunday, PDO::PARAM_STR);
因此它认为您拥有的 PDO 令牌数量与您拥有的 bindValues 数量相同。
我正在将 PHP PDO 实例转换为 Laravel 5.5。我更改了数据库连接 from/to:
//$dbc = new PDO ('mysql:host='. $DB_HOST .';dbname='. $DB_NAME, $DB_USER, $DB_PASS);
$dbc = \Illuminate\Support\Facades\DB::connection('foobardb')->getPdo();
出于某种原因,这导致我的 SELECT 查询失败。
$query = "SELECT *
FROM foobartable
WHERE date_created > :sunday
AND date_created <= :monday
AND date_updated > :sunday
AND date_updated <= :monday";
$stmt = $dbc->prepare($query);
$stmt->bindValue(':monday', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday', $sunday, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
根据堆栈跟踪,该错误专门在 $stmt->execute();
SQLSTATE[HY093]: Invalid parameter number
我显然有
出于某种原因,Laravel 个连接不会自动使用 PDO::ATTR_EMULATE_PREPARES
。即使一个mysql连接。只需在连接数组中添加选项即可解决此问题。
'foobardb' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => 'foobardb',
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
//add addition options here
'options' => [PDO::ATTR_EMULATE_PREPARES => true]
],
不知道是不是只限于Laravel 5.5,还是说之前的版本也需要加入这个选项
解决此问题的另一种方法是执行以下操作:
$query = "SELECT *
FROM foobartable
WHERE date_created > :sunday
AND date_created <= :monday
AND date_updated > :sunday2
AND date_updated <= :monday2";
然后:
$stmt->bindValue(':monday', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday', $sunday, PDO::PARAM_STR);
$stmt->bindValue(':monday2', $monday, PDO::PARAM_STR);
$stmt->bindValue(':sunday2', $sunday, PDO::PARAM_STR);
因此它认为您拥有的 PDO 令牌数量与您拥有的 bindValues 数量相同。