title: How can arguments to variadic functions be passed by reference in PHP?
body: <p>Assuming it's possible, how would one pass arguments by reference to a variadic function without generating a warning in PHP? We can no longer use the '&amp;' operator in a function call, otherwise I'd accept that (even though it would be error prone, should a coder forget it).</p>
  
  <p>What inspired this is are old MySQLi wrapper classes that I unearthed (these days, I'd just use PDO). The only difference between the wrappers and the MySQLi classes is the wrappers throw exceptions rather than returning <code>FALSE</code>.</p>
  
  <pre><code>class DBException extends RuntimeException {}
  ...
  class MySQLi_throwing extends mysqli {
      ...
      function prepare($query) {
          $stmt = parent::prepare($query);
          if (!$stmt) {
              throw new DBException($this-&gt;error, $this-&gt;errno);
          }
          return new MySQLi_stmt_throwing($this, $query, $stmt);
      }
  }
  // I don't remember why I switched from extension to composition, but
  // it shouldn't matter for this question.
  class MySQLi_stmt_throwing /* extends MySQLi_stmt */ {
      protected $_link, $_query, $_delegate;
  
      public function __construct($link, $query, $prepared) {
          //parent::__construct($link, $query);
          $this-&gt;_link = $link;
          $this-&gt;_query = $query;
          $this-&gt;_delegate = $prepared;
      }
      function bind_param($name, &amp;$var) {
          return $this-&gt;_delegate-&gt;bind_param($name, $var);
      }
      function __call($name, $args) {
          //$rslt = call_user_func_array(array($this, 'parent::' . $name), $args);
          $rslt = call_user_func_array(array($this-&gt;_delegate, $name), $args);
          if (False === $rslt) {
              throw new DBException($this-&gt;_link-&gt;error, $this-&gt;errno);
          }
          return $rslt;
      }
  }
  </code></pre>
  
  <p>The difficulty lies in calling methods such as <code>bind_result</code> on the wrapper. Constant-arity functions (e.g. <code>bind_param</code>) can be explicitly defined, allowing for pass-by-reference. <code>bind_result</code>, however, needs all arguments to be pass-by-reference. If you call <code>bind_result</code> on an instance of <code>MySQLi_stmt_throwing</code> as-is, the arguments are passed by value and the binding won't take.</p>
  
  <pre><code>try {
      $id = Null;
      $stmt = $db-&gt;prepare('SELECT id FROM tbl WHERE ...');
      $stmt-&gt;execute()
      $stmt-&gt;bind_result($id);
      // $id is still null at this point
      ...
  } catch (DBException $exc) {
     ...
  }
  </code></pre>
  
  <p>Since the above classes are no longer in use, this question is merely a matter of curiosity. Alternate approaches to the wrapper classes are not relevant. Defining a method with a bunch of arguments taking <code>Null</code> default values is not correct (what if you define 20 arguments, but the function is called with 21?). Answers don't even need to be written in terms of <code>MySQL_stmt_throwing</code>; it exists simply to provide a concrete example.</p>