`

PHP的工作模型

 
阅读更多

http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/

 

PHP的工作模型非常特殊。从某种程度上说,PHP和ASP、ASP.NET、JSP/Servlet等流行的Web技术,有着本质上的区别。

  以Java为例,Java在Web应用领域,有两种技术:Java Servlet和JSP(Java Server Page)。Java Servlet是一种特殊类型的Java程序,它通过实现相关接口,处理Web服务器发送过来的请求,完成相应的工作。JSP在形式上是一种类似于PHP的脚本,但是事实上,它最后也被编译成Servlet。也就是说,在Java解决方案中,JSP和Servlet是作为独立的Java应用程序执行的,它们在初始化之后就驻留内存,通过特定的接口和Web服务器通信,完成相应工作。除非被显式地重启,否则它们不会终止。因此,可以在JSP和Servlet中使用各种缓存技术,例如数据库连接池。

  ASP.NET的机制与此类似。至于ASP,虽然也是一种解释型语言,但是仍然提供了Application对象来存放应用程序级的全局变量,它依托于ASP解释器在IIS中驻留的进程,在整个应用程序的生命期有效。

  PHP却完全不是这样。作为一种纯解释型语言,PHP脚本在每次被解释时进行初始化,在解释完毕后终止运行。这种运行是互相独立的,每一次请求都会创建一个单独的进程或线程,来解释相应的页面文件。页面创建的变量和其他对象,都只在当前的页面内部可见,无法跨越页面访问。在终止运行后,页面中申请的、没有被代码显式释放的外部资源,包括内存、数据库连接、文件句柄、Socket连接等,都会被强行释放。

  也就是说,PHP无法在语言级别直接访问跨越页面的变量,也无法创建驻留内存的对象。见下例:

 

 

  <?php
  class StaticVarTester {
      public static $StaticVar = 0;
  }
  
  function TestStaticVar() {
       StaticVarTester :: $StaticVar += 1;
       echo "StaticVarTester :: StaticVar = " . StaticVarTester :: $StaticVar;
  }
  
  TestStaticVar();
  echo "<br/>";
  TestStaticVar();
  ?>
 

 

 

   在这个例子中,定义了一个名为StaticVarTester的类,它仅有一个公共的静态成员$StaticVar,并被初始化为0。然后,在TestStaticVar()函数中,对StaticVarTester :: $StaticVar进行累加操作,并将它打印输出。

   熟悉Java或C++的开发者对这个例子应该并不陌生。$StaticVar作为StaticVarTester类的一个静态成员,只在类被装载时进行初始化,无论StaticVarTester类被实例化多少次,$StaticVar都只存在一个实例,而且不会被多次初始化。因此,当第一次调用TestStaticVar()函数时,$StaticVar进行了累加操作,值为1,并被保存。第二次调用TestStaticVar()函数,$StaticVar的值为2。

   打印出来的结果和我们预料的一样:

 

  StaticVarTester :: StaticVar = 1

  StaticVarTester :: StaticVar = 2

 

   但是,当浏览器刷新页面,再次执行这段代码时,不同的情况出现了。在Java或C++里面,$StaticVar的值会被保存并一直累加下去,我们将会看到如下的结果:

 

  StaticVarTester :: StaticVar = 3

  StaticVarTester :: StaticVar = 4

  …

 

   但是在PHP中,由于上文叙及的机制,当前页面每次都解释时,都会执行一次程序初始化和终止的过程。也就是说,每次访问时,StaticVarTester都会被重新装载,而下列这行语句

 

   public static $StaticVar = 0;

 

   也会被重复执行。当页面执行完成后,所有的内存空间都会被回收,$StaticVar这个变量(连同整个StaticVarTester类)也就不复存在。因此,无论刷新页面多少次,$StaticVar变量都会回到起点:先被初始化为0,然后在TestStaticVar()函数调用中被累加。所以,我们看到的结果永远是这个:

 

  StaticVarTester :: StaticVar = 1

  StaticVarTester :: StaticVar = 2

 

  PHP这种独特的工作模型的优势在于,基本上解决了令人头疼的资源泄漏问题。Web应用的特点是大量的、短时间的并发处理,对各种资源的申请和释放工作非常频繁,很容易导致泄漏。同时,大量的动态html脚本的存在,使得追踪和调试的工作都非常困难。PHP的运行机制,以一种非常简单的方式避免了这个问题,同时也避免了将程序员带入到繁琐的缓冲池和同步等问题中去。在实践中,基于PHP的应用往往比基于Java或.NET的应用更加稳定,不会出现由于某个页面的BUG而导致整个站点崩溃的问题。(相比之下,Java或.NET应用可能因为缓冲池崩溃或其他的非法操作,而导致整个站点崩溃。)后果是,即使PHP程序员水平不高,也无法写出使整个应用崩溃的代码。PHP脚本可以一次调用极多的资源,从而导致页面执行极为缓慢,但是执行完毕后所有的资源都会被释放,应用仍然不会崩溃。甚至即使执行了一个死循环,也会在30秒(默认时间)后因为超时而中止。从理论上来说,基于PHP的应用是不太可能崩溃的,因为它的运行机制决定它不存在常规的崩溃这个问题。在实践中,很多开发者也认为PHP是最稳定的Web应用。

  但是,这种机制的缺点也非常明显。最直接的后果是,PHP在语言级别无法实现跨页面的缓冲机制。这种缓冲机制缺失造成的影响,可以分成两个方面:

  一是对象的缓冲。如我们所知,很多设计模式都依赖于对象的缓冲机制,对于需要频繁应付大量并发的服务端软件更是如此。因此,对象缓冲的缺失,理论上会极大地降低速度。但是,由于PHP本身的定位和工作机制等原因,它在实际工作中的速度非常快。就作者自己的经验来看,在小型的Web应用中,PHP至少不比Java慢。在大型的应用中,为了榨干每一分硬件资源,即使PHP本身足够快,一个优秀的对象缓冲机制仍然是必要的。在这种情况下,可以使用第三方的内存缓冲软件,如Memcached。由于Memcached本身的优异特性(高性能,支持跨服务器的分布式存储,和PHP的无缝集成等),在大型的PHP应用中,Memcached几乎已经成为不可或缺的基础设施了。比起使用PHP语言自己实现对象缓冲来,这种第三方解决方案似乎更好一些。

  二是数据库连接的缓冲。对MySQL,PHP提供了一种内置的数据库缓冲机制,使用起来非常简单,程序员需要做的只是用mysql_pconnect()代替mysql_connect()来打开数据库而已。PHP会自动回收被废弃的数据库连接,以供重复使用。具有讽刺意味的是,在实际应用中,这种持久性数据库连接往往会导致数据库连接的伪泄漏现象:在某个时间,并发的数据库连接过多,超过了MySQL的最大连接数,从而导致新的进程无法连接数据库。但是过一段时间,当并发数减少时,PHP会释放掉一些连接,网站又会恢复正常。出现这种现象的原因是,当使用pconnect时,Apache的httpd进程会不释放connect,而当Apache的httpd进程数超过了mysql的最大连接数时,就会出现无法连接的情况。因此,需要小心地调整Apache和Mysql的配置,以使Apache的httpd进程数不会超出MySQL的最大连接数。在某些情况下,一些有经验的PHP程序员宁可继续使用mysql_connect(),而不是mysql_pconnect()。

  就作者所知,在PHP未来的roadmap中,对于工作模型这一部分,没有根本性的变动。这是PHP的缺点,也是PHP的优势,从本质上说,这就是PHP的独特之处。因此,我们很难期待PHP在近期内会对这一问题做出重大的改变。但是,在对待这个问题带来的一系列后果时,我们必须谨慎应对。

 

 

PHP 有两种工作模式:一种是CGI,一种是模块模式

一个是使用exe,一个是使用dll。使用模块,效率比较高

 

 

PHP 在Apache中两种工作方式: CGI模式、Apache模块dll

1.CGI方式 PHP在Apache 2.x 中的CGI方式

# 对 PHP 5 用这行
Action application/x-httpd-php “/php/php-cgi.exe”

2. Apache  Module方式

# 对 PHP 5 用这两行:
LoadModule php5_module “c:/php/php5apache2.dll”
AddType application/x-httpd-php .php

这两种工作方式的区别:

在CGI模式下,如果客户机请求一个php文件,Web服务器就调用php-cgi.exe去解释这个文件,然后再把解释的结果返回给Web Serve,Web Serve以网页的形式返回给客户机;而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。

从某种意义上说,以Apache某块形式运行的php比FastCGI形式有着更好的安全性及执行效率和速度。

CGI (Common Gateway Interface)  通用网关接口,CGI是一种工具,他是用来沟通web服务器和客户端(浏览等)的桥梁,必须运行于网络服务器上面,可以通过很多脚本语言来实现,例如php

FastCGI的工作原理是:
1、Web Server 启动时FastCGI解析器进程也启动;
2、FastCGI解析进程初始化好后等待web Server 发来连接(如果没有连接一直等待,进程一直启动着);
3、当客户端请求到达Web Server时,FastCGI进程管理器会选择并连接其中一个CGI进程来进行解析。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。

 

FastCGI执行方式是以单一线程来执行操作,所以不需要进行线程的安全检查,除去线程安全检查的防护反而可以提高执行效率,所以,如果是以 FastCGI(无论搭配 IIS 6 或 IIS 7)执行 PHP ,都建议下载、执行 non-thread safe 的 PHP (PHP 的二進位檔有兩種包裝方式:msi 、zip ,請下載 zip 套件)。

而线程安全检查正是为ISAPI方式的PHP准备的,因为有许多php模块都不是线程安全的,所以需要使用Thread Safe的PHP。

 

 

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。
FastCGI的官方站点在http://www.fastcgi.com
  FastCGI的工作原理是:
  1、Web Server 启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module);
  2、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
  3、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
  4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

  在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

分享到:
评论

相关推荐

    基于PHP的DayinCMS3D模型管理系统php版源码.zip

    标题"基于PHP的DayinCMS3D模型管理系统php版源码.zip"揭示了这是一个使用PHP编程语言开发的3D模型管理系统的源代码。DayinCMS可能是这个系统的名称,它专为管理和组织3D模型设计。源码以.zip格式提供,意味着用户...

    DayinCMS3D模型管理系统php版v1.3

    DayinCMS 3D模型管理系统是一款基于PHP MYSQL,是一款针对3D打印模型分享的通用开源程序。 1、专向开发,针对3D打印模型分享的需求,支持模型上传,模型展示,模型预定等功能,也可以用在图片素材管理。 2、多点缓存...

    php工作流引擎,可视化设计,兼容PHP8

    1. 高度可定制:PHP工作流引擎允许开发者根据实际业务需求定制工作流模型,包括任务类型、审批规则、流程跳转等。 2. 可扩展性:良好的工作流引擎设计应具备良好的模块化结构,方便添加新的功能和适配不同的业务场景...

    三维展示BIM模型--php嵌套标签

    这样的好处是可以减少前端页面的维护工作量,同时也便于扩展和更新BIM模型资源。 - **动态生成嵌套标签**:通过PHP脚本可以读取数据库中的BIM模型信息,并根据这些信息动态生成相应的`&lt;iframe&gt;`嵌入代码。例如,...

    Server模型及其PHP实现

    Server模型及其PHP实现, 对于掌握socket编程非常实用

    支持对其他模型的字段替换插件 for PHP168 v6.rar

    3. **自定义扩展**:开发者可以利用插件创建新的模型,并通过字段映射来复用已有的字段,减少重复工作。 5. **兼容性增强**:对于第三方应用或模块,如果需要与PHP168 v6的模型进行交互,字段替换功能可以提高兼容...

    《PHP5的对象模型》

    PHP5的对象模型[1]--面向对象编程 PHP5的对象模型[2]--对象模型 PHP5的对象模型[3]--定义一个类 PHP5的对象模型[4]--构造函数和析构函数 PHP5的对象模型[5]--对象复制

    PHP书写的自定义模型的类

    PHP书写的自定义模型的类,可定义后台自定义数据,采用单一入口

    基于JavaScript和PHP的支持更换 Live2D 模型的 Typecho 插件源码

    这个基于JavaScript和PHP的Typecho插件源码是专门为博客平台Typecho设计的,目的是实现Live2D模型的更换功能。Live2D是一种二维动画技术,通过实时渲染和交互,使得静态的2D图像具有生动的动态效果,常见于游戏、...

    php 工作流源码

    在PHP中实现工作流,需要设计数据模型来存储流程状态、任务信息以及参与者信息。这个源码可能包含这样的数据结构设计,如工作流实例表、任务表、参与者表等。 `ThinkPHP`是一个知名的PHP框架,它为快速开发高效、...

    PHP工作流引擎 phpworkflow

    phpworkflow提供了一个灵活的框架,让开发者可以定义和管理各种工作流模型,而无需深陷于底层的流程控制代码。 **核心特性:** 1. **流程定义** - phpworkflow支持XML或YAML格式来定义工作流,使得流程设计易于...

    支持 ACL、RBAC、ABAC 多种模型的 PHP 权限管理框架

    支持 ACL、RBAC、ABAC 多种模型的 PHP 权限管理框架。支持 ACL、RBAC、ABAC 多种模型的 PHP 权限管理框架。支持 ACL、RBAC、ABAC 多种模型的 PHP 权限管理框架。支持 ACL、RBAC、ABAC 多种模型的 PHP 权限管理框架。...

    基于PHP的oms运营管理系统源码,支持自定义模型和工作流配置

    该系统是一款基于PHP的oms运营管理系统源码,包含768个文件,涵盖183个JavaScript脚本、137个SCSS样式表、132...系统具备自定义模型和工作流配置功能,拥有优质的底层架构,服务层抽离,适用于构建灵活的运营管理平台。

    php:连表查询一对一和关联模型一对一

    php:连表查询一对一和关联模型一对一,php:连表查询一对一和关联模型一对一php:连表查询一对一和关联模型一对一php:连表查询一对一和关联模型一对一php:连表查询一对一和关联模型一对一php:连表查询一对一和...

    基于PHP的DayinCMS 3D模型管理系统 php版.zip

    【标题】"基于PHP的DayinCMS 3D模型管理系统 php版.zip" 是一个使用PHP编程语言开发的3D模型管理系统的源代码压缩包。这个系统专为管理和展示3D模型设计,它允许用户上传、存储、搜索和展示各种3D模型数据。PHP作为...

    php phalcon模型使用中文帮助文档

    Phalcon 是开源、全功能栈、使用 C 扩展编写、针对高性能优化的 PHP 5 框架。 开发者不需要学习和使用 C 语言的功能, ... 其中模型是我们开发中常用的,可官方没有详细的中文api文档,本文档按照官方英文文档翻译过来

    基于活动的PHP工作流引擎开发概要

    7. **可扩展性和自定义性**:一个好的PHP工作流引擎应允许用户自定义活动、规则和流程模型,以适应不同企业的业务需求。 8. **日志和审计**:为了监控和跟踪流程执行情况,工作流引擎需要记录详细的日志,并提供...

    PHP MVC

    在PHP MVC中,模型类通常封装了与特定数据表或数据实体相关的操作,如增删改查。例如,一个`UserModel`可能包含了获取用户信息、更新用户状态等方法。 **2. 视图(View)** 视图是用户看到和与之交互的界面部分。它...

    基于php沙盘模型展示网站.zip

    【标题】:“基于PHP沙盘模型展示网站”指的是一个使用PHP编程语言构建的在线平台,该平台通过沙盘模拟的方式展示各种网站功能和交互。PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适用于Web...

    PHP实例开发源码—DayinCMS 3D模型管理系统 php版.zip

    【标题】"PHP实例开发源码—DayinCMS 3D模型管理系统 php版.zip" 提供的是一个基于PHP编程语言的3D模型管理系统的源代码。这个系统可能用于存储、组织、检索和展示3D模型,是Web开发中的一个实用工具,特别适合于...

Global site tag (gtag.js) - Google Analytics