Я буду, вероятно, гореться для этого, но какой смысл того, чтобы тестировать на существование, если Вы просто соберетесь удалить его? Один из моих главных главных объектов неприязни является приложением, бросающим ошибочное диалоговое окно с чем-то как, "Невозможно удалить файл, он не существует!"
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.
, Если файл не существует во-первых, выполненная миссия!
Невозможно предотвратить вызов конструктора при создании объекта (строка 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');
Это может иметь смысл, если вы имеете дело с некоторым кодом, который вы не можете изменить по какой-либо причине и который должен работать вокруг некоторого раздражающего поведения плохо написанного конструктора.
Если отделение создания экземпляра от инициализации не является строго обязательным требованием, есть две другие возможности: во-первых, статический фабричный метод.
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, великолепен, если по какой-то причине вам необходимо логически отделить инициализацию от создания экземпляра, но если поддержка вашего варианта использования выше является особым случаем, а не обычным требованием , может быть неудобно требовать, чтобы пользователи создавали и инициализировали ваш объект в два отдельных шага.
Фабричный метод хорош тем, что дает вам метод для вызова для получения инициализированного экземпляра. Однако объект инициализируется и создается в одной и той же операции, поэтому, если вам нужно разделить их, это не сработает.
И, наконец,
, чтобы сначала создать объект, а затем передать параметры, которые вы могли бы попробуйте этот способ:
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);
позже.
Обратите внимание, что если конструктор (метод __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);