我有以下架构:
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| someInt | int(11) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
当我运行以下脚本时,整数将作为字符串返回。
$pdo = new \PDO("mysql:host={$db['host']};dbname={$db['dbname']};charset={$db['charset']}",$db['username'],$db['password'],array(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION,\PDO::ATTR_DEFAULT_FETCH_MODE=>\PDO::FETCH_ASSOC));
var_dump($pdo->query('SELECT * FROM integerTesting')->fetchAll());
array(3) {
[0]=>
array(3) {
["id"]=>
string(1) "4"
["name"]=>
string(6) "Name 1"
["someInt"]=>
string(1) "1"
}
[1]=>
array(3) {
["id"]=>
string(1) "5"
["name"]=>
string(6) "Name 2"
["someInt"]=>
string(1) "2"
}
[2]=>
array(3) {
["id"]=>
string(1) "6"
["name"]=>
string(6) "Name 3"
["someInt"]=>
string(1) "3"
}
}
因此,我将 PDO::ATTR_EMULATE_PREPARES
更改为 FALSE
,并得到我正在寻找的结果:
$pdo = new \PDO("mysql:host={$db['host']};dbname={$db['dbname']};charset={$db['charset']}",$db['username'],$db['password'],array(\PDO::ATTR_EMULATE_PREPARES=>false,\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION,\PDO::ATTR_DEFAULT_FETCH_MODE=>\PDO::FETCH_ASSOC));
var_dump($pdo->query('SELECT * FROM integerTesting')->fetchAll());
array(3) {
[0]=>
array(3) {
["id"]=>
int(4)
["name"]=>
string(6) "Name 1"
["someInt"]=>
int(1)
}
[1]=>
array(3) {
["id"]=>
int(5)
["name"]=>
string(6) "Name 2"
["someInt"]=>
int(2)
}
[2]=>
array(3) {
["id"]=>
int(6)
["name"]=>
string(6) "Name 3"
["someInt"]=>
int(3)
}
}
我回答了我自己的问题吗?否,因为我的问题明确指出没有禁用 ATTR_EMULATE_PREPARES
。为什么这很重要?因为这样做显然会破坏。我原来的问题如下,但我知道这实际上并不是一个 Doctrine 问题,而是一个 PDO/MySQL 问题。
我有以下 Doctrine 实体:
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* @Entity @Table(name="integerTesting")
**/
class IntegerTesting
{
/**
* @var int
*
* @Column(type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(type="string") */
protected $name;
/**
* @var int
*
* @Column( type="integer")
*/
protected $someInt;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getSomeInt()
{
return $this->someInt;
}
public function setSomeInt($someInt)
{
$this->someInt = $someInt;
return $this;
}
}
我添加了几个或多个记录,然后使用 Doctrine 的 findAll() 方法以及直接 PDO 查询读取一些记录:
<?php
require_once "bootstrap.php";
function addRow(int $i, $entityManager):void {
$e = new IntegerTesting();
$e->setName("Name $i");
$e->setSomeInt($i);
$entityManager->persist($e);
$entityManager->flush();
}
for ($i = 1; $i <= 3; $i++) {
addRow($i, $entityManager);
}
//Using Doctrine's findAll() method
var_dump($entityManager->getRepository('IntegerTesting')->findAll());
//Using direct PDO query
var_dump($entityManager->getConnection()->query('SELECT * FROM integerTesting')->fetchAll());
使用 Doctrine 的 findAll() 方法的输出将整数列返回为所需的整数类型。
array(3) {
[0]=>
object(IntegerTesting)#61 (3) {
["id":protected]=>
int(4)
["name":protected]=>
string(6) "Name 1"
["someInt":protected]=>
int(1)
}
[1]=>
object(IntegerTesting)#63 (3) {
["id":protected]=>
int(5)
["name":protected]=>
string(6) "Name 2"
["someInt":protected]=>
int(2)
}
[2]=>
object(IntegerTesting)#64 (3) {
["id":protected]=>
int(6)
["name":protected]=>
string(6) "Name 3"
["someInt":protected]=>
int(3)
}
}
但是,直接查询将它们作为字符串返回,这是不需要的:
array(3) {
[0]=>
array(3) {
["id"]=>
string(1) "4"
["name"]=>
string(6) "Name 1"
["someInt"]=>
string(1) "1"
}
[1]=>
array(3) {
["id"]=>
string(1) "5"
["name"]=>
string(6) "Name 2"
["someInt"]=>
string(1) "2"
}
[2]=>
array(3) {
["id"]=>
string(1) "6"
["name"]=>
string(6) "Name 3"
["someInt"]=>
string(1) "3"
}
}
我通过将 PDO::ATTR_EMULATE_PREPARES
设置为 FALSE
找到了解决方案,但是,经过艰苦的故障排除后,发现它破坏了 Doctrine 的其他一些方面(类类型继承、也许还有其他功能)。
如何防止 Doctrine 将整数作为字符串返回?
最佳答案
在 php-8.1.0RC1/中,即使是 EMULATE_PREPARES 也是 native 类型, https://github.com/php/php-src/blob/php-8.1.0RC1/UPGRADING#L130 所以将来应该可以通过将 PHP 升级到 8.1 来解决这个问题
关于php - 防止 PHP、PDO 和 MySQL/MariaDB 在不禁用 ATTR_EMULATE_PREPARES 的情况下将整数作为字符串返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56853024/