이전에 작성
이 기사에서는 foreach
, for
, while이 없는 생성기에서 PHP Yield를 사용하는 방법에 대해 논의하고 싶습니다.
루프의 종류입니다. 함수를 생성기로 변환하기 위해 yield
를 사용하는 방법을 논의해 보겠습니다. foreach
,for
, while
循环的那种。就讨论 yield
将一个函数变成为生成器的用法。
关于
yield
特性,是在开发PHP5
时被提上日程,PHP5.5
版本正式加入。
关于yield
的使用,我看到大部分文章都停留在,使用yield
如何在foreach
中穿出数据,今天想给大家讲讲 生成器 所有语法。
相关学习推荐:PHP编程从入门到精通
官网讲解
生成器允许你在 foreach
代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield
多次,以便生成需要迭代的值。
看了下官网对他讲解:php.net 生成器语法 . 每个字都认识,但似乎还是体会到它讲的内涵。官网我们主要看两部分内容:
yield
的语法。代码例子。
先说语法, yield 的左边是一个赋值语句,右边可以是值(也可是表达式) 。而yield 会先执行右边的表达式,并把值$value送到生成器外面。当生成器收到值后,会执行yield左边的语句,赋值给$data.
<?phpfunction func(){ $data = (yield [$express]);}
语法就这样,估计大家还是有些懵,那就看看官网下面代码例子吧,我看里面例子参差不齐。
注意yield 外面包的这一层括号,如果是在php5.5,右侧$express的优先级是判断,可能会比左侧$data的赋值语句低的。所以在php5用yield,yield 右边是可运行表达式,左侧需要接受返回并赋值,那么这个括号是有必要的。在php7不会有这个问题。
通过例子来了解它
不论是学 人类语言,计算机语言,都是模仿开始
对于一个用人类语言来描述,都不那么明晰时,所以那就通过例子告诉你它能做什么,不能做什么。
相关代码,我放到gitee了,希望你能复制到你本地运行下,亲自运行感受下,有助于了理解接下来的内容。
git clone gitee.com/xupaul/PHP-generator-yie...
怎样才能产生 Generator
先定义一个函数,在函数内 写个 yield 关键词,将这个函数调用赋值给一个变量。一个生成器就产生了。
代码 /php-yield-test/yieldFunctions.php 是生成器按照不同语法组合定义了多个生成器。
测试代码 /php-yield-test/whatIsGenerator.php,用来检查哪些函数能构成生成器,哪些不能。运行结果如下
- 函数内必须有
yield
关键词,函数可以是全剧函数,或者类的方法。 - 哪怕
yield
肯定不会被执行,也会产生生成器。见:yield_func4 - 光秃秃 的
yield
关键词就行(不向外送出,不处理外面的输入)。见: yield_func2 - 函数内使用 生成器 并不能让自己也成为生成器,见:yield_func5
- eval函数中直接运行
yield
会报错, 见:yield_func11
是的,函数内有没有foreach,while,for 语句都不是关键,关键是 yield. 生成器的类型判断用
$gen instanceof Generator
yield
기능과 관련하여, PHP5
개발 시 안건으로 제기되었고, PHP5.5
버전이 정식 추가되었습니다.
yield
사용과 관련하여 오늘 foreach
에서 yield
를 사용하여 데이터를 소모하는 방법에 대해 대부분의 기사가 붙어 있는 것을 봤습니다. 제너레이터의 모든 구문을 알려드리고 싶습니다.
관련 학습 권장사항: 초보부터 마스터까지 PHP 프로그래밍🎜 🎜공식 웹사이트 설명🎜🎜생성기를 사용하면foreach
코드 블록에 코드를 작성하여 메모리에 배열을 생성하지 않고도 데이터 세트를 반복할 수 있습니다. 이로 인해 메모리가 상한에 도달하거나 상당한 공간을 차지하게 됩니다. 처리 시간. 대신 일반 사용자 정의 함수와 마찬가지로 생성기 함수를 작성할 수 있으며, 한 번만 반환하는 일반 함수 대신 생성기가 값을 반복해야 할 만큼 생성기가 필요한 만큼생성
할 수 있습니다. . 🎜🎜공식 웹사이트를 보고 그에게 설명했습니다: php.net 생성기 구문 저는 모든 단어를 알고 있었지만 여전히 그 의미를 이해하는 것 같았습니다. 공식 웹사이트에서는 주로 🎜🎜 먼저 구문에 대해 이야기해 보겠습니다. 항복의 왼쪽은 대입문이고 오른쪽은 값(또는 표현식)이 될 수 있습니다. Yield는 먼저 오른쪽의 표현식을 실행하고 $value 값을 생성기 외부로 보냅니다. 생성기가 값을 받으면 Yield 왼쪽에 있는 명령문을 실행하고 $data에 값을 할당합니다.🎜
- 🎜
yield
구문 두 부분을 살펴봅니다. 🎜- 🎜코드 예시. 🎜
<?phpfunction yield_func(){ yield 12; return 'a';}$gen = yield_func();$re = $gen->current();echo 'current return : ' . $re;🎜 구문은 아직 다들 헷갈리는 것 같으니 코드를 살펴보세요. 공식 웹 사이트 아래의 예는 고르지 않은 것 같습니다. 🎜🎜🎜yield를 감싸는 괄호 레이어에 주목하세요. php5.5의 경우 오른쪽 $express의 우선 순위가 판단이며 왼쪽 $data의 할당 문보다 낮을 수 있습니다. 따라서 php5에서는 Yield를 사용하세요. Yield의 오른쪽은 연산 가능한 표현식이고, 왼쪽은 반환값을 받아들이고 값을 할당해야 하므로 이 대괄호가 필요합니다. 이 문제는 php7에서는 발생하지 않습니다. 🎜🎜🎜🎜🎜예문으로 배워보세요🎜🎜🎜인간의 언어를 배우든, 컴퓨터 언어를 배우든 모든 것은 모방에서 시작됩니다🎜🎜🎜인간의 언어로 사물을 기술할 때는 명확하지 않으니, 차근차근 말씀드리겠습니다. 예 할 수 있는 것과 할 수 없는 것. 🎜🎜관련 코드를 gitee에 올려 놓았습니다. 로컬 환경에 복사하여 직접 실행해 보시면 다음 내용을 이해하는 데 도움이 될 것입니다. 🎜🎜🎜git clone gitee.com/xupaul/PHP-generator-yie...🎜🎜🎜🎜생성기 생성 방법
🎜먼저 함수를 정의하고, 함수에 Yield 키워드를 쓰고, 함수 호출은 변수에 값을 할당합니다. 발전기가 생성됩니다. 🎜🎜코드 /php-yield-test/yieldFunctions.php는 다양한 구문 조합에 따라 여러 생성기를 정의하는 생성기입니다. 🎜🎜테스트 코드 /php-yield-test/whatIsGenerator.php, 생성기를 구성할 수 있는 함수와 생성할 수 없는 함수를 확인하는 데 사용됩니다. 실행 결과는 다음과 같습니다🎜🎜🎜
🎜🎜예, 함수에 foreach, while 및 for 문이 있는지 여부가 핵심이 아닙니다.
yield
키워드는 함수에 포함되어야 합니다. 함수는 전체 함수이거나 클래스 메서드일 수 있습니다.yield
가 반드시 실행되지 않더라도 제너레이터는 생성됩니다. 참고: Yield_func4- 기본
yield
키워드만 사용하면 됩니다(전송 없음, 외부 입력 처리 없음). 참조: Yield_func2- 함수 내에서 생성기를 사용한다고 해서 그 자체가 생성기가 되는 것은 아닙니다. 참조: Yield_func5
- 평가 함수에서 직접
yield
를 실행하면 다음이 보고됩니다. 오류, 참조: Yield_func11$gen 인스턴스 생성기를 사용하세요. >🎜🎜🎜🎜🎜Generator 함수🎜🎜Generator 개체는 생성기에서 반환됩니다.🎜🎜🎜Generator 개체는 new를 통해 인스턴스화할 수 없습니다.🎜
- Generator::current — 返回当前产生的值
- Generator::key — 返回当前产生的键
- Generator::next — 生成器继续执行
- Generator::rewind — 重置迭代器
- Generator::send — 向生成器中传入一个值
- Generator::throw — 向生成器中抛入一个异常
- Generator::valid — 检查迭代器是否被关闭
- Generator::__wakeup — 序列化回调
- Gengerator::getReturn - Get the return value of a generator
摘自 php.net generator
看着以上方法,是不想起了
Iterator
, 他们的确很像。同时注意,官网zh语言版本的文档没有索引方法getReturn
,访问也是404。文档以en版为准,ch做参考。
以上就是生成器所有的方法,我们一个个来看。
测试方法代码 /php-yield-test/generatorMothod.php, 这里面对每个方法都有使用举例,运行结果如下。
好接下来对举例做个一一讲解。
Generator::current
- 返回当前产生的值
<?phpfunction yield_func(){ yield 12; return 'a';}$gen = yield_func();$re = $gen->current();echo 'current return : ' . $re;
输出:
current return : 12
看到 php-yield-test/generatorMothod.php
代码。
通过第一个代码事例,可得,对一个generator调用current方法,才算真正开始执行。执行到yield为止。如果不能命中yield,则执行到函数结束。
非generoator会立马执行并得到结果,而非一个生成器对象。
通过例子2,调用current一次,两次呢,第一次可以看到代码执行日志,第二次,只是把上一次的结果返回给我们而已,并不是让该生成器重新执行。
通过例子1,调用该函数还会获取到返回值,返回的内容就是 yield 表达式左边的内容。如果表达式无内容,则是NULL.
Generator::send
- 向生成器
yield
点中传入一个值,并返回下一次current
值。
<?phpfunction yield_func(){ $data = yield 12; echo 'get yield data: ' . $data; return 'a';}$gen = yield_func();$re = $gen->current();$gen->send(32);
输出:
get yield data: 32
例子3,是一个current,send的常规调用。调用current代码运行yield等到用户send输入参数。接收到输入后,继续运行。current能够接收到yield弹出的值,send返回值为空。
例子4,直接调用send,相当于调用current,send。不过current的返回值,并不会通过send传给用户。
例子21中,可以看到直接调用send(1),会运行生成器,并向第一个yield处输入1,继续运行至下一个yield的返回值value
。所以,$gen->send(2)
,和 $gen->current()
结果都是同一个值。
也就是说:跳过current,直接调用send,会丢失第一次yield的弹出值。
Generator::next
- 跳过中断,并让生成器继续执行
<?phpfunction yield_func(){ echo 'run to code line: ' . __LINE__ . PHP_EOL; yield; echo 'run to code line: ' . __LINE__ . PHP_EOL; return $result;}$gen = yield_func();$gen->current();echo 'current called' . PHP_EOL;$gen->next();
输出:
run to code line: 4current called run to code line: 6
例子5,这是一个较为常规的调用,调用current
代码运行yield
等到用户输入,这是调用next跳过,让代码继续运行。
例子6,直接调用next
,相当于调用current
,next
。而且通过最后打印$result
, 我们发现怎么有点像在调用 $gen->send(NULL);
。
Generator::rewind
- 重置迭代器
<?phpfunction yield_func(){ echo 'run to code line: ' . __LINE__ . PHP_EOL; $result = yield 12; echo 'run to code line: ' . __LINE__ . PHP_EOL;}$gen = yield_func();echo 'call yield_func rewind ' . PHP_EOL;$gen->rewind();
输出:
call yield_func rewind run to code line: 4
例子7,8 中,发现调用该方法,会导致隐式调用current
。
例子9 中,发现在执行过一个yield代码段后,再次调用该方法,会导致报错(哪怕该 生成器已结束)。
Generator::throw
- 向生成器中抛入一个异常
<?phpfunction yield_func(){ try { $re = yield 'exception'; } catch (Exception $e) { echo 'catched exception msg: ' .$e->getMessage(); }}$gen = yield_func();$gen->throw(new \Exception('new yield exception'));
输出:
catched exception msg: new yield exception
通过以上简单的例子可得,throw 就是让yield这行代码产生异常,让外面的try catch 捕获我们生成的那个异常。
例子11中,构造生成器,并调用current方法,运行到yield处,再调用throw,就能捕获到异常。
例子12中,当调用send方法,跳过函数内yield代码时,再调用throw传入异常,就没法捕获了。
Generator::valid
- 检查迭代器是否被关闭
<?phpfunction yield_func(){ yield 12; return 'a';}$gen = yield_func();$gen->send(1);$check = $gen->valid();echo 'the generator valid ? ' . intval($check);
输出:
the generator valid ? 0
例子12中,发现current被隐式调用。
例子13中,可得,当生成器运行到yield代码段时,用valid
函数检查,都会返回true
。
所以,别问我是否已运行,问就是运行。该方法用来获取是否关闭状态,不是 是否运行状态!运行到底,运行到return就是 关闭状态。
Generator::key
- 返回当前产生的键
<?phpfunction yield_func(){ yield 1 => 'abc';}$gen = yield_func();echo 'value is :' . $gen->current() . PHP_EOL;echo 'key is: ' . $gen->key() . PHP_EOL;
输出:
value is :abc key is: 1
从以上例子中,可得yield可显示设置返回的key.
例子15 中,发现key的分发规律和PHP数组键值发放策略是差不多的,默认从0开始,未指定则是以上一个数字key+1
作为当前的key
.
例子16 中,我们又发现current
被隐式调用。
Generator::__wakeup
- Generator::__wakeup — 序列化回调
<?phpfunction yield_func(){ yield 1 => 'abc';}$gen = yield_func();try {$ser = serialize($gen);} catch (\Exception $e) { print_r($e->getMessage());}
输出:
Serialization of 'Generator' is not allowed
这是一个魔术方法,见 PHP 魔术方法,也就是说 生成器 不能被序列化成一个字符串。
例子17就不用说了,看下例子18,看样子序列化成功了。也就是说一个生成器做为一个方法可以被序列化,当函数变成生成器时,就不能被序列化了。
Generator::getReturn
<?phpfunction yield_func(){ yield 1 => 'abc'; return 32;}$gen = yield_func();$gen->send(0);echo 'call yield_func return, and get: ' . $gen->getReturn();
输出:
call yield_func return, and get: 32
该函数就是获取生成器最后的返回值。如果没有return语句,或者没有执行到return语句,调用该函数得到的就是NULL。
例子19 可得,getReturn 能够获取到生成器最后的返回值。
例子19、20 可得,当生成器没有执行到return语句,或者没有执行到最后时,调用getReturn是会导致报错。
综上所述
到这里,我们就发现rewind
,next
和 __wakeup
这两个函数感觉没啥叼用呢,为啥还存在呢,因为Generator
继承Iterator
,自然就有了rewind
, next
方法,PHP
虽然支持方法覆盖,但子类的访问修饰符
不能缩紧,所以Generator
只能重写这两个方法。 __wakeup
继承自 stdClass
。
状态转换
看图:
PHP yield 生命周期图
画了两个状态转换图,上面的要细致,繁复一点。下面的精简版,便于快速理解。
总结
以上就是关于 PHP 生成器的基础内容,希望你看了后对它有更进一步认识。下一讲,我们手把手一起来做一个任务调度器,实战一下。
有问题欢迎提问,谢谢大家!
위 내용은 PHP 항복 코루틴 생성기 사용법 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

