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();
    }
});