|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73108 Internal class cast handler uses integer instead of float
Submitted: 2016-09-18 21:12 UTC Modified: 2017-12-26 11:41 UTC
From: hartenfels at uni-koblenz dot de Assigned: nikic (profile)
Status: Closed Package: Class/Object related
PHP Version: 7.0.11 OS: Linux
Private report: No CVE-ID: None
 [2016-09-18 21:12 UTC] hartenfels at uni-koblenz dot de
This is a problem related to cast_object handlers for internal classes.

When using an object with a cast handler in arithmetic, integer conversion is triggered instead of floating point conversion, even in situations where floating point math is used.

The expected behavior would be that the floating point cast is triggered instead.

If only a cast handler for floating point is present, the conversion even fails outright with the message that the object could not be converted to an integer. The cast to double isn't even attempted.

This may be related to #54973.

Test script:
The entire extension can be found at

static int castbug_cast(zval *readobj, zval *retval, int type TSRMLS_DC)
    if (type == IS_LONG) {
        ZVAL_LONG(retval, 123);
        return SUCCESS;
    else if (type == IS_DOUBLE) {
        ZVAL_DOUBLE(retval, 31.41);
        return SUCCESS;
    else {
        return FAILURE;

$cb = new CastBug();

/* these work as expected */
var_dump((int) $cb);
var_dump((float) $cb);

/* these use integer conversion instead of double conversion */
var_dump($cb + 1.5);
var_dump($cb * 2.0);
var_dump($cb / 10.0);

Expected result:

Actual result:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-19 13:29 UTC]
-Status: Open +Status: Verified
 [2016-09-19 13:29 UTC]
Indeed, this is related to bug #73108 (might be even seen as

Note that it's possible to work around that issue by employing an
`do_operation` handler[1] which is available as of PHP 5.6.

[1] <>
 [2016-09-19 13:30 UTC]
Of course, I meant that this issue is related to bug #54973.
 [2016-09-22 00:33 UTC]
As I see it, the root of the problem is we have no way to cast an object to whatever number type is best, we have to request an integer or a float specifically. That means we end up picking one, and I guess we chose integers.

We could choose floats, but floats don't work in every situation. What if you need to represent a >54-bit number?

I'm not sure how this could be fixed without breaking existing extensions, though.
 [2016-09-22 00:47 UTC] hartenfels at uni-koblenz dot de
How would any extension ever rely on this behavior? If you specify both an integer and a float cast handler, I don't think you would ever expect the former to take precedence. And in fact, there's other extensions that break due to this bug, such as SimpleXML, which is probably a much more common use case.

But even if you really want to keep this behavior, if your object only has a float cast handler, you get an error about a missing integer cast handler. What should happen instead is that the float handler is used.
 [2017-12-26 11:41 UTC]
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sun Jun 04 06:03:41 2023 UTC