PHP 수익률의 고급 사용법 알아보기

coldplay.xixi
풀어 주다: 2023-04-09 06:16:01
앞으로
5203명이 탐색했습니다.

PHP 수익률의 고급 사용법 알아보기

오프닝

처음PHPyield를 접했을 때,yield? Baidu에서 검색해 보겠습니다: yield——코루틴, 생성기. 많은 기사에서Iterator,Generator에 대해 이야기하고 있습니다. 이봐~, 이건 PHP iterator의 보완책입니다. 몇 페이지를 더 넘기면Go 코루틴을 찾을 수 있습니다. 호기심에동시성,스레드,파이프라인 통신이 포함된Go 코루틴을 클릭했습니다. , wc, nb, 이것들은PHP를 보러 다시 오면 1분마다Go로 전환하고 싶습니다.PHPyield的时候,感觉,yield是什么黑科技,百度一下:yield——协程,生成器。很多文章都在讲IteratorGenerater, 蛤~,这东西是 PHP 迭代器的一个补充。再翻几页,就是Go 协程。我出于好奇点开看了下Go 协程, 里面都是并发线程管道通讯这类字眼,wc,nb, 这tm才是黑科技啊,再回来看PHP,分分钟想转Go

相关学习推荐:PHP编程从入门到精通

yield 语法加入 PHP

yield语法是在版本5.5加入PHP的,配合迭代器使用,功能上就是流程控制代码,和gotoreturn类似。

以下就是官方提供的 yield 小例子,通过执行结果,我们可分析当代码执行到yield $i时,他会进行return $i, 待echo "$valuen"后,gotofor ($i = 1; $i , 对!PHP 的 yield 就是一个能出能进的语法。在z代码中七进七出,把 $i平平安安得送了出来。


        
로그인 후 복사

我们遇到了什么问题

写代码就是解决问题。我们来看看他们遇到了什么问题:php官方呢,需要言简意赅地把yield介绍给大家。一部分网友呢,需要在有限的资源内完成大文件操作。而我们的鸟哥。面对的一群对当下yield的教程停留于初级而不满意的phper,就以一个任务调度器作为例子,给大家讲了一种yield高级用法。

php.net:生成器语法,
PHP如何读取大文件,
风雪之隅:在PHP中使用协程实现多任务调度.

提出问题,再用yield来解答,看到以上答案,我觉得呢,这PHP协程不过如此(Go协程相比)。

有句话——一个好问题比答案更重要,目前广大网友还没有给yield提出更好,更困难的问题。

yield这个进进出出的语法,很多举例都是再让yield做迭代器啊,或者利用低内存读取超大文本的Excelcsv什么的,再高级就是用它实现一个简单的任务调度器,并且这个调度器,一看代码都差不多。

我来出道题

正如一个好的问题,比答案更有价值

  1. 用PHP实现一个 Socket Server,他能接收请求,并返回Server的时间。

好,这是第一个问题,铺垫。 官方答案

  1. 在原来的代码上,我们加个需求,该Socket Server 处理请求时,依赖其他 Socket Server,还需要有 Client 功能。也就是他能接收请求,向其它Server发起请求。

这是第二个问题,也是铺垫。

  1. 原来的Socket Server同一时间只能服务一个客户,希望能实现一个非阻塞I/OSocket Server, 这个 Server 内有 Socket Client 功能,支持并发处理收到的请求,和主动发起的请求。要求不用多线程,多进程。

这个问题,还是铺垫,这几个问题很干,大家可以想一想,2,3题的答案,都放在一个脚本里了:nio_server.php

以上这段代码,我列举了一个具体的业务,就是用户请求购物车加购动作, 而购物车服务呢,又需要和 产品服务,库存服务,优惠服务 交互,来验证加购动作可行性。有同步,异步方式请求,并做对比。

后续还有很多代码,我都放gitee链接了。使用方法,见readme.md

  1. 最后一个问题:在PHP中,用同步写代码,程序呢异步执行?需要怎么调整代码。

提示:这个和PHPyield语法有关。

再提示:yield语法特征是什么,进进出出!

看着我们的代码,同步, 异步,进进出出你想到了什么?

看到代码,同步处理模式下,这三个函数checkInventorycheckProductcheckPromo

관련 학습 권장사항: 초보부터 마스터까지 PHP 프로그래밍PHP yield구문에 추가된yield 구문은 버전 5.5의 PHP에 추가되었으며 반복자와 함께 사용되며 기능적으로 프로세스 제어입니다.코드는 goto, return과 유사합니다. 다음은 공식에서 제공하는 Yield의 작은 예입니다. 실행 결과를 통해 yield $i로 코드가 실행되면 return $i를 수행하는 것으로 분석할 수 있습니다., echo "$valuen", goto for ($i = 1; $i , 그렇죠! PHP의 Yield는 나가고 들어갈 수 있는 구문이다. z코드에서는 7in, 7out, $i가 안전하게 전송됩니다.
## 启动一个处理耗时2s的库存服务$ php ./other_server.php 8081 inventory 2## 启动一个处理耗时4s的产品服务$ php ./other_server.php 8082 product 4## 监听8083端口,处理一个请求 耗时6s的 promo 服务$ php ./other_server.php 8083 promo 6
로그인 후 복사
로그인 후 복사
어떤 문제에 부딪혔나요코드를 작성하는 것은 문제를 해결하는 것입니다. 어떤 문제가 발생했는지 살펴보겠습니다. PHP 관계자는 모든 사람에게 간결하고 간결한 방식으로 Yield를 소개해야 합니다. 일부 네티즌은 제한된 리소스 내에서 대용량 파일 작업을 완료해야 합니다. 그리고 우리 새 형제. 저는 아직 기본 수준에 불과한 현재의 산출량 튜토리얼에 만족하지 않는 PHPer 그룹을 만났습니다. 저는 yield의 고급 사용법을 가르치기 위해 작업 스케줄러를 예로 사용했습니다. php.net: 생성기 구문,
PHP가 대용량 파일을 읽는 방법
바람과 눈코너: 코루틴을 사용하여 PHP에서 다중 작업 스케줄링 구현질문을 하고 를 사용하세요. 위의 답변을 본 후에는 이 PHP 코루틴이 그 이상은 아니라고 생각합니다(Go 코루틴과 비교). 답변보다 좋은 질문이 중요하다라는 말이 있습니다. 현재 대부분의 네티즌들은 더 좋고 더 어려운 질문을 하지 않았습니다. yield이 입출력 구문은 Yield를 반복자로 사용하거나 매우 큰 텍스트 Excel, 를 읽기 위해 낮은 메모리를 사용하는 예가 많습니다. csv등은 아무리 고급 기능이라도 이를 사용하여 간단한 작업 스케줄러를 구현할 수 있으며, 이 스케줄러의 코드는 얼핏 보면 유사합니다. 질문할게요
좋은 질문처럼 답보다 더 가치있습니다
  1. PHP를 사용하여 요청을 받을 수 있는 소켓 서버를 구현합니다. 서버 시간으로 돌아갑니다.
자, 이것이 무대를 설정하는 첫 번째 질문입니다. 공식 답변
  1. 원본 코드에는 요구사항을 추가했습니다. 소켓 서버가 요청을 처리할 때 다른 소켓 서버에 의존하며 클라이언트 기능도 필요합니다. 즉, 그는 요청을 받고 다른 서버에 대한 요청을 시작할 수 있습니다.
두 번째 질문이자 예시입니다.
  1. 원래 소켓 서버는 한 번에 하나의 클라이언트에만 서비스를 제공할 수 있습니다. 우리는비차단 I/O소켓 서버를 구현하려고 합니다. 소켓 클라이언트 기능은 수신된 요청과 적극적으로 시작된 요청의동시처리를 지원합니다. 멀티스레딩이나 멀티프로세스를 사용할 필요는 없습니다.
이 질문은 여전히 예표입니다. 질문 2와 3에 대한 답변은 모두 nio_server.php에 있습니다. 코드 세그먼트에는 사용자가 장바구니 추가 구매 작업을 요청하고 장바구니 서비스가 추가 구매의 타당성을 확인하기 위해 제품 서비스, 재고 서비스 및 우대 서비스와 상호 작용해야 하는 특정 비즈니스를 나열했습니다. 행동. 요청하고 비교할 수 있는 동기식 및 비동기식 방법이 있습니다.
다음에는 코드가 많을 것 같아서 gitee 링크를 걸어두었습니다. 사용법은 readme.md를 참조하세요
  1. 마지막 질문: PHP에서 코드를 동기적으로 작성하면 프로그램이 비동기적으로 실행됩니까? 코드를 조정하는 방법.
팁: 이는 PHPyield구문과 관련이 있습니다. 또 다른 알림: yield, in and out의 문법적 특징은 무엇입니까? 우리 코드를 보면 동기, 비동기, in and out 강하다> > 무슨 생각이 들었나요? 코드를 확인하세요. 동기 처리 모드에서 이 세 가지 함수checkInventorycheckProductcheckPromo는 요청을 시작하고 차례로 반환된 결과를 기다립니다. , 이 세 가지 기능이 실행된 후 고객 요청에 응답합니다.

异步处理模式下,这三个函数发起请求完毕后,代码就跳出循环了,然后是在select()下的一个代码分支中接收请求, 并收集结果。每次收到结果后判断是否完成,完成则响应客户端。

那么能不能这样:在异步处理的流程中,当Server收到 自己发起的client有数据响应后,代码跳到 nio_server.php 的 247行呢,这样我们的收到请求校验相关的代码就能放到这里,编码能就是同步,容易理解。不然,client的响应处理放在 280 行以后,不通过抓包,真的很难理解,执行了第 247 行代码后,紧接着是从 280 行开始的。

诶~这里是不是有进进出出那种感觉了~ 代码从 247 行出去,开始监听发出Client响应,收到返回数据,带着数据再回到 247 行,继续进行逻辑校验,综合结果后,再响应给客户端。

用yield来解决问题

基于 yield 实现的,同步编码,"异步"I/OSocket Server就实现了。代码。

这里 “异步” 打了引号,大佬别扣这个字眼了。 该是非阻塞I/O

不等大家的答案了,先上我的结果代码吧,代码呢都放在这个目录下了。

gitee https://gitee.com/xupaul/PHP-generator-yield-Demo/tree/master/yield-socket

运行测试代码

clone 代码到本地后,需要拉起4个 command 命令程序:

拉起3个第三方服务

## 启动一个处理耗时2s的库存服务$ php ./other_server.php 8081 inventory 2## 启动一个处理耗时4s的产品服务$ php ./other_server.php 8082 product 4## 监听8083端口,处理一个请求 耗时6s的 promo 服务$ php ./other_server.php 8083 promo 6
로그인 후 복사
로그인 후 복사

启动购物车服务

## 启动一个非阻塞购物车服务$ php ./async_cart_server.php ## 或者启动一个一般购物车服务$ php ./cart_server.php
로그인 후 복사

发起用户请求

$ php ./user_client.php
로그인 후 복사

运行结果呢如下,通过执行的时间日志,可得这三个请求是并发发起的,不是阻塞通讯。

在看我们的代码,三个函数,发起socket请求,没有设置callback,而是通过yield from接收了三个socket的返回结果。

也就是达到了,同步编码,异步执行的效果。

运行结果

非阻塞模式

client 端日志:

通过以上起始时间结束时间,就看到这三个请求耗时总共就6s,也就按照耗时最长的promo服务的耗时来的。也就是说三个第三方请求都是并发进行的。

cart server 端日志:

而 cart 打印的日志,可以看到三个请求一并发起,并一起等待结果返回。达到非阻塞并发请求的效果。

阻塞模式

client 端日志:

以上是阻塞方式请求,可以看到耗时 12s。也就是三个服务加起来的耗时。

cart server 端日志:

cart 服务,依次阻塞方式请求第三方服务,顺序执行完毕后,共耗时12s,当然如果第一个,获第二个服务报错的话,会提前结束这个检查。会节约一点时间。

工作原理

这里就是用到了yield的工作特点——进进出出,在发起非阻塞socket请求后,不是阻塞方式等待socket响应,而是使用yield跳出当前执行生成器,等待有socket响应后,在调用生成器的send方法回到发起socket请求的函数内,在yield from Async::all()接收数据响应数据搜集完毕后,返回。

和Golang比一比

考虑到网速原因,我这就放上一个国内教程链接:Go 并发 教程

php的协程是真协程,而Go是披着协程外衣的轻量化线程(“协程”里,都玩上“锁”了,这就是线程)。

我个人偏爱,协程的,觉得线程的调度有一定随机性,因此需要锁机制来保证程序的正确,带来了额外开销。协程的调度(换入换出)交给了用户,保证了一段代码执行连续性(当然进程级上,还是会有换入换出的,除非是跨进程的资源访问,或者跨机器的资源访问,这时,就要用到分布式锁了,这里不展开讨论),同步编码,异步执行,只需要考虑那个哪个方法会有IO交互会协程跳出即可。

和NodeJS比划一下

Javascript 和 PHP 两个脚本语言有很多相似的地方,弱类型,动态对象,单线程,在Web领域生态丰富。不同的是,Javascript在浏览器端一开始就是异步的(如果js发起网络请求只能同步进行,那么你的网页渲染线程会卡住),例如AjaxsetTimeoutsetInterval,这些都是异步+回调的方式工作。

基于V8引擎而诞生的NodeJS,天生就是异步的,在提供高性能网络服务有很大的优势,不过它的IO编码范式么。。。刚开始是 回调——毁掉地狱,后来有了Promise——屏幕竖起来看,以及Generator——遇事不绝yield一下吧,到现在的Async/Await——语法糖?真香!

可以说JS的委员非常勤快,在异步编程范式的标准制定也做的很好(以前我尝试写NodeJS时,几个回调就直接把我劝退了),2009年诞生的NodeJS有点后来居上的意思。目前PHP只是赶上了协程,期待PHP的Async/Await语法糖的实现吧。

PHP yield 使用注意事项

一旦使用上 yield 后,就必须注意调用函数是,会得到函数结果,还是 生成器对象。PHP 不会自动帮你区别,需要你手动代码判断结果类型——if ($re instanceof \Generator) {}, 如果你得到的是 生成器,但不希望去手动调用 current() 去执行它,那么在生成器前 使用 yield from 交给上游(框架)来解决。

爆改 Workerman

博客写到这,就开始手痒痒了,看到Workerman框架,我在基础上二开,使其能——同步编码,异步执行

代码已放到:PaulXu-cn/CoWorkerman.git

目前还是dev阶段,大家喜欢可以先 体验一波。

$ composer require paulxu-cn/co-workerman
로그인 후 복사
로그인 후 복사

一个简单的单线程 TCP Server

count = 1;$worker->onConnect = function (CoTcpConnection $connection) { try { $conName = "{$connection->getRemoteIp()}:{$connection->getRemotePort()}"; echo PHP_EOL . "New Connection, {$conName} \n"; $re = yield from $connection->readAsync(1024); CoWorker::safeEcho('get request msg :' . $re . PHP_EOL ); yield from CoTimer::sleepAsync(1000 * 2); $connection->send(json_encode(array('productId' => 12, 're' =>true))); CoWorker::safeEcho('Response to :' . $conName . PHP_EOL . PHP_EOL); } catch (ConnectionCloseException $e) { CoWorker::safeEcho('Connection closed, ' . $e->getMessage() . PHP_EOL); }};CoWorker::runAll();
로그인 후 복사

这里设置fork 一个worker线程,处理逻辑中带有一个sleep()2s的操作,依然不影响他同时响应多个请求。

启动测试程序

## 启动CoWorker服务$ php ./examples/example2/coWorkermanServer.php start## 启动请求线程$ php ./examples/example2/userClientFork.php
로그인 후 복사

运行结果

绿色箭头——新的请求,红色箭头——响应请求

从结果上看到,这一个worker线程,在接收新的请求同时,还在回复之前的请求,各个连接交错运行。而我们的代码呢,看样子就是同步的,没有回调。

CoWorker购物车服务

好的,这里我们做几个简单的微服务模拟实际应用,这里模拟用户请求端购物车服务库存服务产品服务。 模拟用户请求加购动作,购物车去分别请求 库存,产品 校验用户是否可以加购,并响应客户请求是否成功。

代码我就不贴了,太长了,麻烦移步 CoWorkerman/example/example5/coCartServer.php

运行命令

## 启动库存服务$ php ./examples/example5/otherServerFork.php 8081 inventory 1## 启动产品服务$ php ./examples/example5/otherServerFork.php 8082 product 2
로그인 후 복사
## 启动CoWorker 购物车服务$ php ./examples/example5/coCartServer.php start
로그인 후 복사
## 用户请求端$ php ./examples/example5/userClientFork.php
로그인 후 복사

运行结果

黄色箭头——新的用户请求,蓝色箭头——购物车发起库存,产品检查请求,红色箭头——响应用户请求

从图中看到也是用1个线程服务多个连接,交错运行。

好的,那么PHPCoWorkerman也能像NodeJS那样用Async/Await那样同步编码,异步运行了。

快来试试这个 CoWorkerman 吧:

$ composer require paulxu-cn/co-workerman
로그인 후 복사
로그인 후 복사

工作原理

先上图:

사진 상단이 워커맨의 작업 동선 다이어그램이고, 사진 하단이 코워커맨의 작업 동선 다이어그램입니다.

workerman작업자 프로세스가 차단 기능을 만나면 IO가 반환될 때까지 기다립니다. 이때 새로운 요청이 있으면 유휴 작업자가 있습니다. 이 새로운 연결에 대한 경쟁이 될 것입니다.workerman内的worker进程遇到阻塞函数的处理方式时,会等待IO返回,如果这个时候,又有了新的请求,那么闲的worker会竞争到这个新的连接。

我在上图worker5中,描述了一个AsyncTCPConnection使用情况,woker内发起了一个非阻塞请求,并注册了回调函数,然后程序继续运行到结束。当异步请求响应时,就需要通过其他方式去响应(如自己再发起一个请求告知请求方)。

在下图中CoWorkerman,也是多个Worker竞争新的请求,当worker1收到一个新的请求,会产生一个生成器,生成器内发起异步请求,并注册响应回调,请求响应后,回到该生成器跳出(yield)的地方,继续执行代码。

发起异步请求,并注册回调函数,这些默认工作CoWorkerman框架内已做了,回调函数内工作是:收到数据,并发给 发起该请求的生成器。

这例子中,通过调用 Promise:all() 发起多个请求,并监听结果返回,待所有的响应返回再继续运行生成器

在程序yield跳出后,该worker就处于事件循环状态($event->loop()),也就是多路监听:请求端口,第三方客户端请求响应端口。这个时候如果:

  1. 有新的请求来,他和其他worker竞争新的请求,如果竞争到了,则该worker内又产生一个新的 生成器。
  2. 客户端有响应,则调用回调函数
  3. 客户端都响应了,继续运行 生成器程序。

从1中,我们可假设,如果就一个Worker,那么该Worker可以在上一个请求未完成情况下,继续接受处理下一个请求。也就是CoWorkerman可以在单Worker下运行,并发处理多个请求。

当然,这里也有个前提,单Worker模式内不能运行阻塞函数,一旦阻塞,后续请求就会堵在网卡。所以,除非对自己的代码非常了解,如果用到第三方库,那么我还是建议你在多Worker模式下运行CoWorkerman,阻塞时,还有其他Worker兜住新请求。

CoWorkerman 的意义

  1. 用同步的代码,发起异步请求,多个请求可并发,从IO串行等待,改为并行等待,减少无畏的等待时间。提高业务程序的效率同时,不降低代码可读性。
  2. 在一个线程内通过事件循环,尽可能处理多个请求,缓解了一个请求一个线程带来的频繁线程切换,从核心上提高运行效率。

CoWorkerman 生态位

适合处理纯Socket请求的应用,如Workerman Gateway,或者是大前端整合多个服务RPC结果, 综合后返给前三页这样的场景.

日志记录是每个程序最基本需求,由于写文件函数是阻塞的,建议用消息队列,或者redis队列,更或者跳过Logstash直接丢Elasticsearch.

CoWorkerman有他的局限性,也有他自己位置。

总结

好~PHP 协程编码到 网络异步编码就到此结束了,如果看到本文章有很多疑惑,欢迎留言提问,如果是yield语法不太记得,可以先读一读这个系列前几篇文章复习一下。

如果行,请三连。CoWorkerman

위의 Worker5 그림에서는AsyncTCPConnection의 사용법을 설명했습니다. 작업자 내에서 비차단 요청이 시작되고 콜백 함수가 등록된 후 프로그램이 끝까지 계속 실행됩니다. . 비동기식 요청이 응답하면 다른 방법으로 응답해야 합니다(예: 요청자에게 알리기 위해 직접 다른 요청을 시작하는 등).

PHP 수익률의 고급 사용법 알아보기아래CoWorkerman그림에는 작업자1이 새 요청을 수신하면 생성기가 생성되고 생성기에서 비동기 요청이 시작되며 여러 작업자가 경쟁하고 있습니다. 응답 콜백이 등록됩니다. 응답을 요청한 후 생성기가 튀어나온 위치(yield)로 돌아가 코드를 계속 실행합니다.

비동기 요청을 시작하고 콜백 함수를 등록합니다. 이러한 기본 작업은 CoWorkerman프레임워크에서 수행되었습니다. 콜백 함수의 작업은 다음과 같습니다. 요청을 시작했습니다.
이 예에서는 Promise:all()을 호출하여 여러 요청이 시작되고 결과가 반환됩니다. 생성기를 계속 실행하기 전에 모든 응답이 반환될 때까지 기다립니다.
프로그램yield가 튀어나온 후 작업자는 이벤트 루프 상태($event->loop()), 즉 다중 채널 모니터링: 요청 포트, 타사 클라이언트 요청 응답 포트. 이때 다음과 같은 경우가 발생합니다.
  1. 새로운 요청이 오면 그는 새로운 요청을 놓고 다른작업자와 경쟁하게 됩니다. 경쟁이 발생하면 작업자에서 새로운 생성기가 생성됩니다. .
  2. 클라이언트가 응답하면 콜백 함수가 호출됩니다.
  3. 클라이언트는 응답하고 생성기 프로그램을 계속 실행합니다.
1에서Worker가 하나만 있는 경우Worker는 이전 요청 처리를 완료하지 않고도 계속할 수 있다고 가정할 수 있습니다. 다음 요청의 즉,CoWorkerman은 단일Worker에서 실행되고 여러 요청을 동시에 처리할 수 있습니다.
물론 여기에는 전제가 있습니다. 단일 Worker모드에서는 차단 기능을 실행할 수 없습니다. 일단 차단되면 이후의 요청은 네트워크 카드에서 차단됩니다. 따라서 자신의 코드를 잘 알지 않는 한, 타사 라이브러리를 사용하는 경우에는 차단할 때 멀티 Worker모드에서 CoWorkerman을 실행하는 것이 좋습니다. , 다른 Worker가 새로운 요청을 보유하고 있습니다.

CoWorkerman의 의미

  1. 동기 코드를 사용하여 비동기 요청, 다중 요청 시작 IO 직렬 대기에서 병렬 대기로 변경하여 동시 작업이 가능하므로 두려움 없는 대기 시간이 줄어듭니다. 코드 가독성을 저하시키지 않으면서 비즈니스 프로그램의 효율성을 향상시킵니다.
  2. 하나의 스레드에서 이벤트 루프를 사용하여 최대한 많은 요청을 처리하므로 하나의 요청과 하나의 스레드로 인해 발생하는 잦은 스레드 전환을 완화하고 코어에서의 작업 효율성을 향상시킵니다.

CoWorkerman 틈새 시장

순수한소켓요청 처리에 적합 애플리케이션 ,Workerman Gateway또는Big Front End와 같은 여러 서비스RPC결과를 통합한 다음 이를처음 세 페이지 code>그런 시나리오입니다.
로깅은 모든 프로그램의 가장 기본적인 요구 사항이므로 파일 쓰기 기능은 Blocking이므로 메시지 큐나 Redis 큐를 사용하거나 Logstash를 생략하는 것이 좋습니다.그냥Elasticsearch를 버리세요.
CoWorkerman에게는 한계가 있고 자신만의 위치가 있습니다.

요약

알겠습니다~이제 PHP 코루틴 코딩에서 네트워크 비동기 코딩으로의 끝입니다. 이 글에 대해 많은 의문점이 있으시면 메시지를 남겨 질문을 남겨주세요.yield구문이 기억나지 않는다면 이 시리즈의 이전 글을 읽어보시면 됩니다. 그것을 검토하십시오. 가능하시면 세번정도 해주세요.CoWorkerman감사합니다!

위 내용은 PHP 수익률의 고급 사용법 알아보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!