doctrine正在将bigints提取为字符串-如何防止这种情况

问题描述 投票:5回答:1

我有以下问题:

Doctrine应该更新已更改的实体。问题是由于某种原因(也许是传统的32位系统?),bigint数据类型被视为字符串(如您在下面看到的那样-这是主义中的bigint类型类,在主义代码中也有许多其他的字符串转换) )。

<?php

namespace Doctrine\DBAL\Types;

use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

/**
 * Type that maps a database BIGINT to a PHP string.
 */
class BigIntType extends Type implements PhpIntegerMappingType
{
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return Type::BIGINT;
    }

    /**
     * {@inheritdoc}
     */
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return $platform->getBigIntTypeDeclarationSQL($fieldDeclaration);
    }

    /**
     * {@inheritdoc}
     */
    public function getBindingType()
    {
        return ParameterType::STRING;
    }

    /**
     * {@inheritdoc}
     */
    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value === null ? null : (string) $value;
    }
}

这将导致更新的数据不应该更新,因为工作单元检查器会比较严格(应如此)的数据,从而导致差异(下面的代码)。

// skip if value haven't changed
if ($orgValue === $actualValue) { // $orgValue = "3829784117300", $actualValue = 3829784117300
    continue;
}

最终结果是以下代码:

$product = $productRepo->find($id);
$product->setOwnerId($ownerId); // $ownerId = 3829784117300
$this->em->flush();

正在生成一个查询,它的工作原理...除了强调db以外,基本上没有其他功能(在我的情况下,我每天有几千万个这样的查询)。上面特定情况的解决方案...

$product = $productRepo->find($id);
if ((int)$product->getOwnerId() !== $ownerId) {
    $product->setOwnerId($ownerId); // $ownerId = 3829784117300
}
$this->em->flush();

简单吧?但是...当你有2个bigints时你会怎么做?好吧... 2个条件...没什么大不了的。但是,如果他们是... 90?好的...我们可以使用反射来遍历实体属性并检查所有内容。

但是...如果在关系链中某处需要检查另一个实体怎么办?完整的解决方案是,我们必须递归检查实体及其子实体的每个属性,并检查bigints。

但是...这不是说教义的工作单位是为了什么?为什么我需要重新分析整个实体并检查是否仅因为bigint被视为字符串(已经导致基本上复制了大量理论代码)而已经检查过的内容?] >>

现在是问题...如何解决(请记住,我不是在为简单案例寻求特定解决方案,而是在寻求可应用于大型代码库的一般解决方案。那应该被维护好几年-正如您在上面看到的,我有解决方案,但是我不能接受一半的工作和脆弱的代码,除非真的没有其他办法)?我正在寻找一种可能错过的设置,该设置使学说将整数像整数一样对待,而不是像字符串一样……。

我有以下问题:原则是要更新已更改的实体。问题是由于某种原因(也许是传统的32位系统?),bigint数据类型被视为字符串(如...

php symfony doctrine-orm doctrine
1个回答
2
投票

一种解决方案是使用您自己的方法来覆盖Doctrine对bigint类型的实现。首先,创建一个与Doctrine的BigIntType相同的类,只不过将强制转换为字符串替换为强制转换为int:

class MyBigIntType extends Type
{
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return Type::BIGINT;
    }

    /**
     * {@inheritdoc}
     */
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return $platform->getBigIntTypeDeclarationSQL($fieldDeclaration);
    }

    /**
     * {@inheritdoc}
     */
    public function getBindingType()
    {
        return \PDO::PARAM_STR;
    }

    /**
     * {@inheritdoc}
     */
    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return (null === $value) ? null : (int)$value;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.