Page 1 of 1

Is there a cleaner way to loop over references?

Posted: Sat Aug 27, 2005 7:16 pm
by nielsene
I've ended up with a slightly crufty function:

Code: Select all

function _invokePreHandlers(&$module,&$con,&$req) {
    $preHandlers =& $module->createPreHandlers();
    $numHandlers=count($preHandlers);
    $view="";
    for ($i=0;$i<$numHandlers;$i++) {
      $aHandler=&$preHandlers[$i];
      if ($aHandler->canHandle($con,$req)) {
         $handled=TRUE;
         $view=$aHandler->execute($con,$req);
         break;
      }
    }
    return $view;
  }
I'd rather not introduce the two extra local variables $i and $numHandlers. However I couldn't a foreach or a while ( $foo=&next()) style loop to work. (For instance:

Code: Select all

function _invokePreHandlers1(&$module,&$con,&$req) {
    $preHandlers =& $module->createPreHandlers();
    $view="";
    reset($preHandlers);
    while ($view=="" && $aHandler=&next($preHandlers)) 
      if ($aHandler->canHandle($con,$req)) 
        $view=$aHandler->execute($con,$req);
    return $view;
  }
does not preserve the references. (PHP4 so I can't place the & before $value in a foreach).

Is there anyway to make this work, or should I just stick with the extra local variables?

Posted: Sat Aug 27, 2005 7:24 pm
by feyd
seems like an opportunity for an iterator class. :)

Posted: Sat Aug 27, 2005 7:28 pm
by nielsene
well, the innards of the iterator would still have the same problem, no?

Posted: Sat Aug 27, 2005 7:56 pm
by feyd
marginally, but it'd get you closer to the look you wanted in the second code-bit.

I'm seeing something like this:

Code: Select all

class ReferenceIterator
{
  var $pos;
  var $data;
  var $size;

  function ReferenceIterator(&$array)
  {
    $this->data = array_values($array);
    $this->size = count($this->data);
    $this->reset();
  }

  function reset()
  {
    $this->pos = ($this->size ? 0 : null);
  }

  function &next()
  {
    if($this->pos !== null) $this->pos++;
    return $this->current();
  }

  function &previous()
  {
    if($this->pos !== null) $this->pos--;
    return $this->current();
  }

  function &current()
  {
    if($this->pos !== null and 0 <= $this->pos and $this->pos < $this->size)
    {
      $ret =& $this->data[$this->pos];
    }
    else
    {
      $this->pos = null;
      $ret = null;
    }
    return $ret;
  }
}