|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-06-12 12:55 UTC] olivier dot laviale at gmail dot com
Description: ------------ Hi, Looks like the following code is no longer possible with PHP7. The following error is raised: "Cannot bind closure to scope of internal class stdClass". I understand that PHP7 may introduce BC changes, but there's no mention about it in the documentation: http://php.net/manual/en/closure.bind.php Test script: --------------- <?php class A { private $a = 1; protected $b = 2; public $c = 3; static public function get_public_vars() { $get_public_vars = Closure::bind(function($object) { return get_object_vars($object); }, null, 'stdClass'); return $get_public_vars($this); } } var_dump(A::get_public_vars(new A)); Expected result: ---------------- [ 'c' => 3 ] Actual result: -------------- Error: Cannot bind closure to scope of internal class stdClass PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 08 12:00:02 2025 UTC |
Thanks for your reply Kalle. There's indeed an error in my code example, should be as follows: ``` <?php class A { private $a = 1; protected $b = 2; public $c = 3; static public function get_public_vars($object) { $get_public_vars = Closure::bind(function($object) { return get_object_vars($object); }, null, 'stdClass'); return $get_public_vars($object); } } var_dump(A::get_public_vars(new A)); ``` Now that we can't bind `stdClass`, what's the best way to get *only* the public properties of an object, since get_object_vars() executes from the current scope?Hi Olivier For the time being, I can only think of the following posibilities to achieve what you are trying to: 1) Simply create your own stdClass object, or use Anonymous Classes (also available in PHP7) 2) Reflection. This is heavy and really should not be used in production code: <?php class Alphabet { public $a, $b, $c; protected $d, $e, $f; private $g, $h, $i; public function __construct() { foreach(range('a', 'i') as $letter) { $this->{$letter} = random_int(0, 10000); } } public function getPublicVars(Alphabet $alphabet) { $ref = new ReflectionObject($alphabet); $props = []; foreach($ref->getProperties(ReflectionProperty::IS_PUBLIC) as $prop) { $props[$prop->name] = $prop->getValue($alphabet); } return($props); } } var_dump(Alphabet::getPublicVars(new Alphabet)); ?> 3) Casting to an array: <?php class Alphabet { public $a, $b, $c; protected $d, $e, $f; private $g, $h, $i; public function __construct() { foreach(range('a', 'i') as $letter) { $this->{$letter} = random_int(0, 10000); } } public function getPublicVars(Alphabet $alphabet) { return(array_filter((array) $alphabet, function($key) { return($key{0} !== "\0"); }, ARRAY_FILTER_USE_KEY)); } } var_dump(Alphabet::getPublicVars(new Alphabet)); ?> This should be considered your last resort (and please do not tell anyone that the code was "promoted" from PHP.net as this is dirty stuff!) I hope this can guide you a little further in the right direction at least :)