1
0
mirror of https://github.com/php/php-src.git synced 2026-04-17 21:11:02 +02:00
Files
archived-php-src/ext/standard/tests/general_functions/var_export_basic6.phpt
Marco Pivetta 25cb9cdb79 Fix GH-8232 - always reference classes in var_export() via their FQCN
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
2022-04-23 11:06:21 +02:00

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(
))"