[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <!DOCTYPE html> 2 <html class="no-js" id="top"> 3 <head> 4 <title>ProxyManager - Ghost object</title> 5 6 <meta name="description" content="A proxyManager write in php" /> 7 <meta name="keywords" content="ProxyManager, proxy, manager, ocramius, Marco Pivetta, php, ghost object" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> 9 <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600' rel='stylesheet' type='text/css'> 10 <link href="css/styles.css" rel="stylesheet" /> 11 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/styles/default.min.css"> 12 <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/highlight.min.js"></script> 13 <script>hljs.initHighlightingOnLoad();</script> 14 <link rel="shortcut icon" href="favicon.ico"> 15 </head> 16 <body> 17 18 <header class="site-header"> 19 <div class="container"> 20 <h1><a href="index.html"><img alt="ProxyManager" src="img/block.png" /></a></h1> 21 22 <nav class="main-nav" role="navigation"> 23 <ul> 24 <li><a href="https://github.com/Ocramius/ProxyManager" target="_blank">Github</a> 25 <div class="bcms-clearfix"></div> 26 </li> 27 </ul> 28 </nav> 29 </div> 30 </header> 31 <main role="main"> 32 <section class="component-content"> 33 34 <div class="component-demo" id="live-demo"> 35 <div class="container"> 36 <div class="main-wrapper" style="text-align: right"> 37 <iframe src="http://ghbtns.com/github-btn.html?user=ocramius&repo=ProxyManager&type=fork&count=true&size=large" 38 allowtransparency="true" frameborder="0" scrolling="0" width="310" height="40"></iframe> 39 40 <iframe src="http://ghbtns.com/github-btn.html?user=ocramius&repo=ProxyManager&type=watch&count=true&size=large" 41 allowtransparency="true" frameborder="0" scrolling="0" width="200" height="40"></iframe> 42 43 </div> 44 <div class="bcms-clearfix bcms-clearfix"></div> 45 </div> 46 </div> 47 <div class="component-info"> 48 <div class="container"> 49 <aside class="sidebar"> 50 <nav class="spy-nav"> 51 <ul> 52 <li><a href="index.html">Intro</a></li> 53 <li><a href="virtual-proxy.html">Virtual Proxy</a></li> 54 <li><a href="null-object.html">Null Objects</a></li> 55 <li><a href="ghost-object.html">Ghost Objects</a></li> 56 <li><a href="remote-object.html">Remote Object</a></li> 57 <li><a href="contributing.html">Contributing</a></li> 58 <li><a href="credits.html">Credits</a></li> 59 <li><a href="copyright.html">Copyright</a></li> 60 </ul> 61 </nav> 62 <div class="bcms-clearfix bcms-clearfix"></div> 63 <a class="btn btn-action btn-full download-component" 64 href="download.html">Download</a> 65 <div class="bcms-clearfix"></div> 66 </aside> 67 68 <div class="content"> 69 <div class="bcms-clearfix"></div> 70 <h3 class="section-title">Lazy Loading Ghost Object Proxies</h3> 71 72 <p>A lazy loading ghost object proxy is a ghost proxy that looks exactly like the real instance of the proxied subject, but which has all properties nulled before initialization.</p> 73 <hr /> 74 75 <h3 class="section-title">Lazy loading with the Ghost Object</h3> 76 77 <p>In pseudo-code, in userland, <a href="http://www.martinfowler.com/eaaCatalog/lazyLoad.html" target="_blank">lazy loading</a> in a ghost object looks like following:</p> 78 79 <pre> 80 <code class="php"> 81 class MyObjectProxy 82 { 83 private $initialized = false; 84 private $name; 85 private $surname; 86 87 public function doFoo() 88 { 89 $this->init(); 90 91 // Perform doFoo routine using loaded variables 92 } 93 94 private function init() 95 { 96 if (! $this->initialized) { 97 $data = some_logic_that_loads_data(); 98 99 $this->name = $data['name']; 100 $this->surname = $data['surname']; 101 102 $this->initialized = true; 103 } 104 } 105 } 106 </code> 107 </pre> 108 109 <p>Ghost objects work similarly to virtual proxies, but since they don't wrap around a "real" instance of the proxied subject, they are better suited for representing dataset rows.</p> 110 111 <hr /> 112 113 <h3 class="section-title">When do I use a ghost object?</h3> 114 115 <p>You usually need a ghost object in cases where following applies</p> 116 117 <ul> 118 <li>you are building a small data-mapper and want to lazily load data across associations in your object graph</li> 119 <li>you want to initialize objects representing rows in a large dataset</li> 120 <li>you want to compare instances of lazily initialized objects without the risk of comparing a proxy with a real subject</li> 121 <li>you are aware of the internal state of the object and are confident in working with its internals via reflection or direct property access</li> 122 </ul> 123 124 <hr /> 125 126 <h3 class="section-title">Usage examples</h3> 127 128 <p><a href="https://github.com/Ocramius/ProxyManager" target="_blank">ProxyManager</a> provides a factory that creates lazy loading ghost objects. To use it, follow these steps:</p> 129 130 <p>First of all, define your object's logic without taking care of lazy loading:</p> 131 132 <pre> 133 <code class="php"> 134 namespace MyApp; 135 136 class Customer 137 { 138 private $name; 139 private $surname; 140 141 // just write your business logic or generally logic 142 // don't worry about how complex this object will be! 143 // don't code lazy-loading oriented optimizations in here! 144 public function getName() { return $this->name; } 145 public function setName($name) { $this->name = (string) $name; } 146 public function getSurname() { return $this->surname; } 147 public function setSurname($surname) { $this->surname = (string) $surname; } 148 } 149 </code> 150 </pre> 151 152 <p>Then use the proxy manager to create a ghost object of it. You will be responsible of setting its state during lazy loading:</p> 153 154 <pre> 155 <code class="php"> 156 namespace MyApp; 157 158 use ProxyManager\Factory\LazyLoadingGhostFactory; 159 use ProxyManager\Proxy\LazyLoadingInterface; 160 161 require_once __DIR__ . '/vendor/autoload.php'; 162 163 $factory = new LazyLoadingGhostFactory(); 164 $initializer = function (LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) { 165 $initializer = null; // disable initialization 166 167 // load data and modify the object here 168 $proxy->setName('Agent'); 169 $proxy->setSurname('Smith'); 170 171 return true; // confirm that initialization occurred correctly 172 }; 173 174 $instance = $factory->createProxy('MyApp\Customer', $initializer); 175 </code> 176 </pre> 177 178 <p>You can now simply use your object as before:</p> 179 180 <pre> 181 <code class="php"> 182 // this will just work as before 183 echo $proxy->getName() . ' ' . $proxy->getSurname(); // Agent Smith 184 </code> 185 </pre> 186 <hr /> 187 188 <h3 class="section-title">Lazy Initialization</h3> 189 190 <p>As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime. The initializer closure signature for ghost objects should be as following:</p> 191 192 <pre> 193 <code class="php"> 194 /** 195 * @var object $proxy the instance the ghost object proxy that is being initialized 196 * @var string $method the name of the method that triggered lazy initialization 197 * @var array $parameters an ordered list of parameters passed to the method that 198 * triggered initialization, indexed by parameter name 199 * @var Closure $initializer a reference to the property that is the initializer for the 200 * proxy. Set it to null to disable further initialization 201 * 202 * @return bool true on success 203 */ 204 $initializer = function ($proxy, $method, $parameters, & $initializer) {}; 205 </code> 206 </pre> 207 208 <p>The initializer closure should usually be coded like following:</p> 209 210 <pre> 211 <code class="php"> 212 $initializer = function ($proxy, $method, $parameters, & $initializer) { 213 $initializer = null; // disable initializer for this proxy instance 214 215 // modify the object with loaded data 216 $proxy->setFoo(/* ... */); 217 $proxy->setBar(/* ... */); 218 219 return true; // report success 220 }; 221 </code> 222 </pre> 223 224 <p>The <code>ProxyManager\Factory\LazyLoadingGhostFactory</code> produces proxies that implement both the <code>ProxyManager\Proxy\GhostObjectInterface</code> and the <code>ProxyManager\Proxy\LazyLoadingInterface</code>.</p> 225 226 <p>At any point in time, you can set a new initializer for the proxy:</p> 227 228 <pre> 229 <code class="php"> 230 $proxy->setProxyInitializer($initializer); 231 </code> 232 </pre> 233 234 <p>In your initializer, you <strong>MUST</strong> turn off any further initialization:</p> 235 236 <pre> 237 <code class="php"> 238 $proxy->setProxyInitializer(null); 239 </code> 240 </pre> 241 242 <p>or</p> 243 244 <pre> 245 <code class="php"> 246 $initializer = null; // if you use the initializer passed by reference to the closure 247 </code> 248 </pre> 249 <hr /> 250 251 <h3 class="section-title">Triggering Initialization</h3> 252 253 <p>A lazy loading ghost object is initialized whenever you access any property or method of it. Any of the following interactions would trigger lazy initialization:</p> 254 255 <pre> 256 <code class="php"> 257 // calling a method 258 $proxy->someMethod(); 259 260 // reading a property 261 echo $proxy->someProperty; 262 263 // writing a property 264 $proxy->someProperty = 'foo'; 265 266 // checking for existence of a property 267 isset($proxy->someProperty); 268 269 // removing a property 270 unset($proxy->someProperty); 271 272 // cloning the entire proxy 273 clone $proxy; 274 275 // serializing the proxy 276 $unserialized = unserialize(serialize($proxy)); 277 </code> 278 </pre> 279 280 <p>Remember to call <code>$proxy->setProxyInitializer(null);</code> to disable initialization of your proxy, or it will happen more than once.</p> 281 282 <hr /> 283 284 <h3 class="section-title">Proxying interfaces</h3> 285 286 <p>You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the methods defined by the interface itself, even if the <code>wrappedObject</code> implements more methods. This will anyway save some memory since the proxy won't contain any properties.</p> 287 288 <p>Tuning performance for production</p> 289 290 <p>See <a href="production.html">Tuning ProxyManager for Production.</a></p> 291 292 </main> 293 294 <footer class="site-footer" role="contentinfo"> 295 <div class="container"> 296 <div class="footer-logos"> 297 <ul> 298 <li><a href="index.html">Intro</a> | </li> 299 <li><a href="virtual-proxy.html">Virtual Proxy</a> | </li> 300 <li><a href="null-object.html">Null Objects</a> | </li> 301 <li><a href="ghost-object.html">Ghost Objects</a> | </li> 302 <li><a href="remote-object.html">Remote Object</a> | </li> 303 <li><a href="contributing.html">Contributing</a> | </li> 304 <li><a href="credits.html">Credits</a> | </li> 305 <li><a href="copyright.html">Copyright</a></li> 306 </ul> 307 </div> 308 </div> 309 310 <div class="bcms-clearfix"></div> 311 </footer> 312 <div class="bcms-clearfix"></div> 313 </body> 314 </html>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |