After skimming through Fabien’s very interesting slideshare presentation on PHP 5.3 (no, I can’t read French), and playing with Jon Wage’s PHP Interactive Terminal, I whipped up a fun little object-oriented array-wrapper class to do some neat ruby-esque things. It should be noted this code is for fun, and probably not sufficient for production use.

Using my array class, the following functions are now possible:

  // Instantiate the object
  $test = new A(1, 2, 3, 4, 5, 6, 8, 10, 20);

  // return an array containing the multiples of 4
  $test->reduce(function($i) { return $i%4==0; }); 

  // Sum up all even values
  $x = 0;
  $test->each(function($i) use (&$x) {
    if($i % 2 != 0)
      continue;
    $x+=$i;
  });
  echo $i;  // outputs "42";

  // return the index of the first item evaluated true
  $isGreaterThan = function($x, $y) { return $x > $y; };
  $test->match(function($i) use ($isGreaterThan) { return $isGreaterThan($i, 15); }); 

  // returns an array of all values multiplied by two
  $test->map(function($i) { return $i*2; }); 

  // until the function evaluates true, execute the block on all variables
  $test->until(function($i) { return $i > 15; })->do(function($i) {
    echo "This number ($i) is less than or equal to 15";
  });

Although we really gain nothing here we don’t already have with functions such as array_walk, array_map, array_filter, and so on, I personally get slightly aroused at this ruby-esque PHP implementation. While not quite as pretty as ruby blocks, anonymous functions (aka “closures”) offer similar functionality. To make it more rubyesque, I’ve overloaded my class’s __call, and __invoke methods:

  // Instantiate an existing array
  $test = new A($fortunes); 

  // return an array with "in bed" appended to all fortunes
  $test->map(function($i, $key) { return $i." in bed."; }); 

  // mutate the array object in place (similar to ruby's exclamation mark convention)
  $test->_map(function($i, $key) { return $i." in bed."; }); 

  // the underscore convention works for all functions that return an array
  $test->_reduce(function($i, $key) { return strpos($i, 'happiness') !== false; }); 

  // Ruby-like array access
  $test = new A(10, 900, 5, 30);
  echo $test(1, 2) // returns array [900, 5] (starts at index 1, length is 2)

  // maybe supported someday, if I have time:
  echo $test['0..2'] // returns array [10, 900, 5] (starts at index 0, up to index 2)
  echo $test['1..,-1'] // returns array [10, 900, 5] (starts at index 0, up to last index, excludes ending index)
  $test['2...3'] = new A(2, 2); //inserts array as the given indexes, to produce array [10, 900, 2, 2, 2, 20]

You can check out my half-baked class here. Any other fun ideas??

*** Update ***
Jwage did something similar by wrapping primitive types in php classes. Check out his code here!

Add comment