PHP 构造函数和静态函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8231198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP constructors and static functions
提问by bar1024
I'm a bit confused on how constructors work in PHP.
我对构造函数在 PHP 中的工作方式有些困惑。
I have a class with a constructor which gets called when I instantiate a new object.
我有一个带有构造函数的类,当我实例化一个新对象时,它会被调用。
$foo = new Foo($args);
__construct($params)
is called in the class Foo
and it executes the appropriate initialization code.
__construct($params)
在类中调用Foo
并执行适当的初始化代码。
However when I use the class to call a static function, the constructor is called again.
但是,当我使用该类调用静态函数时,会再次调用构造函数。
$bar = Foo::some_function(); //runs the constructor from Foo
This causes the constructor to execute, running the object initialization code that I intended only for when I create a new Foo
object.
这会导致构造函数执行,运行我只打算在创建新Foo
对象时使用的对象初始化代码。
Am I missing the point of how constructors work? Or is there a way to prevent __construct()
from executing when I use the class to make static function calls?
我是否错过了构造函数如何工作的重点?或者有没有办法__construct()
在我使用类进行静态函数调用时阻止执行?
Should I use a "factory" function instead to do the object initialization? If so, what's the point of the constructor then?
我应该使用“工厂”函数来进行对象初始化吗?如果是这样,那么构造函数的意义何在?
::EDIT:: I have a form where users can upload photos to an album (create_photo.php) and an area where they can view the album (view_photos.php). Upon form submit:
::EDIT:: 我有一个表单,用户可以在其中将照片上传到相册 (create_photo.php) 和一个可以查看相册的区域 (view_photos.php)。在表单提交时:
$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..);
The Photo constructor creates and saves the photo. However in view_photo.php, when I call:
Photo 构造函数创建并保存照片。但是在 view_photo.php 中,当我调用时:
$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database
This is causing Photo's constructor to run!
这导致 Photo 的构造函数运行!
回答by Naftali aka Neal
I see nothing that replicates your question.
我看不到任何可以复制您的问题的内容。
See Demo: http://codepad.org/h2TMPYUV
见演示:http: //codepad.org/h2TMPYUV
Code:
代码:
class Foo {
function __construct(){
echo 'hi!';
}
static function bar(){
return 'there';
}
}
echo Foo::bar(); //output: "there"
回答by Ivan Buttinoni
Assumption PHP 5.x
假设 PHP 5.x
Different goals, different path
不同的目标,不同的道路
create a new instance of a class (object)
class myClassA { public $lv; public function __construct($par) { echo "Inside the constructor\n"; $this->lv = $par; } } $a = new myClassA(11); $b = new myClassA(63);
because we create a new object PHP calls:
__construct($par)
;of the new object, so:
$a->lv == 11 $b->lv == 63
use a function of a class
class myClassB { public static $sv; public static function psf($par) { self::$sv = $par; } } myClassB::psf("Hello!"); $rf = &myClassB::$sv; myClassB::psf("Hi.");
now
$rf == "Hi."
function or variabiles must defined static to be accessed by
::
, no object is created calling "psf", the "class variable" svhas only 1 instance inside the class.use a singleton created by a Factory (myClassA is above)
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";
创建一个类(对象)的新实例
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 个实例。使用由工厂创建的单例(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";
Using the factory (getInstance) the first time we construct a new object having $parset to gino.
我们第一次使用工厂(getInstance)构造一个$par设置为gino的新对象。
Using the factory the second time $singletonhas already a value that we return. No new object is created (no __constructis called, less memory & cpu is used).
第二次使用工厂$singleton已经有一个我们返回的值。没有创建新对象(没有调用__construct,使用更少的内存和 CPU)。
The value of course is an object instanceOfmyClassA and don't forget:
值当然是一个对象instanceOfmyClassA 并且不要忘记:
myClassC::$singleton->lv == "gino"
myClassC::$singleton->lv == "gino"
Pay attention to singletons:
注意单身人士:
What is so bad about singletons?
http://www.youtube.com/watch?v=-FRm3VPhseI
http://www.youtube.com/watch?v=-FRm3VPhseI
By my answer I don't want promote/demote singleton. Simply from the words in the question, I made this calc:
根据我的回答,我不想提升/降级单身人士。简单地从问题中的话,我做了这个计算:
"static"+"__construct"="singleton"!
“静态”+“__construct”=“单例”!
回答by Martin
Here is my workaround:
这是我的解决方法:
I put method construct()
in static class. Notice, it is different than __construct()
which I use in regular classes.
我把方法construct()
放在静态类中。请注意,它与__construct()
我在常规课程中使用的不同。
Each class is in own file, so I lazy load that file on first use of class. This gives me event of first use of class.
每个类都在自己的文件中,所以我在第一次使用类时延迟加载该文件。这给了我第一次使用类的事件。
spl_autoload_register(function($class) {
include_once './' . $class . '.php';
if (method_exists($class, 'construct')) {
$class::construct();
}
});
回答by senera
I define class properties as array in a static method and call them via the method. I'm not sure if it's the best solution or not but works great.
我在静态方法中将类属性定义为数组,并通过该方法调用它们。我不确定这是否是最好的解决方案,但效果很好。
Example:
例子:
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