【问题标题】:Why does propel convert float property to string?为什么推进将浮点属性转换为字符串?
【发布时间】:2013-03-26 08:14:37
【问题描述】:

我刚刚注意到,propel 在生成的 setter 方法中将数值转换为字符串。 我的问题是,由于我使用的是德语语言环境,浮点值是用逗号而不是点插入的。例如:“3.5”生成字符串“3,5”。 我正在使用 PostgreSQL,它显然需要 3.5。

版本信息: 如果相关,我使用的是:PHP 5.3.9,Propel 1.6 和 Symfony 2.2。

详情:

表定义如下所示:

<table name="account_entry">
    ...
    <column name="amount" type="decimal" size="12" scale="2" required="true" />
    ...
</table>

生成的 setAmount() 方法如下所示:

public function setAmount($v)
{
    if ($v !== null && is_numeric($v)) {
        $v = (string) $v;
    }

    if ($this->amount !== $v) {
        $this->amount = $v;
        $this->modifiedColumns[] = AccountEntryPeer::AMOUNT;
    }


    return $this;
} // setAmount()

保存对象会导致 PostgreSQL 错误:

Invalid text representation: 7 ERROR: invalid input syntax for type numeric: "3,5"

我花了一段时间才找到发生这种转换的地方。如您所见,浮点值在 setAmount() 中被转换为字符串。到目前为止,我从未注意到将浮点值转换为字符串会导致字符串包含特定于语言环境的小数分隔符。

我想知道为什么 propel 首先将浮点值转换为字符串? 有一些解决方法吗?

我想出的唯一解决方法是非常丑陋和烦人:

setlocale(LC_ALL, 'en_US');
$ae->setAmount(3.5);
setlocale(LC_ALL, 'de_DE');

【问题讨论】:

  • 处理列好像是the default behavior。但是根据生成 SQL 的方式(例如插入),it seems 应该 再次 强制转换以匹配本机列类型。您可以查看issue on Github 和/或提交一个
  • 感谢您的研究。我在推进邮件列表上发布了这个问题。如果它可能不是错误,我想避免创建错误报告。

标签: php propel


【解决方案1】:

问题在于,Propel 将与该列相关的 PHP 字段转换为 setter 中的原生 PHP 类型(正如@j0k 所提到的),但是如果您再深入一点,您就会发现问题。在PropelTypes.php helper 类中,在第 76 行,您可以看到“十进制”的原生 PHP 类型被列为“字符串”。

将此与列为“double”的“float”本机类型进行比较。我不确定这是否是故意的,但无论如何,只需将列切换到type="float"type="double" 即可解决您的问题。

Propel 应该将其转换为您的 DBMS 需要的任何类型。

【讨论】:

  • 谢谢!将类型从十进制更改为双精度确实解决了我的问题。我仍然认为它是一种解决方法,因为 PostgreSQL 现在使用 double 作为类型而不是小数(x,y)。但这对我来说很好。
  • 很高兴它成功了。老实说,我不确定为什么核心 Propel 人员会将本机类型默认为“字符串”,但对于某些 DBMS 来说可能是有意义的。
  • 这是因为数据库中的 DECIMAL 字段是精确的,而 CPU 上的原生浮点处理不是。因此,Propel 通过返回字符串中的确切值来确保安全,让您担心算术和存储。见 f.e. link
猜你喜欢
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 2014-09-25
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多