__set_state()
之类的__get_state()
是否有相反的PHP函数?我并不是说__sleep()
用于序列化。我想要一个简单的函数,在对象上调用var_export()
之后但在var_export()
获取数据之前调用,这样我就可以在每个对象上选择要导出的数据。 我知道有一种方法可以通过但是有一个更简单的方法吗?方式是什么?__get()
和debug_backtrace()
来实现这一点,只有在对象上调用var_export()
时才能修改数据。
修改:无法通过__get()
和debug_backtrace()
实现此操作,仅在对象上调用var_export()
时修改数据,因为{{ 1 {}未在__get()
上调用。
解决方案:
var_export()
当然,有了自己的实现,你可以做任何事情。使用<?php
/*
* @author Christian Mayer <http://fox21.at>
* @link http://stackoverflow.com/q/21762276/823644
* @link https://eval.in/163041
* @link https://eval.in/163462
* @link https://eval.in/163909
* @link https://gist.github.com/TheFox/49ff6903da287c30e72f
*/
interface Exportable{
public function __get_state();
}
function unset_with_get_state($expression){
$before = clone $expression;
$classVars = array_keys(get_class_vars(get_class($before)));
foreach(array_diff($classVars, $before->__get_state()) as $var){
unset($before->$var);
}
return $before;
}
function my_var_export($expression, $return = null){
$before = $expression;
if($before instanceof Exportable){
$before = unset_with_get_state($expression);
}
return var_export($before, $return);
}
class Foo implements Exportable{
public $name = null;
public $foo = null;
public $bar = null;
public function __get_state(){
// Only show 'name' and 'bar' on my_var_export().
return array('name', 'bar');
}
}
$a = 'hello';
my_var_export($a);
print "\n";
$b = new Foo();
$b->name = 'world';
$b->foo = 'foo is foo';
$b->bar = 'bar is bar';
my_var_export($b);
print "\n";
我的意思是,如果有一个内置的PHP函数或类似的东西,所以你不必自己做。此解决方案并非真正 easy ,因为您必须从is there a simpler way?
扩展所有对象。这也适用于您的变量为Exportable
的情况。在此示例中,我选择仅导出public
和name
,但不导出bar
。内置的PHP函数(如foo
)会更好。
答案 0 :(得分:7)
你写下你的问题:
我想要一个简单的函数,在对象上调用var_export()但在var_export()获取数据之前调用
听起来你想采用var_export()
函数,然后调用适配器而不是var_export()
。然后在适配器内部,您将获得之前的数据它(真的) var_export()ed
:
function my_var_export($expression, $return = NULL) {
$before = $expression;
return var_export($before, $return);
}
$a = 'hello';
my_var_export($a); // 'hello'
使用此适配器,您在技术上能够确定您正在寻找的内容,但这也是前提条件。
所以我们关心的是对象,而不是字符串。对于那些对象,应该调用__get_state()
方法。到目前为止,我们知道这样的对象应该是什么(它应该是 exportable ),我们创建一个接口:
interface Exportable {
/**
* @return static clone of $this for var_export
*/
public function __get_state();
}
那怎么能实现呢?一个想法是克隆真实对象,然后更改它,以便var_export
不会遇到任何问题。这种克隆将使我们无需操纵具体对象就可以将其导出。但这只是一个约定,一个无法克隆的对象也可以实现这个__get_state()
方法,那么编写实现可能会稍微复杂一些。
另一方面,在界面的帮助下,适配器my_var_export()
可以更加智能地将$before
传递给var_export()
时如何处理:
function my_var_export($expression, $return = null)
{
$before = $expression instanceof Exportable
? $expression->__get_state()
: $expression;
return var_export($before, $return);
}
只是插入了可导出 $expression
需要特殊处理的新案例。这与$a = 'hello';
表达式一样。
所以现在要试一试,我们需要一个具体类型 Exportable ,示例我在这里使用 Foo 。出于测试目的,我给它一个私有属性,仅在已采用__get_state()
操作中调用var_export()
的实现时才设置:
class Foo implements Exportable
{
private $name = null;
private $__get_state_called;
public function __construct($name)
{
$this->name = (string)$name;
}
public function __get_state()
{
$before = clone $this; // or if inherited: parent::__get_state()
$before->__get_state_called = true;
return $before;
}
}
工作示例比:
$b = new Foo('hello');
my_var_export($b);
根据需要提供输出:
Foo::__set_state(array(
'name' => 'hello',
'__get_state_called' => true,
))
这是你的“神奇”功能 调整函数 完整示例(run it online):__get_state()
,在 var_export()
获取数据之前称为,但之后(my_
) var_export()
被称为。{/ p>
var_export
以添加所需的功能。使用接口来处理需要特殊处理的对象。<?php
/*
* @author hakre <http://hakre.wrodpress.com/>
* @link http://stackoverflow.com/a/24228153/367456
* @link https://eval.in/163041
*/
/**
* Interface Exportable
*/
interface Exportable
{
/**
* @return static clone of $this for var_export
*/
public function __get_state();
}
/**
* @param mixed $expression
* @param bool $return (optional)
*
* @return void|string
*/
function my_var_export($expression, $return = null)
{
$before = $expression instanceof Exportable
? $expression->__get_state()
: $expression;
return var_export($before, $return);
}
/**
* Class Foo
*/
class Foo implements Exportable
{
private $name = null;
private $__get_state_called;
public function __construct($name)
{
$this->name = (string)$name;
}
/**
* @see Exportable
* @return Foo|static
*/
public function __get_state()
{
$before = clone $this; // or if inherited: parent::__get_state()
$before->__get_state_called = true;
return $before;
}
}
$a = 'hello';
my_var_export($a);
echo "\n\n";
$b = new Foo('world');
my_var_export($b);