gpt4 book ai didi

php - Doctrine 将 bigint 作为字符串获取 - 如何防止这种情况

转载 作者:行者123 更新时间:2023-12-04 15:38:31 25 4
gpt4 key购买 nike

我有以下问题:

Doctrine 假设更新已更改的实体。问题是由于某种原因(也许是传统的 32 位系统?)bigint 数据类型被视为字符串(如下所示 - 这是 Doctrine 中的 bigint 类型类,还有多种其他转换为 Doctrine 代码中的字符串) )。

<?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 个 bigint 时你会怎么做?好的... 2 个条件... 没什么大不了的。但如果他们是…… 90 呢?好的...我们可以使用反射检查实体属性并检查所有内容。

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

但是……这不是工作单元的 Doctrine 吗?为什么我需要重新解析整个实体并检查已经检查过的东西,因为 bigint 被视为字符串(导致基本上复制了大量的 Doctrine 代码)?

现在的问题是......如何解决这个问题(请记住,我不是在为一个简单的案例要求一个特定的解决方案,我要求一个可以应用于大型代码库的通用解决方案,即应该在 future 几年保持 - 正如你在上面看到的那样,我有解决方案,但我对半工作和脆弱的代码不满意,除非真的没有其他办法)?我正在寻找一个我错过的设置,它使 Doctrine 将整数视为整数而不是字符串......类似的东西。

最佳答案

一种解决方案是覆盖 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;
}
}

然后,在 config.yml 中注册类型或 doctrine.yaml :
doctrine:
dbal:
types:
bigint: MyBigIntType

我用 Symfony 2.8 对此进行了测试,这导致使用 MyBigIntType对于所有类型为 bigint 的字段.也应该与更高版本的 Symfony 一起使用。

关于php - Doctrine 将 bigint 作为字符串获取 - 如何防止这种情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58286804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com