세션 관련 XSS 공격으로부터 응용 프로그램을 보호하려면 다음 조치가 필요합니다. 1. 세션 쿠키를 보호하기 위해 Httponly 및 Secure 플래그를 설정하십시오. 2. 모든 사용자 입력에 대한 내보내기 코드. 3. 스크립트 소스를 제한하기 위해 컨텐츠 보안 정책 (CSP)을 구현하십시오. 이러한 정책을 통해 세션 관련 XSS 공격을 효과적으로 보호 할 수 있으며 사용자 데이터가 보장 될 수 있습니다.

PHP 세션 성능을 최적화하는 방법 : 1. 지연 세션 시작, 2. 데이터베이스를 사용하여 세션을 저장, 3. 세션 데이터 압축, 4. 세션 수명주기 관리 및 5. 세션 공유 구현. 이러한 전략은 높은 동시성 환경에서 응용의 효율성을 크게 향상시킬 수 있습니다.

THESESSION.GC_MAXLIFETIMESETTINGINSTTINGTINGSTINGTERMINESTERMINESTERSTINGSESSIONDATA, SETINSECONDS.1) IT'SCONFIGUDEDINPHP.INIORVIAINI_SET ()

PHP에서는 Session_Name () 함수를 사용하여 세션 이름을 구성 할 수 있습니다. 특정 단계는 다음과 같습니다. 1. Session_Name () 함수를 사용하여 Session_Name ( "my_session")과 같은 세션 이름을 설정하십시오. 2. 세션 이름을 설정 한 후 세션을 시작하여 세션을 시작하십시오. 세션 이름을 구성하면 여러 응용 프로그램 간의 세션 데이터 충돌을 피하고 보안을 향상시킬 수 있지만 세션 이름의 독창성, 보안, 길이 및 설정 타이밍에주의를 기울일 수 있습니다.

