040ffc7f3327b05f01c54a8bef3ba60a

This class lets you handle basic getting & setting of class properties without having to declare methods for each property.

All methods that start with "get" or "set" (that aren't already declared) are routed through to __call magic method and then values are set & retrieved from an associative array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
class PropertyHandler 
{
    const GET_REGEX = "^get([aA-zZ0-9_]+)$";
    const SET_REGEX = "^set([aA-zZ0-9_]+)$";

    private $props;

    function __construct()
    {
        $props = array();
    }

    public function __call($method, $arguments)
    {
        if($this->isGetMethod($method))
        {
            return $this->execGetMethod($method);
        }elseif($this->isSetMethod($method))
        {
            return $this->execSetMethod($method, $arguments);
        }else
        {
            throw new Exception("Unhandled method $method");
        }
    }

    private function isGetMethod($method)
    {
        return $this->isTypeMethod($method, self::GET_REGEX);
    }

    private function isSetMethod($method)
    {
        return $this->isTypeMethod($method, self::SET_REGEX);
    }

    private function isTypeMethod($method, $regex)
    {
        return (preg_match("/$regex/", $method) > 0);
    }

    private function execGetMethod($method)
    {
        $matches = array();

        preg_match("/" . self::GET_REGEX . "/", $method, $matches);
        if(count($matches) > 0)
        {
            return $this->getProp($matches[1]);
        }
    }

    private function execSetMethod($method, $arguments)
    {
        if(count($arguments) > 1)
        {
            throw new Exception("Set methods are not allowed to take more than one argument");
        }

        $matches = array();

        preg_match("/" . self::SET_REGEX . "/", $method, $matches);
        if(count($matches) > 0)
        {
            $this->setProp($matches[1], $arguments[0]);
        }
    }

    public function setProp($propName, $propVal)
    {
        if(!$propName)
        {
            throw new Exception("Invalid empty property name");
        }

        $this->props[$propName] = $propVal;
    }

    public function getProp($propName)
    {
        if(isset($this->props[$propName]))
        {
            return $this->props[$propName];
        }
    }
}

/**
 *  Very simple example
 */
class PropTest extends PropertyHandler
{
  public function __construct()
  {
    parent::__construct();
  }
}

$props = new PropTest();

//Notice that neither PropTest nor PropertyHandler actually have setFirstName or getFirstNames
//These are setting and retrieving associative the associative array value with key "FirstName"
$props->setFirstName('Mark');
echo $props->getFirstName();
?>

Refactorings

No refactoring yet !

Avatar

exil.myopenid.com

September 15, 2008, September 15, 2008 22:13, permalink

No rating. Login to rate!

Great code, but it has a lot of unnecessary overhead, since it forms the base/core class that all other classes take functionality from, this overhead will be exponential - pretty code must take a backseat here, stability and speed must be the overall implementation goal.

First I would strongly advise against such usage of regex's, and I would also re-consider breaking it down so much.

Here is my take on it, I bashed this up and tested it with your above example, using a loop to execute it 100,000 times, it took half the time - (I know its missing the getProp() function etc, but they're easily added)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php

	/**
	 * This class implements auto-getter and setters by making using of PHP magic __call() method..
	 */
	class PropertyHandler 
	{
	    private $props;
	
	    function __construct()
	    {
	        $props = array();
	    }
	
	    public function __call($method, $arguments)
	    {
	    	// Handle Setters....
	    	if(strpos($method, "set") === 0)
		{
			$param = substr($method, 3, strlen($method));

			if(!strlen($param))
			{
				throw new Exception("Invalid or empty property name");
			}
				
			if(!count($arguments))
			{
				throw new Exception("Not allowed more than 1 argument..");
			}

			$this->props[$param] = $arguments[0];
		}
			
		// Handle Getters....
		elseif(strpos($method, "get") === 0)
		{
			$param = substr($method, 3, strlen($method));
			
			if(strlen($param) == 0)
			{
				throw new Exception("Invalid or empty property name");
			}
				
				return $this->props[$param];
			}
			
			// No manageable type found? thats fatal..
		else
	        {
			throw new Exception("Unhandled method $method");
	        }
	    }
	}
	
	/**
	 *  Very simple example
	 */
	class PropTest extends PropertyHandler
	{
	  public function __construct()
	  {
	    parent::__construct();
	  }
	}
	
	
	for($i = 0; $i < 100000; $i++)
	{
		$props = new PropTest();
		$props->setFirstName('Mark');
		$props->getFirstName();
	}

?>
1bf59120892e34eb60836725566c6e55

fain182.myopenid.com

November 13, 2008, November 13, 2008 11:16, permalink

No rating. Login to rate!

it isn't better to use __get and __set?

Your refactoring





Format Copy from initial code

or Cancel