Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__set/__get with array properties

Tags:

php

Wondering if it's possible to do something like the following (I know the code won't work as intended, just trying to get the purpose across):

class Form
{
    private $v = array();

    function __set($varName, $varValue)
    {
        ... do some treatment on the varValue ...
        $this->v[$varName] = $varValue;
    }

    function &__get($varName)
    {
        if(!isset($this->v[$varName]))
            $this->v[$varName] = NULL;

        return $this->v[$varName];
    }
};

I want to be able to set a variable like:

$form->Values['whatever'] = 'dirty';

and have it run through the setter function which would call some cleaning operations and actually end up filling a couple other arrays like 'HtmlValues' and 'SqlValues' so I can just pull the values encoded for the format I want, so I can later call

echo $form->HtmlValues['whatever'];

The problem is of course the normal issue that if you just use _get, you get end up setting a value that's returned, and even though &_get returns it by reference and thing kind of work, __set is never actually called, even though you're setting a private member.

So basically, I'm wondering if there's a way to call a function on a value whenever you set it within an array (potentially multiple arrays deep and what not like $form->Values['group']['item'] = 'whatever';

The desired output would be something like:

$form->Values['name'] = "&";
echo $form->HtmlValues['name']; = &

(Just to reinforce, I'm not looking for the actual encoding, just the ability to call it on every variable as it's set/changed without having to encode the entire array manually)

like image 527
John Avatar asked May 09 '11 16:05

John


People also ask

What is __ get?

__get() is utilized for reading data from inaccessible properties.

What is the magic method in PHP?

Magic methods in PHP are special methods that are aimed to perform certain tasks. These methods are named with double underscore (__) as prefix. All these function names are reserved and can't be used for any purpose other than associated magical functionality. Magical method in a class must be declared public.


2 Answers

You want to implement the ArrayAccess interface. the linked page has examples on how to do this.

EDIT: For ease of access, I have included the example from php.net below:

<?php
class obj implements arrayaccess {
    private $container = array();
    public function __construct() {
        $this->container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }
    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }
    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }
    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>
like image 125
Jonathan Fingland Avatar answered Sep 23 '22 06:09

Jonathan Fingland


Take a look at ArrayAccess.

like image 34
Alin Purcaru Avatar answered Sep 21 '22 06:09

Alin Purcaru