세션 ID는 로그인시, 민감한 작업 전에 및 30 분마다 정기적으로 재생되어야합니다. 1. 세션 고정 공격을 방지하기 위해 로그인 할 때 세션 ID를 재생합니다. 2. 안전성을 향상시키기 위해 민감한 작업 전에 재생성. 3. 정기적 인 재생은 장기 활용 위험을 줄이지 만 사용자 경험을 평가해야합니다.

Session_SET_COOKIE_PARAMS () 함수를 통해 PHP에서 세션 쿠키 매개 변수 설정을 달성 할 수 있습니다. 1)이 기능을 사용하여 만료 시간, 경로, 도메인 이름, 보안 플래그 등과 같은 매개 변수를 설정하십시오. 2) call session_start ()를 호출하려면 매개 변수를 발효시킵니다. 3) 사용자 로그인 상태와 같은 요구에 따라 매개 변수를 동적으로 조정합니다. 4) 보안을 향상시키기 위해 안전하고 httponly 플래그 설정에주의를 기울이십시오.

PHP에서 세션을 사용하는 주요 목적은 다른 페이지간에 사용자의 상태를 유지하는 것입니다. 1) 세션은 Session_Start () 함수를 통해 시작되어 고유 한 세션 ID를 생성하고 사용자 쿠키에 저장합니다. 2) 세션 데이터는 서버에 저장되므로 로그인 상태 및 쇼핑 카트 컨텐츠와 같은 다른 요청간에 데이터를 전달할 수 있습니다.

하위 도메인 간의 세션을 공유하는 방법? 공통 도메인 이름에 대한 세션 쿠키를 설정하여 구현. 1. 세션 쿠키 도메인을 서버 측에서 .example.com으로 설정하십시오. 2. 메모리, 데이터베이스 또는 분산 캐시와 같은 적절한 세션 저장 방법을 선택하십시오. 3. 쿠키를 통해 세션 ID를 전달하면 서버는 ID를 기반으로 세션 데이터를 검색하고 업데이트합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Dreamweaver Mac版
시각적 웹 개발 도구

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는
