Creating a cycle() function in PHP
I love using the cycle
helper in Rails and I’ve always wished PHP had something
similar. But every time I created one I ran into the same problem every time.
How do I use multiple cycle calls in a single loop?
I happened to look at Rails’ source code and noticed it allowed a specific
namespace to be set in the last parameter cycle('blue', 'red', name: 'colors')
.
This concept could be easily recreated with PHP by beginning the last argument
with a colon.
The Function
<?php
/**
* Cycles through each argument added
* Based on Rails `cycle` method
*
* if last argument begins with ":"
* then it will change the namespace
* (allows multiple cycle calls within a loop)
*
* @param mixed $values infinite amount can be added
* @return mixed
* @author Baylor Rae'
*/
function cycle($first_value, $values = '*') {
// keeps up with all counters
static $count = array();
// get all arguments passed
$values = func_get_args();
// set the default name to use
$name = 'default';
// check if last items begins with ":"
$last_item = end($values);
if( substr($last_item, 0, 1) === ':' ) {
// change the name to the new one
$name = substr($last_item, 1);
// remove the last item from the array
array_pop($values);
}
// make sure counter starts at zero for the name
if( !isset($count[$name]) )
$count[$name] = 0;
// get the current item for its index
$index = $count[$name] % count($values);
// update the count and return the value
$count[$name]++;
return $values[$index];
}
Basic Usage
<?php for( $i = 0; $i < 9; $i++ ) : ?>
<p><?php echo cycle('one', 'two', 'three') ?></p>
<?php endfor; ?>
Custom Namespace
<?php for( $i = 0; $i < 9; $i++ ) : ?>
<p class="<?php echo cycle('odd', 'even') ?>">
<?php echo cycle('one', 'two', 'three', ':counter') ?>
</p>
<?php endfor; ?>
A Realistic Example
<?php
$things = array('shoe', 'sox', 'sand', 'laptop', 'guitar', 'bag', 'legos', 'elephpant', 'stapler', 'binder', 'desk', 'chair');
foreach( $things as $thing ) :
?>
<div class="grid_4 <?php echo cycle('alpha', '', 'omega') ?>">
<?php echo $thing ?>
</div>
<?php if( cycle(false, false, true, ':use_clear_div') ) : ?>
<div class="clear">// clear div every three items</div>
<?php endif; ?>
<?php endforeach; ?>
This is a example of using cycle
with the 960 Grid System. The idea is instead
of keeping up with an iterating variable (probably $i
), you simply pass a
matching number of boolean arguments to cycle
.