Я немного смущен тем, как работают конструкторы в 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). По форме 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
Это вызывает запуск конструктора 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 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."
функция или variabiles должны быть определены как static, к которым должен обращаться ::
, не создается объект, вызывающий «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 , используется меньше памяти и процессора).
Значение курса – объект instanceOf myClassA и не забывайте:
myClassC::$singleton->lv == "gino"
Обратите внимание на одноточие:
Что так плохо о одиночных играх?
http://www.youtube.com/watch?v=-FRm3VPhseI
По моему ответу я не хочу продвигать / demote singleton. Просто из слов в вопросе, я сделал это calc:
"Статические" + "__ конструкт" = "синглтон"!
Вот мое обходное решение :
Я поставил метод construct()
в статическом классе. Обратите внимание, что он отличается от __construct()
который я использую в обычных классах.
Каждый класс находится в собственном файле, поэтому я lazy загружаю этот файл при первом использовании класса. Это дает мне возможность первого использования класса.
spl_autoload_register(function($class) { include_once './' . $class . '.php'; if (method_exists($class, 'construct')) { $class::construct(); } });