{"id":35,"date":"2008-03-30T11:41:18","date_gmt":"2008-03-30T16:41:18","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/2008\/03\/30\/php5-singleton-pattern-with-magic-__get-and-__set\/"},"modified":"2014-03-16T12:19:09","modified_gmt":"2014-03-16T17:19:09","slug":"php5-singleton-pattern-with-magic-__get-and-__set","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2008\/03\/30\/php5-singleton-pattern-with-magic-__get-and-__set\/","title":{"rendered":"Php5 Simple Singleton Design Pattern"},"content":{"rendered":"<p>I wanted to reproduce a simple singleton design pattern in PHP 5. After reviewing many overly complex examples, I synthesized to this example.<\/p>\n<p>It also makes use of the PHP5 magic function __get and __set also poorly addressed in web postings. Going for cleaner code I like to see $obj-&gt;prop rather than $obj-&gt;getProp() and $obj-&gt;setProp(value) in the code. But I am greedy and want to have read only and write only props. So I configured the various examples to achieve that goal. As well you can see in the __set and __get methods you may choose to work the props or call a private method that would handle the validation and proper handling of the set and return values. I demonstrated this here.<\/p>\n<p>This is the singleton running with the idea of a single configuration object for an application. It only has one real property named isDebugging for the example.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">&lt;?php\r\nclass Config\r\n\tstatic private $_instance;\r\n    private $isDebugging = false; \/\/ Read write\r\n\tprivate $version = &quot;1.1&quot;   ;  \/\/ Read only\r\n\tprivate $cannotReadProp = &quot;x&quot; ;\r\n\tpublic static function getInstance($args = array())\r\n\t{\r\n\t\tif(!self::$_instance)\r\n\t\t{\r\n\t\t\tself::$_instance = new Config();\r\n\t\t}\r\n\t\tself::$_instance-&gt;setIsDebugging(isset($args&#x5B;'isDebugging']) ? $args&#x5B;'isDebugging'] : self::$_instance-&gt;isDebugging);\r\n\t\treturn self::$_instance;\r\n\t}\r\n\tprivate static function setIsDebugging($value)\r\n\t{\r\n\t\tself::$_instance-&gt;isDebugging = is_bool($value)? $value: self::$_instance-&gt;isDebugging;\r\n\t}\r\n\tpublic static function __set($prop, $value)\r\n\r\n\t\tif (isset(self::$_instance-&gt;$prop)\r\n\t\t{\r\n\t\t\tswitch ($prop)\r\n\t\t\t{\r\n\t\t\t\tcase 'isDebugging':\r\n\t\t\t\t\tself::$_instance-&gt;setIsDebugging($value);\r\n\t\t\t\t\tbreak\r\n\t\t\t\tdefault :\r\n\t\t\t\t\tthrow new Exception('Cannot write property &#x5B;' . $prop . ']',1);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tthrow new Exception('Undefined property &#x5B;' . $prop . ']',1);\r\n\t\t}\r\n\t}\r\n\tpublic static function __get($prop)\r\n\t{\r\n\t\tif (isset(self::$_instance-&gt;$prop))\r\n\t\t{\r\n\t\t\tswitch ($prop)\r\n\t\t\t{\r\n\t\t\t\tcase 'isDebugging':\r\n\t\t\t\t\treturn self::$_instance-&gt;isDebugging\r\n\t\t\t\t\tbreak;\r\n\t\t\t       default :\r\n\t\t\t\t\tthrow new Exception('Cannot read property &#x5B;' . $prop . ']',1);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tthrow new Exception('Undefined property &#x5B;' . $prop . ']',1);\r\n\t\t}\r\n\t}\r\n}\r\n?&gt;\r\n<\/pre>\n<p>This is a testing script for the above. Note there are some commented lines for testing the exception thowing.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\tinclude 'config.inc.php';\r\n\t\/\/ First reference\r\n\t$myConfig1 = Config::getInstance();\r\n\t\/\/ Get property\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Set property\r\n\techo 'Set $myConfig1-&gt;isDebugging = true &lt;br\/&gt;';\r\n\t$myConfig1-&gt;isDebugging = true;\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Second reference\r\n\techo '&lt;br\/&gt;';\r\n\techo 'Add second reference and not getInstance args&lt;br\/&gt;';\r\n\techo '$myConfig2 = Config::getInstance(); &lt;br\/&gt;';\r\n\t$myConfig2 = Config::getInstance();\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig2-&gt;isDebugging:' . ($myConfig2-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Third reference&lt;br \/&gt;\r\n\techo '&lt;br\/&gt;';\r\n\techo 'Add third reference and change prop via getInstance arg &lt;br\/&gt;';\r\n\techo '$myConfig3 = Config::getInstance(array(\\'isDebugging\\'=&gt;false)); &lt;br\/&gt;';\r\n\t$myConfig3 = Config::getInstance(array('isDebugging'=&gt;false));\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig2-&gt;isDebugging:' . ($myConfig2-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig3-&gt;isDebugging:' . ($myConfig3-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Set property via second instance\r\n\techo '&lt;br\/&gt;';\r\n\techo 'Set property via second instance &lt;br\/&gt;';\r\n\techo 'Set $myConfig2-&gt;isDebugging = true &lt;br\/&gt;';\r\n\t$myConfig2-&gt;isDebugging = true;\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig2-&gt;isDebugging:' . ($myConfig2-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig3-&gt;isDebugging:' . ($myConfig3-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Set property to incorrect data type\r\n\techo '&lt;br\/&gt;';\r\n\techo 'Set $myConfig1-&gt;isDebugging = 123&lt;br\/&gt;';\r\n\techo 'No exception for invalid data type and not prop change.&lt;br\/&gt;';\r\n\t$myConfig1-&gt;isDebugging = 123;\r\n\techo ('$myConfig1-&gt;isDebugging:' . ($myConfig1-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig2-&gt;isDebugging:' . ($myConfig2-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\techo ('$myConfig3-&gt;isDebugging:' . ($myConfig3-&gt;isDebugging ? &quot;true&quot; : &quot;false&quot;)) . '&lt;br\/&gt;';\r\n\t\/\/ Setter throws undefined property exception\r\n\t\/\/$myConfig1-&gt;test = true;\r\n\t\/\/ Getter throws undefined property exception\r\n\t\/\/echo '$myConfig1-&gt;test:' . $myConfig1-&gt;test . '&lt;br\/&gt;';\r\n\t\/\/ Setter throws cannot write property exception\r\n\t\/\/$myConfig1-&gt;version = '2.2';\r\n\t\/\/ Setter throws cannot read property exception\r\n\t\/\/echo '$myConfig1-&gt;cannotReadProp:' . $myConfig1-&gt;cannotReadProp . '&lt;br\/&gt;';\r\n?&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to reproduce a simple singleton design pattern in PHP 5. After reviewing many overly complex examples, I synthesized to this example. It also makes use of the PHP5 magic function __get and __set also poorly addressed in web postings. Going for cleaner code I like to see $obj-&gt;prop rather than $obj-&gt;getProp() and $obj-&gt;setProp(value) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[57],"class_list":["post-35","post","type-post","status-publish","format-standard","hentry","category-general","tag-php-2"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/comments?post=35"}],"version-history":[{"count":7,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":271,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/35\/revisions\/271"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}