Doc #69811 [Ana]: Cannot bind closure to scope of internal class stdClass

From: Date: Tue, 16 Jun 2015 22:24:00 +0000
Subject: Doc #69811 [Ana]: Cannot bind closure to scope of internal class stdClass
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-12444@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69811&edit=1 ID: 69811 Updated by: kalle@php.net Reported by: olivier dot laviale at gmail dot com Summary: Cannot bind closure to scope of internal class stdClass Status: Analyzed Type: Documentation Problem Package: Documentation problem Operating System: Linux PHP Version: 7.0.0alpha1 Block user comment: N Private report: N New Comment: 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 :) Previous Comments: ------------------------------------------------------------------------ [2015-06-14 21:39:03] olivier dot laviale at gmail dot com 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? ------------------------------------------------------------------------ [2015-06-13 06:25:20] kalle@php.net To clarify Laurence's change; This is intended behaviour that you cannot bind a closure to an class defined internally. Also I think you have a mistake in the example, as you pass a newly created instance of 'A' to the 'A::get_public_vars()' method, but 'A::get_public_vars()' still assumes '$this' in the return statement, not that it would render the practice of binding closures to internally classes anymore allowed ;-) ------------------------------------------------------------------------ [2015-06-12 12:55:13] 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 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=69811&edit=1

« previous php.doc.bugs (#12444) next »