PHP [ООП] - Как назвать конструктора класса вручную?

Я буду, вероятно, гореться для этого, но какой смысл того, чтобы тестировать на существование, если Вы просто соберетесь удалить его? Один из моих главных главных объектов неприязни является приложением, бросающим ошибочное диалоговое окно с чем-то как, "Невозможно удалить файл, он не существует!"

On Error Resume Next
aFile = "c:\file_to_delete.txt"
Kill aFile
On Error Goto 0
return Len(Dir$(aFile)) > 0 ' Make sure it actually got deleted.

, Если файл не существует во-первых, выполненная миссия!

11
задан A.N.M. Saiful Islam 14 December 2009 в 06:44
поделиться

4 ответа

Невозможно предотвратить вызов конструктора при создании объекта (строка 9 в вашем коде). Если в вашем методе __ construct () есть какие-то функциональные возможности, которые вы хотите отложить до завершения построения, вам следует переместить их в другой метод. Хорошим названием для этого метода может быть init () .

Почему бы просто не сделать это?

class Test {
    public function __construct($param1, $param2, $param3) {
        echo $param1.$param2.$param3;
    }
}

$ob = new Test('p1', 'p2', 'p3');

РЕДАКТИРОВАТЬ: Я просто подумал о хакерском способе, с помощью которого вы могли бы предотвратить вызов конструктора (вроде как ). Вы можете создать подкласс Test и переопределить конструктор с помощью пустого, ничего не делающего конструктора.

class SubTest extends Test {
    public function __construct() {
        // don't call parent::__construct()
    }

    public function init($param1, $param2, $param3) {
        parent::__construct($param1, $param2, $param3);
    }
}

$ob = new SubTest();
$ob->init('p1', 'p2', 'p3');

Это может иметь смысл, если вы имеете дело с некоторым кодом, который вы не можете изменить по какой-либо причине и который должен работать вокруг некоторого раздражающего поведения плохо написанного конструктора.

23
ответ дан 3 December 2019 в 02:10
поделиться

Если отделение создания экземпляра от инициализации не является строго обязательным требованием, есть две другие возможности: во-первых, статический фабричный метод.

class Test {
    public function __construct($param1, $param2, $param3) {
        echo $param1.$param2.$param3;
    }

    public static function CreateTest($param1, $param2, $param3) {
        return new Test($param1, $param2, $param3);
    }
}

$params = array('p1','p2','p3');

if(method_exists($ob,'__construct')) {
    call_user_func_array(array($ob,'CreateTest'),$params);
}

Или, если вы используете php 5.3.0 или выше, вы можете использовать лямбда:

class Test {
    public function __construct($param1, $param2, $param3) {
        echo $param1.$param2.$param3;
    }
}

$params = array('p1','p2','p3');

$func = function ($arg1, $arg2, $arg3) {
    return new Test($arg1, $arg2, $arg3);
}

if(method_exists($ob,'__construct')) {
    call_user_func_array($func, $params);
}

Метод инициализации, описанный Asaph, великолепен, если по какой-то причине вам необходимо логически отделить инициализацию от создания экземпляра, но если поддержка вашего варианта использования выше является особым случаем, а не обычным требованием , может быть неудобно требовать, чтобы пользователи создавали и инициализировали ваш объект в два отдельных шага.

Фабричный метод хорош тем, что дает вам метод для вызова для получения инициализированного экземпляра. Однако объект инициализируется и создается в одной и той же операции, поэтому, если вам нужно разделить их, это не сработает.

И, наконец,

1
ответ дан 3 December 2019 в 02:10
поделиться

, чтобы сначала создать объект, а затем передать параметры, которые вы могли бы попробуйте этот способ:

class Test {
    public function __CONSTRUCT($p1="Bundy", $p2="house", $p3=10) {
        $this->init($p1, $p2, $p3);
    }
    public function init($p1, $p2, $p3) {
        //setup your object here
    }
}

тогда можно построить объект и вызвать

$ob->init($p1, $p2, $p3);

позже.

0
ответ дан 3 December 2019 в 02:10
поделиться

Обратите внимание, что если конструктор (метод __construct) содержит аргументы, переданные ссылка, то функция:

call_user_func_array

завершится с ошибкой.

Я предлагаю вам использовать вместо этого класс Reflection; вот как это можно сделать:

// assuming that class file is already included.

$refMethod = new ReflectionMethod('class_name_here',  '__construct');
$params = $refMethod->getParameters();

$re_args = array();

foreach($params as $key => $param)
{
    if ($param->isPassedByReference())
    {
        $re_args[$key] = &$args[$key];
    }
    else
    {
        $re_args[$key] = $args[$key];
    }
}

$refClass = new ReflectionClass('class_name_here');
$class_instance = $refClass->newInstanceArgs((array) $re_args);
9
ответ дан 3 December 2019 в 02:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: