我需要一些帮助来理解PHP的内部工作原理。
请记住,在过去,我们曾经写过TSR(终止和驻留)例程(Pre-windows时代)?一旦执行该程序,它将保留在内存中,并可通过某些热键(alt-或ctrl-组合键)重新执行。
我想在Web服务器/应用程序中使用类似的概念。比方说,我有common_functions.php,它包含常用函数(如Generate_City_Combo()或Check_Permission()或Generate_User_Permission_list()等)到该apache / php服务器上运行的所有Web应用程序。
在所有模块或应用程序的php文件中,我可以写:
require_once(common_functions.php);
将在所有模块和应用程序中包含该公共文件,并且工作正常。
我的问题是:php如何在内部处理这个问题?
说我有:
两个应用程序AppOne和AppTwo
AppOne有两个菜单选项AppOne_Menu_PQR和AppOne_Menu_XYZ
AppTwo有两个菜单选项AppTwo_Menu_ABC和APPTwo_Menu_DEF
所有这四个菜单项都从common_functions.php调用函数{如Generate_City_Combo()或Check_Permission()或Generate_User_Permission_list()}
现在考虑以下场景: A)用户XXX登录并点击其个性化仪表板上的AppOne_Menu_PQR,然后他/她将完成所有屏幕和说明。这是一系列8-10页的请求(屏幕),它是交互式的。在此结束之后,用户XXX从他的个性化仪表板中点击AppTwo_Menu_DEF,并再次像之前他/她一样通过所有屏幕和指令(大约8-10页/屏幕)。然后用户XXX注销。
B)用户XXX登录并执行方案A中提到的任何操作。同时,用户YYY也登录(从其他客户端计算机)并执行方案A中提到的类似操作。
对于方案A,它是同一个会话。对于场景B,有两个不同的会话。
假设所有菜单选项都调用Generate_User_Permission_list()和Generate_Footer()或许多菜单选项调用Generate_City_Combo()。
那么每次请求PHP会执行/包含common_functions.php多少次?每次会议?或者每个PHP启动/关闭?我的理解是common_functions.php将在每个页面请求/循环/加载/屏幕执行一次,对吗?基本上每次互动一次。
记住Generate_City_Combo()或Generate_Footer()之类的函数产生相同的输出或做同样的事情,无论是谁或何时调用。
我想在每个应用程序启动和关闭时将其限制为一次。
这些只是一些例子。我的实际问题要复杂得多。在我的应用程序中,我想只调用一次Application_Startup()例程,这将创建理想的环境(如所有查找和引用数据结构,只读数据,安全矩阵,菜单选项,上下文敏感的业务执行逻辑等。 )。之后,所有进入服务器的请求都不需要花费任何时间或资源来创建环境,但可以立即引用“已创建的环境”。
这在PHP中是否可行?怎么样?你能指点我到某个地方或一些解释PHP内部工作的书吗?
提前致谢。
答案 0 :(得分:2)
PHP在一个完全独立的执行框架中处理每个HTTP请求 - 没有持久的进程运行来为它们提供服务。 (您的网络服务器正在运行,但每次加载PHP页面时,都会调用PHP解释器的单独实例。)
如果生成所需持久区域所需的时间很长,您可能希望考虑将这些脚本的输出缓存在磁盘上,并在缓存版本可用时首先加载(而不是过时)。
答案 1 :(得分:1)
PHP(几乎在所有情况下)都是面向页面的。没有Application_Startup()可以跨HTTP请求维护状态。
您有时可以通过从数据库或$ _SESSION加载/卸载序列化数据来模拟这种情况,但是会产生开销。此外,在其他情况下,memcached服务器也可以对此进行优化,但您通常无法使用典型虚拟主机服务(如cPanel)。
如果我必须像你所说的那样构建一个应用程序,我会将用户选择序列化到会话中,然后保存数据库中会话之间持续存在的任何需求。
PHP有几个ORM模块,如Doctrine,可以简化数据库的对象序列化。
答案 2 :(得分:1)
我会说你可能过早地进行优化,但有希望。
您经常需要在内存中复制已编译代码的多个副本,因为您希望每个请求具有稳定性;您不希望在相同的内存空间中运行单独的请求,并且存在竞争条件或数据损坏的风险!
也就是说,有numerous PHP Accelerators可以预编译PHP代码,大大加快了include和require调用。
答案 3 :(得分:0)
我在这里是不可思议的,但随着PThread的出现,似乎可能会有一个实际解决方案的方向,而不是仅仅说,实际上,“没有,你不能用PHP做到这一点。“
一个人基本上可以用PHP创建自己的多线程Web服务器,只需使用CLI工具,socket_ *函数和PThreads。只需侦听端口80,将请求添加到请求队列,然后启动一些工作线程来处理队列。
可以根据请求队列长度和操作系统的运行队列长度来管理工作器数。每隔几秒,主线程就可以通过一个函数来管理工作池的大小。如果Web请求队列长度大于某些常量时间,则操作系统的运行队列长度和工作者数量小于配置的最大值,它可以实例化另一个工作线程。如果Web请求队列长度小于其他(较低)常量时间,则OS的运行队列长度和工作者数量大于配置的最小值,它可能会告诉其中一个工作线程在完成其当前请求时死亡。然后可以调整常量和配置值,以最大化服务器的所有吞吐量。这样的事情。
您必须自己进行所有uri解析,并且必须自己将HTTP响应拼凑在一起,但工作线程可以实例化扩展Threaded的对象,或者重用以前实例化的Threaded对象。
Voila - PHP TomCat。