-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSingleton.php
More file actions
157 lines (135 loc) · 5.32 KB
/
Copy pathSingleton.php
File metadata and controls
157 lines (135 loc) · 5.32 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
namespace Psr;
// Singleton
trait Singleton
{
protected static $getInstance; // A Temporary variable for 'quick data'
protected $methods = array(); // Anonymous Function Declaration
private $storage; // Instance of the Container
public static function __callStatic($methodName, $arguments = array())
{
return self::getInstance()->Skeleton( $methodName, $arguments );
}
public static function newInstance()
{
// Start a new instance of the class and pass any arguments
$class = new \ReflectionClass( get_called_class() );
self::$getInstance = $class->newInstanceArgs( func_get_args() );
return self::$getInstance;
}
public static function getInstance()
{ // see if the class has already been called this run
if (!empty(self::$getInstance))
return self::$getInstance;
$calledClass = get_called_class();
// check if the object has been sterilized in the session
if (array_key_exists( $calledClass, $_SESSION )) {
// This will invoke the __wake up operator
if (is_object( self::$getInstance
= unserialize( $_SESSION[$calledClass] ) ))
return self::$getInstance;
throw new \Exception( 'Unserialize failed on '.$calledClass.' using Singleton' );
}
// Start a new instance of the class and pass any arguments
$class = new \ReflectionClass( get_called_class() );
self::$getInstance = $class->newInstanceArgs( func_get_args() );
return self::$getInstance;
}
/**
* @param null $object
* @return object|null
*/
public static function clearInstance($object = null)
{
if (array_key_exists( __CLASS__, $_SESSION ))
unset($_SESSION[__CLASS__]);
return self::$getInstance =
(is_object( $object ) ? $object : null );
}
public function __call($methodName, $arguments = array())
{
return $this->Skeleton( $methodName, $arguments );
}
private function Skeleton($methodName, $arguments = array())
{
// Have we used addMethod() to override an existing method
if (key_exists( $methodName, $this->methods ))
return (null === ($result = call_user_func_array( $this->methods[$methodName], $arguments )) ? $this : $result);
// Is the method in the current scope ( public, protected, private ).
// Note declaiming the method as private is the only way to ensure single instancing
if (method_exists($this , $methodName)) {
return (null === ($result = call_user_func_array( array($this, $methodName), $arguments )) ? $this : $result); }
if (key_exists( 'closures', $GLOBALS ) && key_exists( $methodName, $GLOBALS['closures'] )) {
$function = $GLOBALS['closures'][$methodName];
$this->addMethod( $methodName, $function );
return (null === ($result = call_user_func_array( $this->methods[$methodName], $arguments )) ? $this : $result);
}
throw new \Exception( "There is valid method or closure with the given name '$methodName' to call" );
}
private function addMethod($name, $closure)
{
if (is_callable( $closure )):
$this->methods[$name] = \Closure::bind( $closure, $this, get_called_class() );
else: // Nested to ensure Singleton returns the correct value of self
throw new \Exception( "New Method Must Be A Valid Closure" );
endif;
}
// for auto class serialization add: const Singleton = true; to calling class
public function __sleep()
{
if (!defined('self::Singleton') || !self::Singleton) return 0;
$object = get_object_vars( $this );
foreach ($object as $key => $value) {
if (is_object( $object[$key] ) ||
is_array( $object[$key] ) ||
empty($object[$key])) continue;
$onlyKeys[] = $key; }
return (isset($onlyKeys) ? $onlyKeys : 0);
}
public function __destruct()
{
// We require a sleep function to be set manually for singleton to manage utilization
if ($this->__sleep() !== 0) $_SESSION[__CLASS__] = serialize( $this );
elseif(array_key_exists( __CLASS__, $_SESSION )) unset($_SESSION[__CLASS__]);
}
// The rest of the methods are for the sake of methods
public function &__get($variable)
{
return $GLOBALS[$variable];
}
public function __set($variable, $value)
{
$GLOBALS[$variable] = $value;
}
public function __isset($variable)
{
return array_key_exists( $variable, $GLOBALS );
}
public function __unset($variable)
{
unset($GLOBALS[$variable]);
}
public function __invoke()
{
return $this->storage;
}
private function set($name, $value = null)
{
$this->storage = null;
if ($value == null) {
if (is_array( $name )) $this->storage = $name;
else $this->storage[] = $name; }
else $this->storage[$name] = $value;
return $this;
}
private function get($variable = null)
{
return ($variable == null ?
$this->storage :
$this->{$variable});
}
private function has($variable)
{
return isset($this->$variable);
}
}