Iterate
, (*1)
PHP classes and interfaces to iterate \Iterator
s by a scenario or to perform a
regular expression match on iterator elements by a scenario., (*2)
A Scenario is a class that implements the ScenarioInterface
or extends either
BaseScenario
or BaseRegexScenario
abstract class. It receives an Iterator
instance and executes the logic in certain moments of the iteration process -
for example, while regex matching is performed - when some pattern matched a
subject, or none matched, or before/after performing a search, etc., (*3)
Think of it as of array_walk()
for iterators or iterator_apply()
,
but instead of a single callback you provide an object (Scenario) with several
methods. And you can use these Scenarios as plugins., (*4)
Iterator is simply any object implementing the \Iterator
interface., (*5)
The main class, which runs the process, is Iterate
. It just needs to be
instantiated and invoked with an iterator and a scenario objects., (*6)
Best suited for use as a Composer library., (*7)
Requirements
Installation
To add this library to your Composer project:, (*8)
composer require shiyan/iterate
Usage
There are 2 base scenarios included:
* The very basic one to execute some logic on each element of the iterator
unconditionally.
* And the regex based one, which performs a regular expression match (using one
or more patterns) on iterator elements (casted to strings), and allows to
execute different logic depending on what pattern matched or if no patterns
matched., (*9)
Example
Assuming there is an array of strings, $array
. Iterate over it,
convert all empty strings to 0 (zero), print all strings containing "PHP" and
simply count all other elements., (*10)
First, create a scenario class:, (*11)
use Shiyan\Iterate\Scenario\BaseRegexScenario;
class ExampleScenario extends BaseRegexScenario {
const PATTERN_EMPTY = '/^$/';
const PATTERN_PHP = '/PHP/';
public $counter;
public function getPatterns(): array {
return [self::PATTERN_EMPTY, self::PATTERN_PHP];
}
public function preRun(): void {
$this->counter = 0;
}
public function onMatch(array $matches, string $pattern): void {
switch ($pattern) {
case self::PATTERN_EMPTY:
$this->iterator[$this->iterator->key()] = 0;
break;
case self::PATTERN_PHP:
print $this->iterator->current() . "\n";
break;
}
}
public function ifNotMatched(): void {
++$this->counter;
}
}
And then:, (*12)
use Shiyan\Iterate\Iterate;
// Convert our array of strings to the iterator object.
$iterator = new ArrayIterator($array);
$scenario = new ExampleScenario();
$iterate = new Iterate();
// Invoke iterate with our scenario.
$iterate($iterator, $scenario);
print "Found {$scenario->counter} non-empty, non-PHP strings.\n";
// Let's check that empty strings were converted to zeros.
print_r($iterator->getArrayCopy());
// If we invoke Iterate with the same scenario once again, it won't find empty
// strings anymore. Instead, we'll have a higher number in the $counter property
// of the $scenario object, because the "0" doesn't match our patterns.
$iterate($iterator, $scenario);
print "Found {$scenario->counter} non-empty, non-PHP strings.\n";