Is there a cleaner way to loop over references?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Is there a cleaner way to loop over references?

Post 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?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

seems like an opportunity for an iterator class. :)
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

well, the innards of the iterator would still have the same problem, no?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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;
  }
}
Post Reply