为了表明我的问题我做了两个功能。第一个向Laravel请求PDO实例并查询数据库。在第二个我自己实现一个新的。 Laravel的第一个结果不准确。第二个给出正确的结果。
表格的定义是这样的:
CREATE TABLE IF NOT EXISTS `event` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`level` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
这是第一个功能:
public function testpdo1() {
$pdo = DB::connection('myconnection')->getPdo();
$query = "SELECT level FROM event LIMIT 4";
$result = $pdo->query($query);
foreach ($result as $row) {
print $row[0] ."\n";
}
}
这给出了这些结果:
102.09999847412
97.900001525879
95.300003051758
94.099998474121
这是第二个功能:
public function testpdo2() {
$pdo = new PDO('dsn', 'user', 'pass');
$query = "SELECT level FROM event LIMIT 4";
$result = $pdo->query($query);
foreach ($result as $row) {
print $row[0] ."\n";
}
}
这给出了这些结果:
102.1
97.9
95.3
94.1
最后一个是正确的结果。
有没有办法让Laravel在第二个函数中表现得像?
我认为差异在于PDO设置。我尝试设置PDO :: ATTR_STRINGIFY_FETCHES但无济于事。我也尝试在第二个函数中查看是否可以使第二个出错。但它没有用。
也许我设置这样的属性有问题。使用laravel(函数1)我尝试将它/config/database.php设置为我的连接选项:
'connections' => [
'myconnection' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'options' => array (
PDO::ATTR_STRINGIFY_FETCHES => true,
),
],
....
使用第二个功能我用
尝试了$pdo = new PDO('dsn', 'user', 'pass', [PDO::ATTR_STRINGIFY_FETCHES => true]);
和
$pdo->setAttribute ( PDO::ATTR_STRINGIFY_FETCHES , true );
在实例化之后,具有真假值。它似乎没有任何区别......
这个问题接近我的问题:PHP PDO query returns inaccurate value for FLOAT fields 。但由于我的第二个功能给出了正确的答案,因此似乎可以得到准确的答案。
@Ragu Swaminathan建议第二个函数给出舍入值。需要明确的是:这些是数据库中的值。
mysql> select level from event LIMIT 4;
+-------+
| level |
+-------+
| 102.1 |
| 97.9 |
| 95.3 |
| 94.1 |
+-------+
4 rows in set (0.00 sec)
当我在函数1的查询中使用舍入时,值变为与函数2中的值相同。这是一种可能的解决方法,但我希望有更好的解决方案。
答案 0 :(得分:0)
这两个函数表现不同的原因确实在PDO设置中。 参数PDO :: ATTR_EMULATE_PREPARES的默认值为true。 Laravel将此参数设置为false。
所以@Ragu Swaminathan是对的。第二个函数给出了舍入值。和mysql_client,phpmyadmin,perl等一样。
我做了一些我希望分享的第二个功能的测试。我稍微改了一下。
public function testpdo2() {
$pdo = new PDO('dsn', 'user', 'pass');
$query = "SELECT level FROM `test`";
$result = $pdo->query($query);
foreach ($result as $row) {
print gettype($row[0]).' : '.$row[0]."<br>";
}
}
结果是
string : 102.1
string : 97.9
string : 95.3
string : 94.1
所以我得到了字符串
当我在实施PDO后放入这一行
$pdo->setAttribute ( PDO::ATTR_EMULATE_PREPARES, false );
结果是
double : 102.09999847412
double : 97.900001525879
double : 95.300003051758
double : 94.099998474121
当我也(!)添加这一行
$pdo->setAttribute ( PDO::ATTR_STRINGIFY_FETCHES , true );
结果是
string : 102.09999847412
string : 97.900001525879
string : 95.300003051758
string : 94.099998474121
这就是为什么这似乎没有帮助
我的最后一次测试是将值102.09999847412插入表中。 &#34;正常&#34;回答为102.1
结论是:花车不值得信任。 但我们已经知道了; - )