PHP-конструкторы и статические функции
Я немного смущен тем, как работают конструкторы в PHP.
У меня есть класс с конструктором, который вызывается при создании нового объекта.
$foo = new Foo($args);
__construct($params)
вызывается в классе Foo
и выполняет соответствующий код инициализации.
Однако, когда я использую класс для вызова статической функции, конструктор снова вызывается.
$bar = Foo::some_function(); //runs the constructor from Foo
Это заставляет конструктор выполнить, запустив код инициализации объекта, который я имел в виду только при создании нового объекта Foo
.
Неужели я не понимаю, как работают конструкторы? Или существует способ предотвратить выполнение __construct()
, когда я использую класс для вызова статических функций?
Следует ли использовать функцию "factory" для инициализации объекта? Если да, то какая точка конструктора тогда?
:: EDIT::
У меня есть форма, в которой пользователи могут загружать фотографии в альбом (create_photo.php) и область, где они могут просматривать альбом (view_photos.php). По форме submit:
$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..);
Конструктор фотографий создает и сохраняет фотографию. Однако в view_photo.php, когда я звоню:
$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database
Это вызывает запуск конструктора фотографий!
Ответы
Ответ 1
Я ничего не вижу, что реплицирует ваш вопрос.
См. демонстрацию: http://codepad.org/h2TMPYUV
код:
class Foo {
function __construct(){
echo 'hi!';
}
static function bar(){
return 'there';
}
}
echo Foo::bar(); //output: "there"
Ответ 2
Успенская
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 экземпляр внутри класса.
-
используйте одноэлемент, созданный Factory (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";
Используя Factory (getInstance), мы впервые создаем новый объект, имеющий $par, установленный в gino.
Используя Factory, второй раз $singleton уже имеет значение, которое мы возвращаем. Новый объект не создается (не вызывается __construct, используется меньше памяти и процессора).
Значение курса - это объект instanceOf myClassA и не забывайте:
myClassC::$singleton->lv == "gino"
Обратите внимание на одноточие:
Что так плохо о одиночных играх?
http://www.youtube.com/watch?v=-FRm3VPhseI
По моему ответу я не хочу продвигать /demote singleton. Просто из слов в вопросе, я сделал это calc:
"статические" + "__ конструкт" = "синглтон"!
Ответ 3
Вот мой обходной путь:
Я ставил метод construct()
в статическом классе. Обратите внимание, что он отличается от __construct()
, который я использую в обычных классах.
Каждый класс находится в собственном файле, поэтому я lazy загружаю этот файл при первом использовании класса. Это дает мне возможность первого использования класса.
spl_autoload_register(function($class) {
include_once './' . $class . '.php';
if (method_exists($class, 'construct')) {
$class::construct();
}
});