问题
I'm a bit confused on how constructors work in 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.
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.
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?
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:
$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 = Photo::find_by_id($_POST['id']) //user-defined function to query database
This is causing Photo's constructor to run!
回答1:
I see nothing that replicates your question.
See Demo: http://codepad.org/h2TMPYUV
Code:
class Foo {
function __construct(){
echo 'hi!';
}
static function bar(){
return 'there';
}
}
echo Foo::bar(); //output: "there"
回答2:
Assumption 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" sv has 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";
Using the factory (getInstance) the first time we construct a new object having $par set to gino.
Using the factory the second time $singleton has already a value that we return. No new object is created (no __construct is called, less memory & cpu is used).
The value of course is an object instanceOf myClassA and don't forget:
myClassC::$singleton->lv == "gino"
Pay attention to singletons:
What is so bad about singletons?
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"!
回答3:
Here is my workaround:
I put method construct()
in static class. Notice, it is different than __construct()
which I use in regular classes.
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();
}
});
回答4:
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
来源:https://stackoverflow.com/questions/8231198/php-constructors-and-static-functions