ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer

"ленивый" __set(), есть идеи?

Собствено внутри класса есть массив, в который часто пишутся / читаются данные в коде, вида:
$this->fields['somefield'] = $someVal;
для чтения я сляпал быстрый геттер:
public function __get($name){
        if($name == 'f'){
            return (object) $this->fields;
        }
        else return false;
    }

и теперь $this->f->somefield красиво отдает из массива значение по ключу.
а с сеттером в стиле $this->f->somefield = $someval; что-то я туплю... Хелп...

ПС: всем спасибо, опять же поймал себя на том что не всегда очевидные мелкие детали меняют картину в целом. Изврат нужен для переопределения ключей от нескольких сторонних апи с большим количеством полей, по этому код выходит скучный, мерзкий, однообразный и простынеподобный. Захотелось слегка упростить ручную работу.
  • Вопрос задан
  • 371 просмотр
Решения вопроса 1
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();
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Immortal_pony
@Immortal_pony Куратор тега PHP
Сеттер должен быть у того класса, который вы отдаете через "быстро сляпанный геттер". А у вас там stdClass.
Можно сделать, например, так:
<?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"
Ответ написан
$this->f->somefield красиво отдает из массива значение по ключу.

пожалуйста не делайте так. Это абсолютно необязательное запутывание программы. Плюсов минимум.
Лучше всего - удалить __get и продолжайте использовать $this->fields['somefield'] = $someVal;

UPD
например так, но зачем
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]);
            }
        };
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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