PHP - Indirect modification of overloaded property

前端 未结 8 1613
悲哀的现实
悲哀的现实 2020-11-28 08:38

I know this question has been asked several times, but none of them have a real answer for a workaround. Maybe there\'s one for my specific case.

I\'m building a map

相关标签:
8条回答
  • 2020-11-28 09:14

    Though I am very late in this discussion, I thought this may be useful for some one in future.

    I had faced similar situation. The easiest workaround for those who doesn't mind unsetting and resetting the variable is to do so. I am pretty sure the reason why this is not working is clear from the other answers and from the php.net manual. The simplest workaround worked for me is

    Assumption:

    1. $object is the object with overloaded __get and __set from the base class, which I am not in the freedom to modify.
    2. shippingData is the array I want to modify a field of for e.g. :- phone_number

     

    // First store the array in a local variable.
    $tempShippingData = $object->shippingData;
    
    unset($object->shippingData);
    
    $tempShippingData['phone_number'] = '888-666-0000' // what ever the value you want to set
    
    $object->shippingData = $tempShippingData; // this will again call the __set and set the array variable
    
    unset($tempShippingData);
    

    Note: this solution is one of the quick workaround possible to solve the problem and get the variable copied. If the array is too humungous, it may be good to force rewrite the __get method to return a reference rather expensive copying of big arrays.

    0 讨论(0)
  • 2020-11-28 09:14

    This is occurring due to how PHP treats overloaded properties in that they are not modifiable or passed by reference.

    See the manual for more information regarding overloading.

    To work around this problem you can either use a __set function or create a createObject method.

    Below is a __get and __set that provides a workaround to a similar situation to yours, you can simply modify the __set to suite your needs.

    Note the __get never actually returns a variable. and rather once you have set a variable in your object it no longer is overloaded.

    /**
     * Get a variable in the event.
     *
     * @param  mixed  $key  Variable name.
     *
     * @return  mixed|null
     */
    public function __get($key)
    {
        throw new \LogicException(sprintf(
            "Call to undefined event property %s",
            $key
        ));
    }
    
    /**
     * Set a variable in the event.
     *
     * @param  string  $key  Name of variable
     *
     * @param  mixed  $value  Value to variable
     *
     * @return  boolean  True
     */
    public function __set($key, $value)
    {
        if (stripos($key, '_') === 0 && isset($this->$key)) {
            throw new \LogicException(sprintf(
                "%s is a read-only event property", 
                $key
            ));
        }
        $this->$key = $value;
        return true;
    }
    

    Which will allow for:

    $object = new obj();
    $object->a = array();
    $object->a[] = "b";
    $object->v = new obj();
    $object->v->a = "b";
    
    0 讨论(0)
提交回复
热议问题