[ 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 - Virtual Proxy</title> 5 6 <meta name="description" content="A proxyManager write in php" /> 7 <meta name="keywords" content="ProxyManager, proxy, manager, ocramius, Marco Pivetta, php, virtual proxy" /> 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 Value Holder Proxy</h3> 71 <p>A lazy loading value holder proxy is a virtual proxy that wraps and lazily initializes a "real" instance of the proxied class.</p> 72 <hr /> 73 74 <h3 class="section-title">What is lazy loading?</h3> 75 76 <p>In pseudo-code, in userland, <a href="http://www.martinfowler.com/eaaCatalog/lazyLoad.html" target="_blank">lazy loading</a> looks like following:</p> 77 78 <pre> 79 <code class="php"> 80 class MyObjectProxy 81 { 82 private $wrapped; 83 84 public function doFoo() 85 { 86 $this->init(); 87 88 return $this->wrapped->doFoo(); 89 } 90 91 private function init() 92 { 93 if (null === $this->wrapped) { 94 $this->wrapped = new MyObject(); 95 } 96 } 97 } 98 </code> 99 </pre> 100 101 <p>This code is problematic, and adds a lot of complexity that makes your unit tests' code even worse.</p> 102 103 <p>Also, this kind of usage often ends up in coupling your code with a particular <a href="http://martinfowler.com/articles/injection.html" target="_blank">Dependency Injection Container</a> or a framework that fetches dependencies for you. That way, further complexity is introduced, and some problems related with service location raise, as I've explained <a href="http://ocramius.github.io/blog/zf2-and-symfony-service-proxies-with-doctrine-proxies/" target="_blank">in this article</a>.</p> 104 105 <p>Lazy loading value holders abstract this logic for you, hiding your complex, slow, performance-impacting objects behind tiny wrappers that have their same API, and that get initialized at first usage.</p> 106 107 <hr /> 108 109 <h3 class="section-title">When do I use a lazy value holder?</h3> 110 111 <p>You usually need a lazy value holder in cases where following applies</p> 112 113 <ul> 114 <li>your object takes a lot of time and memory to be initialized (with all dependencies)</li> 115 <li>your object is not always used, and the instantiation overhead can be avoided</li> 116 </ul> 117 118 <hr /> 119 120 <h3 class="section-title">Usage examples</h3> 121 122 <p>ProxyManager provides a factory that eases instantiation of lazy loading value holders. To use it, follow these steps:</p> 123 124 <p>First of all, define your object's logic without taking care of lazy loading:</p> 125 126 <pre> 127 <code class="php"> 128 namespace MyApp; 129 130 class HeavyComplexObject 131 { 132 public function __construct() 133 { 134 // just write your business logic 135 // don't worry about how heavy initialization of this will be! 136 } 137 138 public function doFoo() { 139 echo "OK!" 140 } 141 } 142 </code> 143 </pre> 144 145 <p>Then use the proxy manager to create a lazy version of the object (as a proxy):</p> 146 147 <pre> 148 <code class="php"> 149 namespace MyApp; 150 151 use ProxyManager\Factory\LazyLoadingValueHolderFactory; 152 use ProxyManager\Proxy\LazyLoadingInterface; 153 154 require_once __DIR__ . '/vendor/autoload.php'; 155 156 $factory = new LazyLoadingValueHolderFactory(); 157 $initializer = function (& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) { 158 $initializer = null; // disable initialization 159 $wrappedObject = new HeavyComplexObject(); // fill your object with values here 160 161 return true; // confirm that initialization occurred correctly 162 }; 163 164 $instance = $factory->createProxy('MyApp\HeavyComplexObject', $initializer); 165 </code> 166 </pre> 167 168 <p>You can now simply use your object as before:</p> 169 170 <pre> 171 <code class="php"> 172 // this will just work as before 173 $proxy->doFoo(); // OK! 174 </code> 175 </pre> 176 <hr /> 177 178 179 <h3 class="section-title">Lazy Initialization</h3> 180 181 <p>As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime. The initializer closure signature should be as following:</p> 182 183 <pre> 184 <code class="php"> 185 /** 186 * @var object $wrappedObject the instance (passed by reference) of the wrapped object, 187 * set it to your real object 188 * @var object $proxy the instance proxy that is being initialized 189 * @var string $method the name of the method that triggered lazy initialization 190 * @var string $parameters an ordered list of parameters passed to the method that 191 * triggered initialization, indexed by parameter name 192 * @var Closure $initializer a reference to the property that is the initializer for the 193 * proxy. Set it to null to disable further initialization 194 * 195 * @return bool true on success 196 */ 197 $initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {}; 198 </code> 199 </pre> 200 201 <p>The initializer closure should usually be coded like following:</p> 202 203 <pre> 204 <code class="php"> 205 $initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) { 206 $newlyCreatedObject = new Foo(); // instantiation logic 207 $newlyCreatedObject->setBar('baz') // instantiation logic 208 $newlyCreatedObject->setBat('bam') // instantiation logic 209 210 $wrappedObject = $newlyCreatedObject; // set wrapped object in the proxy 211 $initializer = null; // disable initializer 212 213 return true; // report success 214 }; 215 </code> 216 </pre> 217 218 <p>The <code>ProxyManager\Factory\LazyLoadingValueHolderFactory</code> produces proxies that implement both the <code>ProxyManager\Proxy\ValueHolderInterface</code> and the <code>ProxyManager\Proxy\LazyLoadingInterface</code>.</p> 219 220 <p>At any point in time, you can set a new initializer for the proxy:</p> 221 222 <pre><code class="php">$proxy->setProxyInitializer($initializer);</code></pre> 223 224 <p>In your initializer, you currently <strong>MUST</strong> turn off any further initialization:</p> 225 226 <pre><code class="php">$proxy->setProxyInitializer(null);</code></pre> 227 228 <p>or</p> 229 230 <pre><code class="php">$initializer = null; // if you use the initializer by reference</code></pre> 231 <hr /> 232 233 <h3 class="section-title">Triggering Initialization</h3> 234 235 <p>A lazy loading proxy is initialized whenever you access any property or method of it. Any of the following interactions would trigger lazy initialization:</p> 236 237 <pre> 238 <code class="php"> 239 // calling a method 240 $proxy->someMethod(); 241 242 // reading a property 243 echo $proxy->someProperty; 244 245 // writing a property 246 $proxy->someProperty = 'foo'; 247 248 // checking for existence of a property 249 isset($proxy->someProperty); 250 251 // removing a property 252 unset($proxy->someProperty); 253 254 // cloning the entire proxy 255 clone $proxy; 256 257 // serializing the proxy 258 $unserialized = serialize(unserialize($proxy)); 259 </code> 260 </pre> 261 262 <p>Remember to call <code>$proxy->setProxyInitializer(null);</code> to disable initialization of your proxy, or it will happen more than once.</p> 263 264 265 266 267 268 269 270 271 <hr /> 272 273 <h3 class="section-title">Proxying interfaces</h3> 274 275 <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 wrappedObject implements more methods. This will anyway save some memory since the proxy won't contain useless inherited properties.</p> 276 277 <p>Tuning performance for production</p> 278 279 <p>See <a href="production.html">Tuning ProxyManager for Production.</a></p> 280 281 282 283 </main> 284 285 <footer class="site-footer" role="contentinfo"> 286 <div class="container"> 287 <div class="footer-logos"> 288 <ul> 289 <li><a href="index.html">Intro</a> | </li> 290 <li><a href="virtual-proxy.html">Virtual Proxy</a> | </li> 291 <li><a href="null-object.html">Null Objects</a> | </li> 292 <li><a href="ghost-object.html">Ghost Objects</a> | </li> 293 <li><a href="remote-object.html">Remote Object</a> | </li> 294 <li><a href="contributing.html">Contributing</a> | </li> 295 <li><a href="credits.html">Credits</a> | </li> 296 <li><a href="copyright.html">Copyright</a></li> 297 </ul> 298 </div> 299 </div> 300 301 <div class="bcms-clearfix"></div> 302 </footer> 303 <div class="bcms-clearfix"></div> 304 </body> 305 </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 |