我对构造函数在PHP中的工作方式有点困惑。
我有一个带有构造函数的类,当我实例化一个新对象时,它会被调用。
$foo = new Foo($args);
CCD_ 1在类CCD_ 2中被调用,并且它执行适当的初始化代码。
但是,当我使用类来调用静态函数时,构造函数会被再次调用。
$bar = Foo::some_function(); //runs the constructor from Foo
这会导致构造函数执行,运行仅在创建新的Foo
对象时使用的对象初始化代码。
我是不是错过了构造函数如何工作的要点?或者,当我使用类进行静态函数调用时,有没有一种方法可以防止__construct()
执行?
我应该使用"工厂"函数来进行对象初始化吗?如果是这样的话,那么构造函数有什么意义呢?
::编辑::我有一个表单,用户可以在其中上传照片到相册(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的构造函数运行!
我没有看到任何能复制您问题的内容。
请参阅演示:http://codepad.org/h2TMPYUV
代码:
class Foo {
function __construct(){
echo 'hi!';
}
static function bar(){
return 'there';
}
}
echo Foo::bar(); //output: "there"
假设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在类内只有一个实例。 -
使用由工厂创建的单例(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更少(。
当然,值是一个对象instanceOfmyClassA,不要忘记:
myClassC::$singleton->lv == "gino"
关注单身人士:
单身汉有什么不好的?
http://www.youtube.com/watch?v=-FRm3VPhseI
根据我的回答,我不想提拔/降级单身汉。简单地根据问题中的单词,我计算出:
"static"+"__construct"="singleton"!
这是我的解决方法:
我把方法construct()
放在静态类中。注意,它与我在常规类中使用的__construct($params)
0不同。
每个类都在自己的文件中,所以我在第一次使用该类时会延迟加载该文件。这给了我第一次使用类的事件。
spl_autoload_register(function($class) {
include_once './' . $class . '.php';
if (method_exists($class, 'construct')) {
$class::construct();
}
});
我在静态方法中将类属性定义为数组,并通过该方法调用它们。我不确定这是否是最好的解决方案,但效果很好。
示例:
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