Generator::send

(PHP 5 >= 5.5.0, PHP 7)

Generator::sendПередать значение в генератор

Описание

public Generator::send ( mixed $value ) : mixed

Передача заданного значения в генератор как результат текущего выражения yield и возобновление его работы.

Если генератор еще не дошел до первого вызова оператора yield, он выполнится до момента первого вызова yield, прежде чем передаст в него значение. Так что нет необходимости вызывать генератор с помощью Generator::next() перед вызовом этого метода (как это делается в Python).

Список параметров

value

Значение, которое отправляется в генератор. Это значение будет текущим возвращаемым значением выражения yield генератора.

Возвращаемые значения

Возвращает сгенерированное значение.

Примеры

Пример #1 Использование Generator::send() для внедрения значений

<?php
function printer() {
    echo 
"I'm printer!".PHP_EOL;
    while (
true) {
        
$string = yield;
        echo 
$string.PHP_EOL;
    }
}

$printer printer();
$printer->send('Hello world!');
$printer->send('Bye world!');
?>

Результат выполнения данного примера:

I'm printer!
Hello world!
Bye world!

add a note add a note

User Contributed Notes 4 notes

up
53
sfroelich01 at sp dot gm dot ail dot am dot com
6 years ago
Reading the example, it is a bit difficult to understand what exactly to do with this. The example below is a simple example of what you can do this.

<?php
function nums() {
    for (
$i = 0; $i < 5; ++$i) {
               
//get a value from the caller
       
$cmd = (yield $i);
       
        if(
$cmd == 'stop')
            return;
//exit the function
       
}    
}

$gen = nums();
foreach(
$gen as $v)
{
    if(
$v == 3)//we are satisfied
       
$gen->send('stop');
   
    echo
"{$v}\n";
}

//Output
0
1
2
3
?>
up
10
sergei dot solomonov at gmail dot com
5 years ago
<?php
function foo() {
   
$string = yield;
    echo
$string;
    for (
$i = 1; $i <= 3; $i++) {
        yield
$i;
    }
}

$generator = foo();
$generator->send('Hello world!');
foreach (
$generator as $value) echo "$value\n";
?>

This code falls with the error:
PHP Fatal error:  Uncaught exception 'Exception' with message 'Cannot rewind a generator that was already run'.
foreach internally calls rewind, you should remember this!
up
-1
anonymous at example dot com
2 months ago
As of 7.3, the behavior of a generator in a foreach loop depends on whether or not it expects to receive data. Relevant if you are experiencing "skips".

<?php
class X implements IteratorAggregate {
    public function
getIterator(){
        yield from [
1,2,3,4,5];
    }
    public function
getGenerator(){
        foreach (
$this as $j => $each){
            echo
"getGenerator(): yielding: {$j} => {$each}\n";
           
$val = (yield $j => $each);
            yield;
// ignore foreach's next()
           
echo "getGenerator(): received: {$j} => {$val}\n";
        }
    }
}
$x = new X;

foreach (
$x as $i => $val){
    echo
"getIterator(): {$i} => {$val}\n";
}
echo
"\n";

$gen = $x->getGenerator();
foreach (
$gen as $j => $val){
    echo
"getGenerator(): sending:  {$j} => {$val}\n";
   
$gen->send($val);
}
?>

getIterator(): 0 => 1
getIterator(): 1 => 2
getIterator(): 2 => 3
getIterator(): 3 => 4
getIterator(): 4 => 5

getGenerator(): yielding: 0 => 1
getGenerator(): sending:  0 => 1
getGenerator(): received: 0 => 1
getGenerator(): yielding: 1 => 2
getGenerator(): sending:  1 => 2
getGenerator(): received: 1 => 2
getGenerator(): yielding: 2 => 3
getGenerator(): sending:  2 => 3
getGenerator(): received: 2 => 3
getGenerator(): yielding: 3 => 4
getGenerator(): sending:  3 => 4
getGenerator(): received: 3 => 4
getGenerator(): yielding: 4 => 5
getGenerator(): sending:  4 => 5
getGenerator(): received: 4 => 5
up
-7
kexianbin at diyism dot com
3 years ago
an example:

$coroutine=call_user_func(create_function('', <<<'fun_code'
    echo "inner 1:\n";
    $rtn=(yield 'yield1');
    echo 'inner 2:';var_export($rtn);echo "\n";
    $rtn=(yield 'yield2');
    echo 'inner 3:';var_export($rtn);echo "\n";
    $rtn=(yield 'yield3');
    echo 'inner 4:';var_export($rtn);echo "\n";
fun_code
));
echo ":outer 1\n";                                       // :outer 1
var_export($coroutine->current());echo ":outer 2\n";     // inner 1:, 'yield1':outer 2
var_export($coroutine->current());echo ":outer 3\n";     // 'yield1':outer 3
var_export($coroutine->next());echo ":outer 4\n";        // inner 2:NULL, NULL:outer 4
var_export($coroutine->current());echo ":outer 5\n";     // 'yield2':outer 5
var_export($coroutine->send('jack'));echo ":outer 6\n";  // inner 3:'jack', 'yield3':outer 6
var_export($coroutine->current());echo ":outer 7\n";     // 'yield3':outer 7
var_export($coroutine->send('peter'));echo ":outer 8\n"; // inner 4:'peter', NULL:outer 8
To Top