mirror of
https://github.com/php/php-src.git
synced 2026-04-17 21:11:02 +02:00
Closes GH-8233
This fix corrects a behavior of `var_export()` that was mostly "hidden" until PHP 8.1 introduced:
* properties with object initializers
* constants containing object references
* default values of class properties containing `enum`s
Since `var_export(..., true)` is mostly used in conjunction with code generation,
and we cannot make assumptions about the generated code being placed in the root
namespace, we must always provide the FQCN of a class in exported code.
For example:
```php
<?php
namespace MyNamespace { class Foo {} }
namespace { echo "<?php\n\nnamespace Example;\n\n" . var_export(new \MyNamespace\Foo(), true) . ';'; }
```
produces:
```php
<?php
namespace Example;
MyNamespace\Foo::__set_state(array(
));
```
This code snippet is invalid, because `Example\MyNamespace\Foo::__set_state()` (which
does not exist) is called.
With this patch applied, the code looks like following (valid):
```php
<?php
namespace Example;
\MyNamespace\Foo::__set_state(array(
));
```
Ref: https://github.com/php/php-src/issues/8232
Ref: https://github.com/Ocramius/ProxyManager/issues/754
Ref: https://externals.io/message/117466
296 lines
5.5 KiB
PHP
296 lines
5.5 KiB
PHP
--TEST--
|
|
Test var_export() function with valid objects
|
|
--FILE--
|
|
<?php
|
|
echo "*** Testing var_export() with valid objects ***\n";
|
|
|
|
// class with no members
|
|
class foo
|
|
{
|
|
// no members
|
|
}
|
|
|
|
// abstract class
|
|
abstract class abstractClass
|
|
{
|
|
abstract protected function getClassName();
|
|
public function printClassName () {
|
|
echo $this->getClassName() . "\n";
|
|
}
|
|
}
|
|
// implement abstract class
|
|
class concreteClass extends abstractClass
|
|
{
|
|
protected function getClassName() {
|
|
return "concreteClass";
|
|
}
|
|
}
|
|
|
|
// interface class
|
|
interface iValue
|
|
{
|
|
public function setVal ($name, $val);
|
|
public function dumpVal ();
|
|
}
|
|
// implement the interface
|
|
class Value implements iValue
|
|
{
|
|
private $vars = array ();
|
|
|
|
public function setVal ( $name, $val ) {
|
|
$this->vars[$name] = $val;
|
|
}
|
|
|
|
public function dumpVal () {
|
|
var_export ( $vars );
|
|
}
|
|
}
|
|
|
|
// a gereral class
|
|
class myClass
|
|
{
|
|
var $foo_object;
|
|
public $public_var;
|
|
public $public_var1;
|
|
private $private_var;
|
|
protected $protected_var;
|
|
|
|
function __construct ( ) {
|
|
$this->foo_object = new foo();
|
|
$this->public_var = 10;
|
|
$this->public_var1 = new foo();
|
|
$this->private_var = new foo();
|
|
$this->protected_var = new foo();
|
|
}
|
|
}
|
|
|
|
// create a object of each class defined above
|
|
$myClass_object = new myClass();
|
|
$foo_object = new foo();
|
|
$Value_object = new Value();
|
|
$concreteClass_object = new concreteClass();
|
|
|
|
$valid_objects = array(
|
|
"new stdclass" => new stdclass,
|
|
"new foo" => new foo,
|
|
"new concreteClass" => new concreteClass,
|
|
"new Value" => new Value,
|
|
"new myClass" => new myClass,
|
|
"myClass_object" => $myClass_object,
|
|
"myClass_object->foo_object" => $myClass_object->foo_object,
|
|
"myClass_object->public_var1" => $myClass_object->public_var1,
|
|
"foo_object" => $foo_object,
|
|
"Value_object" => $Value_object,
|
|
"concreteClass_object" => $concreteClass_object
|
|
);
|
|
/* Loop to check for above objects with var_export() */
|
|
echo "\n*** Output for objects ***\n";
|
|
foreach($valid_objects as $key => $obj) {
|
|
echo "\n-- Iteration: $key --\n";
|
|
var_export( $obj );
|
|
echo "\n";
|
|
var_export( $obj, FALSE);
|
|
echo "\n";
|
|
var_dump( var_export( $obj, TRUE) );
|
|
echo "\n";
|
|
}
|
|
?>
|
|
--EXPECT--
|
|
*** Testing var_export() with valid objects ***
|
|
|
|
*** Output for objects ***
|
|
|
|
-- Iteration: new stdclass --
|
|
(object) array(
|
|
)
|
|
(object) array(
|
|
)
|
|
string(17) "(object) array(
|
|
)"
|
|
|
|
|
|
-- Iteration: new foo --
|
|
\foo::__set_state(array(
|
|
))
|
|
\foo::__set_state(array(
|
|
))
|
|
string(27) "\foo::__set_state(array(
|
|
))"
|
|
|
|
|
|
-- Iteration: new concreteClass --
|
|
\concreteClass::__set_state(array(
|
|
))
|
|
\concreteClass::__set_state(array(
|
|
))
|
|
string(37) "\concreteClass::__set_state(array(
|
|
))"
|
|
|
|
|
|
-- Iteration: new Value --
|
|
\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))
|
|
\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))
|
|
string(58) "\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))"
|
|
|
|
|
|
-- Iteration: new myClass --
|
|
\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))
|
|
\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))
|
|
string(271) "\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))"
|
|
|
|
|
|
-- Iteration: myClass_object --
|
|
\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))
|
|
\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))
|
|
string(271) "\myClass::__set_state(array(
|
|
'foo_object' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'public_var' => 10,
|
|
'public_var1' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'private_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
'protected_var' =>
|
|
\foo::__set_state(array(
|
|
)),
|
|
))"
|
|
|
|
|
|
-- Iteration: myClass_object->foo_object --
|
|
\foo::__set_state(array(
|
|
))
|
|
\foo::__set_state(array(
|
|
))
|
|
string(27) "\foo::__set_state(array(
|
|
))"
|
|
|
|
|
|
-- Iteration: myClass_object->public_var1 --
|
|
\foo::__set_state(array(
|
|
))
|
|
\foo::__set_state(array(
|
|
))
|
|
string(27) "\foo::__set_state(array(
|
|
))"
|
|
|
|
|
|
-- Iteration: foo_object --
|
|
\foo::__set_state(array(
|
|
))
|
|
\foo::__set_state(array(
|
|
))
|
|
string(27) "\foo::__set_state(array(
|
|
))"
|
|
|
|
|
|
-- Iteration: Value_object --
|
|
\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))
|
|
\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))
|
|
string(58) "\Value::__set_state(array(
|
|
'vars' =>
|
|
array (
|
|
),
|
|
))"
|
|
|
|
|
|
-- Iteration: concreteClass_object --
|
|
\concreteClass::__set_state(array(
|
|
))
|
|
\concreteClass::__set_state(array(
|
|
))
|
|
string(37) "\concreteClass::__set_state(array(
|
|
))"
|