PHP присваивает значение $ this - PullRequest
3 голосов
/ 27 октября 2010

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

$this = new self;

Но никто не может переназначить $this в php.

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

Как я могу сделать $this клоном другого объекта того же класса?

или, более конкретно,

Я хочуобъект, чтобы вернуться к определенному состоянию, которое было ранее сохранено.


РЕДАКТИРОВАТЬ : некоторые примеры, где это может быть полезно.

Скажем, у вас есть объект Url, который принимает контроллер, действие и многое другое.Вы получите много ссылок с одним и тем же, скажем, контроллером и действием, но другие свойства будут отличаться.Я создаю экземпляр объекта с общими параметрами, вызываю для него метод, чтобы сохранить его состояние, к которому он возвращается после вывода ссылки (IOW после метода __toString).

$defaultPath = Url::factory('controller','action1')->extraParams('status',0)->save();

echo $defaultPath->action('action2'); // this has action2 as action and a status 0 as extra params
echo $defaultPath->extraParams('status',2); // this has action1 as action and 2 as status

Другое использование - у меня есть таблица CRUD, и я должен настроить каждый столбец как объект, который я передаю объекту основной таблицы.Пройдя столбец, я запускаю метод сброса для столбца, чтобы у меня мог быть код, подобный следующему:

    $column->field = 'layouts_id';
    $column->value = $layoutId;
    $dbInput->addColumn($column);

    $column->field = 'pages_id';
    $column->value = $pagesId;
    $dbInput->addColumn($column);

В обеих ситуациях я сохраняю много кода и путаницу, не правда ли?

Ответы [ 5 ]

3 голосов
/ 27 октября 2010

Я вижу огромную проблему с тем, что вы намереваетесь:

Если вы нашли способ переназначить $this, как вы можете быть уверены, что любой, кто использует ваш класс, знает, как он себя ведет?Хотя я признаю, что это интересно сделать

$column->field = 'layouts_id';
$column->value = $layoutId;
$dbInput->addColumn($column);

$column->field = 'pages_id';
$column->value = $pagesId;
$dbInput->addColumn($column);

Что произойдет, если мне понадобится $column дважды?

$column->field = 'layouts_id';
$column->value = $layoutId;
$dbInput->addColumn($column);
// log my value
$logger->log($column); // oops, it's empty

...

Вы нарушите ожидаемое поведение и, по моему мнению, сделаете его чрезвычайноТрудно понять ваш код.Но чтобы дать некоторые идеи о том, как все же достичь вышеупомянутого поведения:

// clone when passing on
$column->field = 'value_id';
$column->value = $value;
$dbInput->addColumn(clone $column);

// manually (re-)create a new object based on an older
$column->field = 'value_id';
$column->value = $value;
$dbInput->addColumn(new Column($column));

В противном случае метод reset() также звучит выполнимо:

class Column() {

    public function reset() {
        $this->field = 'standard field id';
        $this->value = 'standard field value';
    }

    public function __construct() {
        $this->reset();
    }

}

Таким образом, вы можете использовать его следующим образом:

// manually (re-)create a new object based on an older
$column->field = 'value_id';
$column->value = $value;
$dbInput->addColumn($column);
$column->reset();

Чтобы преодолеть проблему указания значений по умолчанию дважды (не проверено):

class Column() {

    public $field = 'standard field id';
    public $value = 'standard field value';

    // keep a static object for resetting
    private static $__blueprint = null;

    public function reset() {
        foreach (self :: $__blueprint as $k => $v)
            $this->$k = $v;
    }

    public function __construct() {
        if (!isset(self :: $__blueprint))
            self :: $__blueprint = clone $this;
    }

}
2 голосов
/ 27 октября 2010

если ваш гипотетический пример $this = new self; сработал, он, вероятно, был бы предназначен для эффективного сброса объекта в чистое состояние.

Вы не можете добиться этого так, как вы просили, но вы, несомненно, можете сделать это довольно легко, написав метод reset(), который устанавливает все свойства в начальное состояние и затем вызывает метод __constructor().

Если вы хотите пойти дальше и клонировать другой экземпляр класса изнутри объекта, который станет клоном (согласно последней части вашего вопроса), это будет намного сложнее. Вы, конечно, не сможете сделать это хорошим способом. Возможно, вам удастся настроить его, написав метод, который принимает клонируемый объект в качестве параметра и устанавливает все свойства текущего объекта в свойствах другого объекта по ссылке. Конечно, это было бы возможно только в том случае, если бы все свойства были общедоступными, но вы можете попробовать это. Конечно, не идеально, хотя. Гораздо лучше сделать это просто снаружи любого из объектов ... но вы сказали, что не предлагайте этого ...;)

1 голос
/ 27 октября 2010

Я думаю, что вы на самом деле получаете шаблон проектирования мухи . Вы не делаете это путем повторного сопоставления $this, но вы создаете свои объекты таким образом, чтобы их можно было повторно использовать без необходимости постоянно создавать и разрушать их ...

Соедините это с Пулом объектов Шаблон дизайна, и вы должны быть золотыми ...

1 голос
/ 27 октября 2010

Вы не можете присвоить значение $this в PHP. Он всегда будет содержать текущий объект, и его нельзя изменить.

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

Лучшее решение, которое я могу придумать, - это иметь в своем классе переменную-член $copy. Затем вы можете проверить, является ли $copy ненулевым, и вместо этого пройти через все методы к этому объекту. Тем не менее, это все равно оставит вас с вашим оригинальным объектом в памяти.

1 голос
/ 27 октября 2010

То, что вы спрашиваете, не имеет смысла в ООП. Переменная this (или ее эквивалент на выбранном вами языке ООП) всегда должна указывать на текущий экземпляр и никогда не должна изменяться. Вот для чего он предназначен.

...