Skip to content

Conversation

twose
Copy link
Member

@twose twose commented Dec 2, 2018

all PHP versions and systems

script

$array = new class
{
    private $private = 1;
    protected $protected = 2;
    public $public = 3;
};
$array = (array)$array;
var_dump($array);

output

array(3) {
  ["0x00class@anonymous/path/to/array.php0x1099fd6330x00private"]=>
  int(1)
  ["0x00*0x00protected"]=>
  int(2)
  ["public"]=>
  int(3)
}

when we convert object which has invisible properties to array, it uses the zend_mangle_property_name result.
I think we can do what the json_encode does, skip protected and private members.

@twose twose changed the title Fix bug: convert object which has invisible properties to array. Fix Bug #77226: convert object which has invisible properties to array. Dec 2, 2018
@nikic
Copy link
Member

nikic commented Dec 2, 2018

There's a lot of code relying on the current behavior, I doubt we can change it. It's possible to use get_object_vars() if you don't want to get mangled property names. It will return all properties that are visible from the current scope.

@twose
Copy link
Member Author

twose commented Dec 2, 2018

There's a lot of code relying on the current behavior

...include output 0x00 in PHP script? I think this is terrible... Is this a feature?

@nikic
Copy link
Member

nikic commented Dec 2, 2018

@twose Object to array casts are a very fast and reliable way to access all the properties of an object. This is necessary for many libraries that do things like serialization, dumping, comparison, etc.

I definitely think that having this as a default behavior for array casts is bad, but it's not something we can simplify change at this point in time.

A good starting point may be to add a new function which provides the current functionality of object-to-array casts under a more explicit name and with less edge cases (e.g. ArrayObject is one of the big offenders, where you need to set a special flag to get normal array-to-object behavior). Libraries that need this functionality can then migrate to that function.

@Ocramius might be a good person to talk to about this.

@Ocramius
Copy link
Contributor

Ocramius commented Dec 2, 2018

This is indeed normal/expected. The \0 delimiters are even tested in the PHP integration tests.

@twose
Copy link
Member Author

twose commented Dec 2, 2018

Thank you for your explanation, never thought that... 😧

@twose twose closed this Dec 2, 2018
@twose twose deleted the zend_proptable_to_symtable branch December 2, 2018 14:52
@nikic
Copy link
Member

nikic commented Dec 2, 2018

@Ocramius What do you think about

A good starting point may be to add a new function which provides the current functionality of object-to-array casts under a more explicit name and with less edge cases (e.g. ArrayObject is one of the big offenders, where you need to set a special flag to get normal array-to-object behavior). Libraries that need this functionality can then migrate to that function.

@Ocramius
Copy link
Contributor

Ocramius commented Dec 2, 2018

I talked about it with @jpauli while at Web5 in 2013: ideally, I'd love to have an API like the one of zendframework/zend-hydrator, which allows populating state and extracting state. The problem with collisions in propert names inside an inheritance still exists, but I still believe that the \0 convention makes sense for now, as it is really really hard for userland code to manage to break that.

@Ocramius
Copy link
Contributor

Ocramius commented Dec 2, 2018

You could probably put such an API in:

  • ReflectionObject#toArray(object $object)
  • ReflectionClass#newInstanceFromState(array $state)

Bad idea? Absolutely, but it is not meant for OOP, and rather for serialisation purposes.

@jpauli
Copy link
Member

jpauli commented Dec 7, 2018

What about __set_state() ? Cannot it help doing what you need ?

@Ocramius
Copy link
Contributor

Ocramius commented Dec 7, 2018

__set_state() is an API to be implemented on each class: I'm talking about something that allows me to instantiate anything at all, with pre-seeded state.

For tools like JMSSerializer, Doctrine ORM, zendframework/zend-di, zendframework/zend-servicemanager, php-di/php-di, ocramius/proxy-manager, phpunit and so on, this would be quite the massive speed-up.

For everyone else: not to be used, as it's gonna be something quite dangerous :-)

@jpauli
Copy link
Member

jpauli commented Dec 7, 2018

Ok I see, we could add facilities to Reflection, that wouldn't be hard to program.
I guess we could write an RFC for PHP-next ?

@Ocramius
Copy link
Contributor

Ocramius commented Dec 7, 2018

Feasible, can probably help during the holidays. Should we take this offline, in private convo?

@jpauli
Copy link
Member

jpauli commented Dec 7, 2018

Yes Ok you can fetch me by email or on IRC :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants