이 기사에서는 특정 참조 값이 있는 PHP 타이머에 대한 설명을 주로 소개합니다. 이제 모든 사람과 공유합니다. 도움이 필요한 친구가 참조할 수 있습니다.
두 가지 일반적인 타이머가 있습니다. 하나는 보고서와 같은 주기적인 타이밍 실행입니다. 매일 오전 3시에 발행되고, 다른 하나는 지정된 시간(1회) 후에 실행됩니다. 예를 들어 일일 로그인 보상은 회원이 시스템에 로그인한 후 5분 후에 발행됩니다. 두 가지 상황은 셸의 cron
및 at
명령과 JavaScript
의 setInterval
및 setTimeout에 해당합니다. >
함수도 비슷합니다(엄밀히 말하면 setInterval
은 주기적으로 실행되며, 지정된 시점의 실행은 스스로 처리해야 합니다). cron
和at
命令,与JavaScript
中的setInterval
和setTimeout
函数类似(严格来说setInterval
是周期性执行,指定时间点执行需要自行处理)。
做web开发的PHP程序员对JavaScript中的两个定时器函数应该都还熟悉,回到PHP层面就有点傻眼:PHP中有sleep
,但是没有(内置)定时器函数可用。sleep
函数勉强可以做到,但会导致进程阻塞,期间不能做其他事(或无响应)。为什么PHP没能提供定时器(Timer)这个功能呢?
个人认为,web开发中PHP不能使用定时器的本质原因是可控 常驻内存运行环境的缺失。两个要点:第一常驻内存,第二可控。CGI模式下,进程执行完脚本后直接退出,不能指望其到指定时间运行任务;PHP-FPM模式下,进程(绝大多数)常驻内存,但不可控。
不可控的意思是执行PHP的进程不受PHP代码影响,进程的入口点和退出时机由额外的程序控制。例如FPM模式下,PHP脚本中的exit
、die
函数只中断脚本的执行,不会对执行脚本的进程产生特别的影响(内存泄露除外)。PHP开发人员编写的脚本是进程的执行体,执行完毕后就从进程的执行上下文中卸载出去。这种情况下,执行PHP脚本的时机仍然由外部驱动,没有外部请求PHP代码就安详的躺在硬盘上,什么都不做,也就定时任务。
由于PHP主要面向web开发,PHP这种执行模式稳定可靠,开发效率快。比如省去资源释放这一步,就避免了开发中很多工作量和坑。想想某些第三方库代码中改时区、字符编码等还不还原,在常驻内存运行环境下几乎肯定会导致后续请求有问题。但在FPM模式下,这种坑无意中直接趟平,省去许多调试时间,为程序员保住发际线做出了不小的贡献。
问题已经了解,那么PHP中如何使用定时器执行定时任务?
在web环境下,PHP脚本默认有超时时间。去掉超时设置,就可以让程序一直在后台运行(如果进程不退出的话)。例如以下代码在响应请求后继续后台运行,并且每五秒钟输出一次时间到文件:
# test.php set_time_limit(0); # 取消超时设置,让脚本可一直运行 echo 'This is a background run forever script. Now you can leave me alone.'; fastcgi_finish_request(); # 结束当前请求 do{ file_put_contents("/tmp/out.dat", "test script, now:" . date("Y-m-d H:i:s") . "\n", FILE_APPEND); sleep(5); }while(true);
请求http://localhost:8080/test.php
文件后,监测/tmp/out.dat
文件,会发现不断有内容输出,无论客户端是否断开连接、关闭浏览器或者重启电脑(不能重启服务器)。这说明程序一直在执行,并且也实现了我们想要的定时器功能。如果把sleep
改成usleep
、time_nanosleep
,还能实现微秒、纳秒级定时器,岂不美哉?
实践中应当尽量避免用这种方式实现定时器,不仅因为低效,还略有危险。原因之一是每次请求会占用一个进程,请求十万次需要十万个进程,基本上会导致系统崩溃或后续请求无响应;另外如果打开了session,但是忘记调用session_write_close
sleep
이 있지만 (내장- 에서) 타이머 기능을 사용할 수 있습니다. sleep
기능은 거의 수행할 수 없지만 이 기간 동안 프로세스가 차단되고 다른 작업을 수행할 수 없습니다(또는 응답하지 않게 됨). PHP는 왜 타이머 기능을 제공하지 않습니까? 이유개인적으로 PHP가 웹 개발에서 타이머를 사용할 수 없는 근본적인 이유는 제어 가능한 상주 메모리 운영 환경이 부족하기 때문이라고 생각합니다. 두 가지 핵심 사항: 첫째, 상주 메모리, 둘째, 제어 가능. CGI 모드에서는 프로세스가 스크립트 실행 후 바로 종료되며 지정된 시간에 작업이 실행될 것으로 예상할 수 없습니다. PHP-FPM 모드에서는 프로세스가 (대부분) 메모리에 상주하지만 제어할 수 없습니다. Uncontrollable은 PHP를 실행하는 프로세스가 PHP 코드의 영향을 받지 않으며 프로세스의 진입점과 종료 시점이 추가 프로그램에 의해 제어된다는 의미입니다. 예를 들어, FPM 모드에서 PHP 스크립트의 exit
및 die
함수는 스크립트 실행을 중단할 뿐이며 스크립트를 실행하는 프로세스에 특별한 영향을 미치지 않습니다. (메모리 누수는 제외) PHP 개발자가 작성한 스크립트는 프로세스의 실행 본문이며 실행 후 프로세스의 실행 컨텍스트에서 언로드됩니다. 이 경우 PHP 스크립트를 실행하는 타이밍은 여전히 외부에 의해 좌우됩니다. 외부 요청이 없으면 PHP 코드는 아무 작업도 하지 않고 조용히 하드 디스크에 놓여 예약된 작업이 됩니다. PHP는 주로 웹 개발을 지향하기 때문에 PHP의 실행 모드는 안정적이고 신뢰할 수 있으며 개발 효율성이 빠릅니다. 예를 들어 리소스 릴리스 단계를 생략하면 개발 시 많은 작업량과 함정을 피할 수 있습니다. 시간대, 문자 인코딩 등을 변경하고 이를 복원하지 않는 일부 타사 라이브러리 코드를 생각해 보세요. 상주 메모리 실행 환경에서는 후속 요청에 거의 확실히 문제가 발생할 것입니다. 그러나 FPM 모드에서는 이 함정이 의도치 않게 완화되어 디버깅 시간을 많이 절약하고 프로그래머의 헤어라인 유지 능력에 상당한 기여를 합니다. rrreee
http://localhost:8080/test.php 파일, <code>/tmp/out.dat
파일을 모니터링하면 클라이언트 연결 끊기, 브라우저 닫기, 컴퓨터 재시작 여부에 관계없이 콘텐츠가 계속 출력되는 것을 확인할 수 있습니다(서버는 다시 시작했습니다). 이는 프로그램이 실행되었으며 우리가 원하는 타이머 기능이 달성되었음을 나타냅니다. sleep
을 usleep
또는 time_nanosleep
으로 변경하면 마이크로초 및 나노초 타이머도 구현할 수 있으면 좋지 않을까요?
session_write_close
를 호출하는 것을 잊어버리면 동일한 사용자의 후속 요청이 중단됩니다. 세션은 활성 상태일 때 잠긴 상태이며 세션을 닫지 못하면 후속 프로세스를 수행할 수 없습니다. 세션을 열려면). 웹 개발에서는 사용자 요청에 가능한 한 빨리 응답해야 합니다. 웹 개발에서 이러한 방식으로 타이머를 강제로 구현하면 전체 웹 애플리케이션이 불안정하고 신뢰할 수 없거나 예측할 수 없게 됩니다. 맹자가 말했다: 군자는 위험한 벽 아래 서지 않는다. 신뢰할 수 없는 관행은 최대한 피해야 하며, 책임을 떠맡거나 전가하는 행위도 피해야 합니다. 솔직히 말해서 CLI 모드를 사용하면 PHP의 공간을 많이 확장할 수 있습니다. CLI 모드에서 프로그램의 진입점은 스크립트이고 코드는 메모리에 상주할 수 있으며 프로세스는 PHP 코드에 의해 완전히 제어됩니다. 이 형식에는 타이머를 구현하는 방법이 많이 있습니다. 이 문서에는 다른 사람에게 영감을 줄 수 있는 여러 가지 방법이 나열되어 있습니다.
기본 제공되는 swoole
및 workerman
과 같은 프레임워크 사용 (고정밀) 타이머 swoole
、workerman
等框架,内置(高精度)定时器;
使用多进程(池)/多线程(池)技术(pcntl
、pthreads
拓展在CLI模式下才可用);
处理tick或者alarm等信号;
使用libevent
、libev
等事件驱动库;
sleep
加循环或自己实现事件循环。
想折腾的话自己用2-5方案,不想折腾swoole
、workerman
pcntl
, pthreads
확장은 CLI 모드에서만 사용할 수 있습니다.) #🎜🎜 #
libevent
, libev
및 기타 이벤트 기반 라이브러리를 사용하세요.
sleep
루프를 추가하거나 직접 이벤트 루프를 구현하세요. 만들고 싶다면 swoole
과 같은 프레임워크를 엉망으로 만들고 싶지 않다면 직접 2-5 계획을 사용하세요. code> 및 workerman
은 안정적이고 신뢰할 수 있는 첫 번째 선택입니다.
위 내용은 PHP 타이머 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!