title: PHP Copy on Write in Arrays vs Objects
body: <p>I have a question about the copy one write optimization in PHP that I believe is distinct from <a href="https://stackoverflow.com/questions/11074970/will-copy-on-write-prevent-data-duplication-on-arrays">this</a> and this question marked as a <a href="https://stackoverflow.com/questions/66703161/does-phps-copy-on-write-work-with-arrays">duplicate</a>. I also do not feel the question is addressed here, either <a href="https://stackoverflow.com/questions/628938/what-is-copy-on-write">this</a>.</p>
  <p>In my observation, the copy on write optimization appears to work differently with arrays than with objects. With arrays, it seems that if anything at all changes, no matter how deep in the array, a copy takes place. With objects, it seems that the copy on write only looks at a shallow level.</p>
  <p>Consider:</p>
  <pre><code>class B{
    var $b;
    function __construct($x) { $this-&gt;b = $x; }
  }
  
  $w = [new B(0)];
  $x = $w; // $x references $w 
  $x[0]-&gt;b = 1; // now $x does not reference $w 
  
  $y = new B(0);
  $z = $y; // $z references $y 
  $z-&gt;b = 1; // $z still references $y 
  </code></pre>
  <p>I make these confirmations on referencing based on passing $w, $x, $y, and $z into the debug_zval_dump function.</p>
  <p>Can someone explain why this is the case? The answer in the second link I provide mentioned &quot;as long as no single byte is changed&quot; and perhaps that is what I need to understand better. My mental model for PHP objects had always been that they are effectively pointers. And the pointer to B in &quot;$x[0]-&gt;b = 1&quot; is not changed so I would view that as not a single byte changing.</p>
  <p>I also don't see why objects behave differently than arrays in this regard.</p>
  <p>Is this behavior properly documented somewhere other than having to read or post on Stack Overflow? The PHP.net manual is quite unhelpful about more theoretical details of the language. With JavaScript, for example, one can view the ECMAScript Standard. That sort of thing doesn't seem to exist for PHP.</p>