T
T
ThunderCat2018-08-14 17:22:30
PHP
ThunderCat, 2018-08-14 17:22:30

"lazy" __set(), any ideas?

Actually, there is an array inside the class, into which data is often written / read in the code, of the form: for reading, I slapped a quick getter:
$this->fields['somefield'] = $someVal;

public function __get($name){
        if($name == 'f'){
            return (object) $this->fields;
        }
        else return false;
    }

and now $this->f->somefield nicely returns the value from the array by key.
and with a setter like $this->f->somefield = $someval; something I'm stupid ... Help ...
PS: thank you all, again I caught myself on the fact that not always obvious small details change the picture as a whole. Perversion is needed to redefine keys from several third-party APIs with a large number of fields, so the code turns out to be boring, nasty, monotonous and sheet-like. I wanted to simplify the manual work a little.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexander, 2018-08-14
@ThunderCat

spoiler
<?php

class My {
    private $fields = [
        'hello' => 'world'
    ];
    public function f() {
        return $this;
    }
    public function __get($name) {
        if($name == 'f') {
            return (object) $this->fields;
        }
    }
    public function __set($name, $value) {
        $this->fields[$name] = $value;
    }
    public function printFields() {
        print_r($this->fields);
    }
}

$my = new My();

$my->f()->jetpack = 'azaza';
$my->printFields();

I
Immortal_pony, 2018-08-14
@Immortal_pony

The setter must be in the class that you give through the "quickly sloppy getter". And you have stdClass there.
You can do, for example, like this:

<?php
class Fields
{
    protected $parent;
    
    public function __construct(\Data &$parent) 
    {
        $this->parent = $parent;
    }
    
    public function __get($name) 
    {
        return array_key_exists($name, $this->parent->fields) ? $this->parent->fields[$name] : false;
    }

    public function __set($name, $value) {
        $this->parent->fields[$name] = $value;
    }
}

class Data
{
    public $fields = [
        'foo' => "bar"
    ];
    
    public function __get($name){
        if($name == 'f'){
            return new \Fields($this);
        }
        else {
            return false;
        }
    }
}

$data = new Data();
$data->f->testInfo = "test passed";
echo $data->fields['testInfo']; // выведет "test passed"

S
Stanislav B, 2018-08-14
@S_Borchev

$this->f->somefield beautifully returns the value from the array by key.

please don't do that. This is a completely optional obfuscation of the program. Minimum pluses.
Your best bet is to remove __get and keep using $this->fields['somefield'] = $someVal;
UPD
like this, but why
class Shit 
{
    private $fields = [];

    public function __get($name){
        if($name !== 'f') {
            return false;
        }

        return new class($this->fields) {
            private $fields;

            public function __construct(&$fields)
            {
                $this->fields = &$fields;
            }

            public function __get($name)
            {
                return $this->fields[$name];
            }

            public function __set($name, $value)
            {
                $this->fields[$name] = $value;
            }

            public function __isset($name)
            {
                return isset($this->fields[$name]);
            }
        };
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question