无论如何,有没有可能在不调用其构造函数的情况下创建php类的实例?
我有一个A类,在创建它的一个实例时传递文件,在A类的构造函数中打开这个文件。
现在在A类中,有一些函数我需要调用,但不需要传递文件,因此不需要使用打开文件的构造函数功能,因为没有传递文件。
所以我的问题是,有没有可能在不调用构造函数的情况下创建PHP类的实例?
注意:我不能使函数成为静态的,因为我正在使用函数中的一些类属性。
发布于 2010-04-01 03:34:21
类构造函数将始终被调用。不过,有几种方法可以解决这个问题。
第一种方法是在构造函数中为参数提供默认值,并且仅在设置了这些参数的情况下对这些参数执行特定的操作。例如:
class MyClass {
public __construct($file = null) {
if ($file) {
// perform whatever actions need to be done when $file IS set
} else {
// perform whatever actions need to be done when $file IS NOT set
}
// perform whatever actions need to be done regardless of $file being set
}
}
另一种选择是扩展类,这样子类的构造函数就不会调用父类的构造函数。
class MyParentClass {
public __construct($file) {
// perform whatever actions need to be done regardless of $file being set
}
}
class MyChildClass extends MyParentClass {
public __construct() {
// perform whatever actions need to be done when $file IS NOT set
}
}
发布于 2011-12-10 23:29:08
在你的情况下,我建议你考虑重新设计你的代码,这样你就不需要做这样的事情,但回答你的问题:是的,这是可能的。
你可以使用PHP5.4中引入的ReflectionClass和它的方法newInstanceWithoutConstructor,这样就可以很容易地创建一个类的实例,而不用调用它的构造函数:
$reflection = new ReflectionClass("ClassName");
$instance = $reflection->newInstanceWithoutConstructor(); //That's it!
发布于 2010-04-01 04:04:21
注意:下面的解决方案适用于PHP5.3及更低版本。从PHP5.4开始,你还可以 .
这确实是可能的。
从PHPUnit_Framework_MockObject_Generator
修改
1 $myClass = unserialize(
2 sprintf(
3 'O:%d:"%s":0:{}',
4 strlen('MyClass'), 'MyClass'
5 )
6 );
请记住,在像PHPUnit这样的框架中,像这样的代码都是很好的,并且是合理的。但是,如果您必须在您的生产代码中包含这样的代码,那么您可能会做一些非常奇怪的事情。
既然你要求解释:
当你使用serialize an Object时,你会得到一个对象的字符串表示。例如
echo serialize(new StdClass) // gives O:8:"stdClass":0:{}
O
的意思是对象。8
是类名的字符串长度。"stdClass"
显然是类名。序列化的对象设置了0
属性(稍后将详细介绍),由空花括号表示。:
只是分隔符。
可以使用unserialize函数将每个序列化的字符串重新创建为其原始的“活动”值。这样做,将绕过构造函数。正如查尔斯正确指出的那样,如果定义了magic method __wakeup()
,就会调用它(就像序列化时调用__sleep()
一样)。
在第3行,您可以看到准备与sprintf一起使用的字符串(第2行)。如您所见,类名的字符串长度为%d
,类名为%s
。这是为了告诉sprintf,它应该使用第4行传递给它的第一个参数作为数字,使用第二个参数作为字符串。因此,sprintf调用的结果是
'O:7:"MyClass":0:{}'
您可以将第4行中出现的两个"MyClass“替换为所需的类名,以便在不调用控制器的情况下创建要实例化的类的序列化字符串。
然后,绕过构造函数,将该字符串反序列化为第1行中的MyClass实例。未序列化的实例将拥有它的类的所有方法以及所有属性。如果MyClass中有属性,则这些属性将具有其默认值,除非您向序列化的虚拟字符串添加不同的值。
这已经够了。没什么太神奇的。
https://stackoverflow.com/questions/2555883
复制相似问题