Skip to content

Conversation

oleibman
Copy link
Collaborator

@oleibman oleibman commented Jul 5, 2025

Fix #4522. Although this is technically a breaking change, it is expected that very few, if any, existing programs will be affected. Nevertheless, DefaultValueBinder is implicitly used by the vast majority of programs out there, and I am reluctant to install a breaking change for something so widespread. So I will save this change for the next breaking release, which should be PhpSpreadsheet 5.0.0. There is no current schedule for that release.

For strings consisting entirely of digits, DefaultValueBinder treats the value as a string if greater than PHP_INT_MAX, or an int otherwise. This prevents the loss of precision in large integers. This treatment dates back to PHPExcel, and has been in place since 2014.

There are several problems with this approach. Excel itself maintains 15 digits of precision. So, string-vs-int should be decided at 999_999_999_999_999. This is much lower than PHP_INT_MAX for 64-bit, and much higher than for 32-bit. DefaultValueBinder is changed to use that new limit.

A second problem is that DefaultValueBinder is only making this adjustment for positive integers. It is changed to test absolute value.

A third problem is that DefaultValueBinder is making this adjustment only for strings, so that if you pass the number in as an int, it will not be adjusted (and will lose precision). It is changed to apply the same test for int.

This is:

  • a bugfix
  • a new feature
  • refactoring
  • additional unit tests

Checklist:

Fix PHPOffice#4522. Although this is technically a breaking change, it is expected that very few, if any, existing programs will be affected. Nevertheless, DefaultValueBinder is implicitly used by the vast majority of programs out there, and I am reluctant to install a breaking change for something so widespread. So I will save this change for the next breaking release, which should be PhpSpreadsheet 5.0.0. There is no current schedule for that release.

For strings consisting entirely of digits, DefaultValueBinder treats the value as a string if greater than PHP_INT_MAX, or an int otherwise. This prevents the loss of precision in large integers. This treatment dates back to PHPExcel, and has been in place since 2014.

There are several problems with this approach. Excel itself maintains
[15 digits of precision](https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3).
So, string-vs-int should be decided at 999_999_999_999_999. This is much lower than PHP_INT_MAX for 64-bit, and much higher than for 32-bit. DefaultValueBinder is changed to use that new limit.

A second problem is that DefaultValueBinder is only making this adjustment for positive integers. It is changed to test absolute value.

A third problem is that DefaultValueBinder is making this adjustment only for strings, so that if you pass the number in as an int, it will not be adjusted (and will lose precision). It is changed to apply the same test for int.
@oleibman oleibman marked this pull request as draft July 5, 2025 04:00
@oleibman
Copy link
Collaborator Author

oleibman commented Jul 5, 2025

My patience with Scrutinizer is just about done. It does not recognize the underscore numeric separator which was introduced in Php 7.4 over 5.5 years ago. I could eliminate the underscores, but I do not believe that we should be forced to adopt less clear code just to satisfy Scrutinizer. For now, I will just suppress the errors.

@oleibman
Copy link
Collaborator Author

Scrutinizer is no longer complaining about the underscores! Way to go!

@oleibman oleibman changed the title WIP Minor Breaking Change to DefaultValueBinder Minor Breaking Change to DefaultValueBinder Jul 24, 2025
@oleibman oleibman marked this pull request as ready for review July 24, 2025 06:39
@oleibman oleibman added this pull request to the merge queue Aug 3, 2025
Merged via the queue into PHPOffice:master with commit 20ac2f1 Aug 3, 2025
14 checks passed
@oleibman oleibman deleted the issue4522 branch August 3, 2025 01:56
@oleibman oleibman mentioned this pull request Aug 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Data loss for large numeric value like 19966412884001452

1 participant