Can I iterate over an array without using a foreach loop in PHP?
Here you go:
$array = array(NULL, FALSE, 0);
while(list($key, $value) = each($array)) {
var_dump($value);
}
Output:
NULL
bool(false)
int(0)
next() and current() can't be used because there is no way to determine if a FALSE return value means a FALSE element or the end of the array. (As you've observed). However, you can use the function each(), as it will return an array containing the current key and value or FALSE at the end of the array. After it has been executed, the current-pointer will be set to the next element.
I must admit that I've not used that since > 10 years. :) However it is a basic PHP function and it still works.
How to implement the WordPres-like ContentGetter interface?
I would make usage of PHP's Iterator concept. You can wrap either the array in to an ArrayIterator or the PDOStatement into a PDOStatementIterator. While this first is a built-in class of PHP, the latter has to be written. Alternatively you can use this one (looks good, but contains more functionality than required for this task)
Based on that, the Document class should look like this:
class Document implements ContentGetter {
/**
* @var Iterator
*/
protected $iterator;
/**
* @param array|PDOStatement $stmtOrArray
*/
public function __construct($stmtOrArray) {
if(is_a($stmtOrArray, 'PDOStatement')) {
$this->iterator = new PDOStatementIterator($stmtOrArray);
} else if(is_array($stmtOrArray)) {
$this->iterator = new ArrayIterator($stmtOrArray);
} else {
throw new Exception('Expected array or PDOStatement');
}
}
/**
* Wrapper for Iterator::valid()
*/
public function have_content() {
return $this->iterator->valid();
}
/**
* Wrapper for Iterator::current() + Iterator::next()
*/
public function get_content() {
$item = $this->iterator->current();
$this->iterator->next();
return $item;
}
}
Tests:
// Feed Document with a PDOStatement
$pdo = new PDO('mysql:host=localhost', 'user', 'password');
$result = $pdo->query('SELECT 1 UNION SELECT 2'); // stupid query ...
$doc = new Document($result);
while($doc->have_content()) {
var_dump($doc->get_content());
}
.
// Feed Document with an array
$doc = new Document(array(1, 2, 3));
while($doc->have_content()) {
var_dump($doc->get_content());
}