Skip to content

Commit

Permalink
Fix can't insert float into MySQL with PHP 7.3
Browse files Browse the repository at this point in the history
## Problem
When inserting a float value into MySQL via the Illuminate\Database package when using at least PHP 7.3, the value is converted to an int.

The bug has been reported a few times before:

* #30435 
* illuminate/database#246

## Cause
PR #16069 introduced logic to the MySQLConnection that cast floats to ints to address a comparison problem with JSON columns, which was reported in issue #16069. This does not seem to cause a problem with PHP 7.1 and below but causes the float to lose it's decimal places when using PHP 7.3. I have not tested with PHP 7.2.

## Bug Reproduction
Given we have the following MySQL table:

```
CREATE TABLE `zip_codes` (
  `zip_code` varchar(255) NOT NULL,
  `latitude` decimal(15,10) NOT NULL,
  `longitude` decimal(15,10) NOT NULL
)
```

When we execute the following using Artisan Tinker:

```php
DB::table('zip_codes')->delete();

// Using the same values
$lat = -0.2;
$lon = 0;
$sql = 'INSERT INTO zip_codes (latitude, longitude, zip_code) VALUES (:lat, :long, :zip)';

// We insert the first by using PDO directly
$values = [':lat' => $lat, ':long' => $lon, ':zip' => 1];
DB::connection()->getPdo()->prepare($sql)->execute($values);

// Then the second by using Eloquent
DB::table('zip_codes')->insert(['latitude' => $lat, 'longitude' => $lon, 'zip_code' => 2]);

// Then pull them both.
DB::table('zip_codes')->get();
```

Then we should see both records with -0.2 as the latitude. But only the first has the value, and the second row is zero.
  • Loading branch information
Chekote authored Jan 10, 2020
1 parent 02a326c commit 95a8141
Showing 1 changed file with 0 additions and 17 deletions.
17 changes: 0 additions & 17 deletions src/Illuminate/Database/MySqlConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,4 @@ protected function getDoctrineDriver()
{
return new DoctrineDriver;
}

/**
* Bind values to their parameters in the given statement.
*
* @param \PDOStatement $statement
* @param array $bindings
* @return void
*/
public function bindValues($statement, $bindings)
{
foreach ($bindings as $key => $value) {
$statement->bindValue(
is_string($key) ? $key : $key + 1, $value,
is_int($value) || is_float($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}
}

0 comments on commit 95a8141

Please sign in to comment.