我对构造函数在PHP中的工作方式有点困惑。
我有一个带有构造函数的类,当我实例化一个新对象时会调用它。
$foo = new Foo($args);
__construct($params)
在类Foo
中调用,并执行相应的初始化代码。
但是当我使用该类调用静态函数时,会再次调用构造函数。
$bar = Foo::some_function(); //runs the constructor from Foo
这会导致构造函数执行,运行我打算仅在创建新Foo
对象时使用的对象初始化代码。
我是否忽略了构造函数的工作原理?或者,当我使用类进行静态函数调用时,有没有办法阻止__construct()
执行?
我应该使用“工厂”功能来进行对象初始化吗?如果是这样,那么构造函数的重点是什么?
:: EDIT :: 我有一个表单,用户可以将照片上传到相册(create_photo.php)和他们可以查看相册的区域(view_photos.php)。提交表格后:
$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..);
Photo构造函数创建并保存照片。但是在view_photo.php中,当我打电话时:
$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database
这导致Photo的构造函数运行!
答案 0 :(得分:19)
我认为没有什么可以复制你的问题。
请参阅演示:http://codepad.org/h2TMPYUV
代码:
class Foo {
function __construct(){
echo 'hi!';
}
static function bar(){
return 'there';
}
}
echo Foo::bar(); //output: "there"
答案 1 :(得分:6)
假设 PHP 5.x
不同的目标,不同的路径
创建一个类(对象)的新实例
class myClassA
{
public $lv;
public function __construct($par)
{
echo "Inside the constructor\n";
$this->lv = $par;
}
}
$a = new myClassA(11);
$b = new myClassA(63);
因为我们创建了一个新的PHP调用对象:
__construct($par)
;
的新对象,所以:
$a->lv == 11
$b->lv == 63
使用类
的函数class myClassB
{
public static $sv;
public static function psf($par)
{
self::$sv = $par;
}
}
myClassB::psf("Hello!");
$rf = &myClassB::$sv;
myClassB::psf("Hi.");
现在$rf == "Hi."
函数或变量必须定义为::
访问的静态,没有创建调用“psf”的对象,“类变量” sv 在类中只有1个实例。 / p>
使用工厂创建的单例(myClassA在上面)
class myClassC
{
private static $singleton;
public static function getInstance($par){
if(is_null(self::$singleton)){
self::$singleton = new myClassA($par);
}
return self::$singleton;
}
}
$g = myClassC::getInstance("gino");
echo "got G\n";
$p = myClassC::getInstance("pino");
echo "got P\n";
首次使用工厂( getInstance )构建一个 $ par 设置为 gino 的新对象。
第二次使用工厂 $ singleton 已经有一个我们返回的值。没有创建新对象(不调用 __ construct ,使用更少的内存和cpu)。
课程的价值是对象 instanceOf myClassA,不要忘记:
myClassC::$singleton->lv == "gino"
注意单身人士:
What is so bad about singletons?
http://www.youtube.com/watch?v=-FRm3VPhseI
根据我的回答,我不想推广/降级单身人士。简单地从问题中的单词,我做了这个计算:
“静态” + “__构建体”= “单”!
答案 2 :(得分:1)
以下是解决方法:
我将方法construct()
放在静态类中。请注意,它与我在常规类中使用的__construct()
不同。
每个类都在自己的文件中,所以我在第一次使用类时懒得加载该文件。这给了我第一次使用课程的事件。
spl_autoload_register(function($class) {
include_once './' . $class . '.php';
if (method_exists($class, 'construct')) {
$class::construct();
}
});
答案 3 :(得分:0)
我在静态方法中将类属性定义为数组,并通过该方法调用它们。我不确定它是否是最佳解决方案,但效果很好。
示例:
class Foo
{
private static construct_method()
{
return [
'one' => 1,
'two' => 2
];
}
public static any_method()
{
return self::construct_method()['one'] + self::construct_method()['two'];
}
}
echo Foo::any_method(); // 3