In Ruby, the Struct class is a convenient way to create a hash-like object on the fly and use it for your nefarious purposes. PHP 5+ can be convinced to do this type of things as well, it just doesn't have it out of the box. Here is a simple class that implements iterator and allows you to populate the internal data structure similar to how Ruby's Struct works. Syntactic sugar? Probably.
Note: I haven't bothered to implement the Ruby Struct API per se, Instead I just got something similar by implementing the Iterator interface and keeping things very PHP-like.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <?php
/* A basic data class sort-of based on Ruby Structs */
class Struct implements Iterator {
/* protected array that contains the class properties */
protected $_data;
/* constructor, takes in data */
function __construct($mixed=array()) {
$this->_data = array();
if (!is_array($mixed) || func_num_args() > 1) {
$mixed = func_get_args();
}
if ($this->_isAssoc($mixed)) {
foreach ($mixed as $prop => $val) {
if (!is_numeric($prop)) {
$this->_data[$prop] = $val;
}
}
}
else {
foreach ($mixed as $prop) {
if (!is_numeric($prop)) {
$this->_data[$prop] = FALSE;
}
}
}
}
/* utility function to decide if an array is associative */
protected function _isAssoc($var) {
return is_array($var) && array_diff_key($var, array_keys(array_keys($var)));
}
/* implementation of __set, just chucks stuff in _data */
function __set($name, $value) {
$this->_data[$name] = $value;
}
/* grabs stuff from _data */
function __get($name) {
if (isset($this->_data[$name])) {
return $this->_data[$name];
}
return FALSE;
}
function rewind() {
reset($this->_data);
}
function current() {
return current($this->_data);
}
function key() {
return key($this->_data);
}
function next() {
return next($this->_data);
}
function valid() {
return ($this->current() !== FALSE);
}
}
|
A quick example:
$z = new Struct(array('foo' => 1, 'bar' => TRUE, 'baz' => array(1,2,3)));
// iterating through the data like an array
foreach ($z as $key => $var) {
echo "$key : $var <br/>\n";
}
// accessing a property directly
echo $z->foo . "<br/>\n";
Interesting but I would still stick to plain PHP, an upvote non the less.