Skip to content

cast_object handler is never called for array cast #11547

Closed
@ju1ius

Description

@ju1ius

Description

The following code:

static zend_class_entry *foo_ce;
static zend_object_handlers foo_handlers;

PHP_MINIT_FUNCTION(my_extension) {
  // Class declaration boilerplate omitted
  foo_ce = register_class_Foo();
  // object handlers initialization boilerplate omitted
  foo_handlers.cast_object = foo_cast_object;
  foo_ce.default_object_handlers = &foo_handlers;
}

static zend_result foo_cast_object(zend_object *readobj, zval *writeobj, int type) {
  switch (type) {
    case IS_LONG:
    case _IS_NUMBER:
      ZVAL_LONG(writeobj, 42);
      return SUCCESS;
    case IS_ARRAY:
      ZVAL_LONG(writeobj, 42);
      convert_to_array(writeobj);
      return SUCCESS;
    default:
      return FAILURE;
  }
}
<?php
$foo = new Foo;
var_dump((int)$foo);
var_dump((array)$foo);

Resulted in this output:

int(42)
array(0) {
}

But I expected this output instead:

int(42)
array(1) {
  [0]=>
  int(42)
}

So it seems that the VM unconditionally uses the result of object->handlers->get_properties_for() without checking beforehand if object->handlers->cast_object() returns something.

Not exactly a bug per se, but rather yet another quirk whose fixing would improve the usability the extension API, IMO.

PHP Version

8.3-dev

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions