[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/ocramius/proxy-manager/html-docs/ -> ghost-object.html (source)

   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&amp;repo=ProxyManager&amp;type=fork&amp;count=true&amp;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&amp;repo=ProxyManager&amp;type=watch&amp;count=true&amp;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, &amp; $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>


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1