翻译php底层运行机制与原理

PHP是一种适用于web开发的动态语言。具体点说,就是一个用C语言实现包含大量组件模块的软件框架。是一个强大的UI框架。

简言之;PHP动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也是C的函数,实际上,我们可以把PHP看做一个C开发的软件。

PHP的所有应用程序都是通过WEB服务器(如IIS,Nginx或Apache)和PHP引擎程序解释执行完成的,工作过程:

(1)当用户在浏览器地址中输入要访问的PHP页面文件名,然后触发一个web请求,并将请求传

送到WEB服务器。(2)WEB服务器接受这个请求,并根据其后缀进行判断是一个PHP请求,WEB服务器从硬盘或内存中调出用户要访问的PHP应用程序,并将其发送给PHP引擎程序。(3)PHP引擎程序将会对WEB服务器传送过来的文件从头到尾进行扫描并根据命令从后台读取,处理数据,并动态地生成相应的HTML页面。

(4)PHP引擎将生成HTML页面返回给WEB服务器。WEB服务器再将HTML页面返回给客户端浏览器。

php运行模式:

1)cgi通用网关接口(CommonGatewayInterface))

2)fast-cgi常驻(long-live)型的CGI

3)cli命令行运行(CommandLineInterface)

4)web模块模式(apache等web服务器运行的模块模式)

一.PHP的设计理念及特点

1、多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,目前PHP也早支持多线程模型。

2、弱类型语言:和C/C++、JAVA、C#等语言不同,PHP是一种弱类型的语言。一个变量的类型并不是一开始就确定不变的,运行中才会确定并可能发生隐式或显示的类型转换,这种机制的灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。

3、引擎(Zend)+组件(ext)的模式降低内部耦合。

4、中间层(sapi)Sapi全称是ServerApplicationProgrammingInterface隔绝webserver和PHP。

5、语法简单灵活,没有太多规范。缺点导致风格混杂。

二、PHP的四层体系

PHP的核心架构如下图:

PHP从下倒上是一个4层体系:

1、Zend引擎:Zend整体用纯C实现,是PHP的内核部分,他将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如:hashtable、OO)、内存分配机制及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕Zend实现。

2、Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(array系列)、标准库等都是通过extension来实现,用户也可以根据需要实现自己的extension的典型应用)。

3、Sapi:Sapi全称ServerApplicationProgrammingInterface,也就是服务端应用编程接口,Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的设计,通过sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。

4、上层应用:这就是我们平时编写的PHP程序,通过不同的spai方式得到各种各样的应用模式,如何通过webserver实现web应用、在命令行下已脚本方式运行等等。

我们需要:性能优异的引擎(Zend)+合适的车轮(Ext)+正确的跑道(Sapi)。

三、Sapi

Sapi通过一系列的接口,使得外部应用可以和PHP交换数据并可以根据不同应用特点实现特定的处理方法,我们常见一些sapi有:

1、apache2handler:这是以apache作为webserver,采用mod_PHP模式运行时候的处理方式,也是现在应用最广泛的一种。

2、cgi:这是webserver和PHP直接的另一种交互方式,也就是大名鼎鼎的fastcgi协议,在最近fastcgi+PHP得到越来越多的应用,也是异步webserver所唯一支持的方式;典型应用nginx服务器;fastcgi说白点就是php的一个扩展

WebServer启动时载入FastCGI进程管理器(IISISAPI或ApacheModule)FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自WebServer的连接。当客户端请求到达WebServer时,FastCGI进程管理器选择并连接到一个CGI解释器。Webserver将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回WebServer。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。在CGI模式中,php-cgi在此便退出了。在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistentdatabaseconnection)可以工作。

3、cli:命令行调用的应用模式

命令行界面(英语:      常见的字符串拼接方式及速度比较:假设有如下4个变量:$strA=‘’;$strB=‘’;$intA=;intB=;

     现在对如下的几种字符串拼接方式做一个比较和说明:

1$s=$strA.$strB和$s=“$strA$strB”2这种情况下,zend会重新malloc一块内存并进行相应处理,其速度一般3$strA=$strA.$strB4这种是速度最快的,zend会在当前strA基础上直接lloc,避免重复拷贝5$s=$intA.$intB6这种速度较慢,因为需要做隐式的格式转换,实际编写程序中也应该注意尽量避免7$strA=sprintf(“%s%s”,$strA.$strB);8这会是最慢的一种方式,因为sprintf在PHP中并不是一个语言结构,本身对于格式识别和处理就需要耗费比较多时间,另外本身机制

  也是malloc内存。不过sprintf的方式最具可读性,实际中可以根据具体情况灵活选择。

PHP的数组通过ZendHashTable来天然实现。foach操作如何实现?对一个数组的foach就是通过遍历hashtable中的双向链表完成。对于索引数组,通过foach遍历效率比for高很多,省去了key-value的查找。count操作直接调用HashTable-NumOfElements,O(1)操作。对于’’这样的字符串,zend会转换为其整数形式。$arr[‘’]和$arr[]是等价的

资源类型变量是PHP中最复杂的一种变量,也是一种复合型结构。PHP的zval可以表示广泛的数据类型,但是对于自定义的数据类型却很难充分描述。由于没有有效的方式描绘这些复合结构,因此也没有办法对它们使用传统的操作符。要解决这个问题,只需要通过一个本质上任意的标识符(label)引用指针,这种方式被称为资源。

在zval中,对于source,lval作为指针来使用,直接指向资源所在的地址。Resource可以是任意的复合结构,我们熟悉的mysqli、fsock、memcached等都是资源。

如何使用资源:

注册:对于一个自定义的数据类型,要想将它作为资源。首先需要进行注册,zend会为它分配全局唯一标示。

获取一个资源变量:对于资源,zend维护了一个id-实际数据的hash_tale。对于一个source,在zval中只记录了它的id。fetch的时候通过id在hash_table中找到具体的值返回。

资源销毁:资源的数据类型是多种多样的。Zend本身没有办法销毁它。因此需要用户在注册资源的时候提供销毁函数。当unset资源时,zend调用相应的函数完成析构。同时从全局资源表中删除它。

资源可以长期驻留,不只是在所有引用它的变量超出作用域之后,甚至是在一个请求结束了并且新的请求产生之后。这些资源称为持久资源,因为它们贯通SAPI的整个生命周期持续存在,除非特意销毁。很多情况下,持久化资源可以在一定程度上提高性能。比如我们常见的mysql_pconnect,持久化资源通过pemalloc分配内存,这样在请求结束的时候不会释放。对zend来说,对两者本身并不区分。

PHP中的局部变量和全局变量是如何实现的?对于一个请求,任意时刻PHP都可以看到两个符号表(symbol_table和active_symbol_table),其中前者用来维护全局变量。后者是一个指针,指向当前活动的变量符号表,当程序进入到某个函数中时,zend就会为它分配一个符号表x同时将active_symbol_table指向a。通过这样的方式实现全局、局部变量的区分。

获取变量值:PHP的符号表是通过hash_table实现的,对于每个变量都分配唯一标识,获取的时候根据标识从表中找到相应zval返回。

函数中使用全局变量:在函数中,我们可以通过显式申明global来使用全局变量。在active_symbol_table中创建symbol_table中同名变量的引用,如果symbol_table中没有同名变量则会先创建。

原文







































著名的白癜风医院
北京中科白殿疯怎么走



转载请注明:http://www.xxcyfilter.com/gailian/gailian/9842.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了