Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP assign value to $this

Tags:

oop

php

this

Basically what I'm trying to achieve is to make the object reference another object of the same class - from inside of a method. It'd be perfect if the following would work:

$this = new self;

But one cannot reassign $this in php.

I of course know, I can return another object from the method and use that, so please do not advise that. The question is:

How can I make $this to be a clone of another object of the same class?

or more specifically,

I want an object to revert to a specific state that was previously saved.


EDIT: some examples where this might be useful.

Say you have an Url object that accepts controller, action and lots more things. You are going to have it fetch a lot of links with the same, say, controller and action, but other properties will differ. I instantiate the object with the common parameters, call a method for it to save its state which it reverts to after outputting a link (IOW after __toString method).

$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

Another use is I have a CRUD table and I have to configure each column as an object I pass to the main table object. After passing the column I launch a reset method on the column, so I can have code like the following:

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

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

In both situations I save a lot of code and confusion, don't you think?

like image 659
raveren Avatar asked Aug 10 '26 01:08

raveren


1 Answers

I see a huge problem with what you're intending:

If you found a way to reassign $this, how do you make sure, that anybody using your class knows how it behaves? While I admit, that it's kinda interesting to do

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

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

What happens, if I need $column twice?

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

...

You would break the expected behaviour and imho make it extremely hard to grasp your code.


But to give some ideas on how to still achieve the aforementioned behaviour:
// 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));


Otherwise the reset() method also sounds feasible:
class Column() {

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

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

}

This way you could use it like so:

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


To overcome the problem of specifying the default values twice (untested):
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;
    }

}
like image 186
Dan Soap Avatar answered Aug 11 '26 14:08

Dan Soap



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!