title: Is there a way to force function parameter to be "unchangeable"?
body: <pre><code>&lt;?php
  // Enter your code here, enjoy!
  class Foo {
      private $a;
      public function getA() {
          return $this-&gt;a;
      }
      public function setA($a) {
          $this-&gt;a = $a;
      }   
  }
  
  class Bar {
      public function test(Foo $f) {
          $f-&gt;setA(2);
      }
  }
  
  $foo = new Foo();
  $foo-&gt;setA(1);
  var_dump($foo);
  
  $bar = new Bar();
  $bar-&gt;test($foo);
  var_dump($foo);
  
  //output
  //object(Foo)#1 (1) {
  //  [&quot;a&quot;:&quot;Foo&quot;:private]=&gt;
  //  int(1)
  //}
  //object(Foo)#1 (1) {
  //  [&quot;a&quot;:&quot;Foo&quot;:private]=&gt;
  //  int(2)
  //}
  
  </code></pre>
  <p>The above code shows PHP object parameters are passed by reference. This results in a dilemma that, by looking at a function's signature, one does not know whether the parameters are changed in the function. This means one have to read the whole function just to find out whether the parameter is changed, which makes the whole code less readable and more bug-prone.</p>
  <p>Is there a way to &quot;systematically assure the code reader&quot; that an object parameter cannot be changed inside a function? I have though of adding more comments but comments can sometimes differ from what the code actually does and when that happens it becomes even harder to debug.</p>
  <p>Workarounds are acceptable, but I would like something that will only affect some specific parameters of some specific functions and not others, in a human-readable fashion.</p>
  <p>Essentially the following effect is what I want:</p>
  <pre><code>class Foo {
      private $a;
      public function getA() {
          return $this-&gt;a;
      }
      public function setA($a) {
          $this-&gt;a = $a;
      }   
  }
  
  class Bar {
      public function test1(Foo $f1, Foo $f2) {
          $f1-&gt;setA(2);
          $f2-&gt;setA(2);
      }
      public function test2(Foo $f1, &quot;immutable&quot; Foo $f2) {
          $f1-&gt;setA($f2-&gt;getA());
      }
      public function test3(Foo $f1, &quot;immutable&quot; Foo $f2) {
          $f1-&gt;setA(3);
          $f2-&gt;setA(3);
      }
  }
  
  $foo1 = new Foo();
  $foo2 = new Foo();
  
  $bar = new Bar();
  // This will work
  $bar-&gt;test1($foo1,$foo2);
  // This will also work
  $bar-&gt;test2($foo1,$foo2);
  // This will throw Exception / Or the $foo2 is unchanged outside the function without Exception is also fine
  $bar-&gt;test3($foo1,$foo2);
  </code></pre>