标签归档:PHP扩展

PHP的生命周期

PHP的生命周期

php本身的生命周期是在命令行执行php test.php程序的生命周期(也就是cli)

整个过程如下:

执行php test.php

调用每个扩展的模块初始化程序

    请求test.php程序

    调用每个扩展的请求初始化程序

        执行test.php程序

    调用每个扩展的请求关闭程序

    释放内存等清除工作

调用每个扩展的模块关闭程序

终止php

如果PHP运行在WEB服务器中,那么它的生命周期就会有些不同了,这里又要根据服务器的不同分为以下三种:

1、单进程

模块初始化

    请求初始化

        执行脚本

    关闭请求

    请求初始化

        执行脚本

    关闭请求
    请求初始化
        执行脚本
    关闭请求
    请求初始化
        执行脚本
    关闭请求
……

……
……
模块关闭

单进程的WEB服务器只对模块初始化一次,所有的页面请求都在其中

2、多进程

模块初始化                         模块初始化                    模块初始化                模块初始化

    请求初始化                         请求初始化                    请求初始化                请求初始化

        执行脚本                            执行脚本                      执行脚本                   执行脚本

    关闭请求                            关闭请求                      关闭请求                   关闭请求

    请求初始化                         请求初始化                    请求初始化                请求初始化

        执行脚本                            执行脚本                      执行脚本                   执行脚本

    关闭请求                            关闭请求                      关闭请求                   关闭请求

    请求初始化                         请求初始化                    请求初始化                请求初始化

        执行脚本                            执行脚本                      执行脚本                   执行脚本

    关闭请求                            关闭请求                      关闭请求                   关闭请求

……                                  ……                            ……                         ……

关闭模块                            关闭模块                       关闭模块                    关闭模块

多进程只是把单进程复制了多份,各个子进程间无法共享数据等。

3、多线程

                        模块初始化

请求初始化                         请求初始化                    请求初始化                请求初始化

    执行脚本                            执行脚本                      执行脚本                   执行脚本

关闭请求                            关闭请求                      关闭请求                   关闭请求

                    关闭模块

全局变化可以在初始化的时候建立,并且只建立一次。

PHP扩展之smart_str分析

php_smart_str_public.h
在php_smart_str_public.h文件中我们找到了如下定义:

1
2
3
4
5
typedef struct {
              char *c;
              size_t len;
              size_t a;
} smart_str;

其中,size_t的定义 为:typedef unsigned int size_t;
char *c 表示整个字符串
size_t len表示整个字符串的实际长度
size_t a 表示这个字符的总长度(smart_str的字符串总长度总是以128字节的倍数增加)

从php_smart_str.h文件所在的源码中我们可以看出它的空间分配具体有如下特点:
1、在初始化时,如果所给字符串的长度小于SMART_STR_START_SIZE(定义为78字节),则初始smart_str的总长度为78字节(即a值),并给它分配空间;如果所给字符串的长度大于SMART_STR_START_SIZE,则将此长度上加上SMART_STR_PREALLOC(定义为128字节)作为smart_str的总长度,并为之分配空间。
2、在已有字符串后添加时,如果添加后的总长度小于当前smart_str->a的值,则无需分配空间,否则,在smart_str新的长度的基础上再加上128字节的空间。
这样有些类似于操作系统中内存以页为单位分配,它的好处是对齐内存地址,提高访问速度。
在php_smart_str.h文件中,我们可以看到一些针对smart_str类型的宏定义的操作方法,方法列表如下:

smart_str_0 如果字符串存在,给字符串的最后添加’\0’;
smart_str_alloc 在初始化和添加字符串时进行空间的分配;
smart_str_appends_ex(dest, src, what) 在一个smart_str变量后面添加一个字符串,它分为两种空间分配方法,当what为真是,它使用__zend_realloc函数,此函数为永久分配内存,在无法分配内存时会报Out of memory的,当what为假时,它使用标准空间分配,即ZendMM所我有的分配函数erealloc(ptr, size)。
smart_str_appends(dest, src) 在一个smart_str变量后面添加一个原生的字符串
smart_str_appendc(dest, c) 在一个smart_str变量后面添加一个字符
smart_str_free(s) 消除smart_str变量,释放所占内存
smart_str_appendl(dest, src, len) 在一个smart_str变量后面添加一个长度为len的字符串
smart_str_append(dest, src) 在一个smart_str变量后面添加一个smart_str字符串
smart_str_append_long(dest, val) 将一个long的数字转化成字符串后添加到smart_str的后面smart_str_append_unsigned(dest, val) 将一个unsigned long的数字转化成字符串后添加到smart_str的后面
smart_str_appendc_ex(dest, ch, what) 与smart_str_appends_ex类似,所不同的是它添加的是一个字符。
smart_str_setl(dest, src, nlen) 将一个长为len的原生的字符串强制转化为一个smart_str
smart_str_sets(dest, src) 将一个原生的字符串强制转化为一个smart_str

【经典代码】
数字转字符串:

1
2
3
4
5
6
7
8
9
char __b[32];             
int __num = 28790;
char *__p;
__p = __b + sizeof(__b) - 1;
*__p= '\0';                                                                                                                                                                                     
do{                                                                                                                                                                                        
 *--__p = (char) (__num % 10)+ '0';                                                                                                 
__num /=10;                                                                                                                                                                       
} while (__num > 0);

JSON格式总结

【JSON是什么】
JSON,JavaScript Object Notation,一种更轻、更友好的用于接口(AJAX、REST等)数据交换的格式。JSON是结构化数据串行化的文本格式,作为XML的一种替代品,用于表示客户端与服务器间数据交换有效负载的格式。它是从ECMAScript语言标准衍生而来的。JSON的设计目标是使它成为小的、轻便的、文本的,而且是JavaScript的一个子集。
JSON能够描述四种简单的类型(字符串、数字、布尔值和null)和两种结构化类型(对象和数组)。

字符串(string)是零个或多个Unicode字符的序列。除了字符 “、\、/和一些控制符(\b,\f,\n,\r,\t)需要编码外,其他 Unicode 字符可以直接输出

对象(Object)是无次序的零个或多个名/值(name/value)对的集合,使用{}包含包含所有元素。这里的name是string类型,value则可以是string、number、boolean、null、Object或Array类型。

数组(Array)是零个或多个value的有序序列。JSON 还可以表示一个数组对象,使用 [] 包含所有元素,每个元素用逗号分隔,元素可以是任意的 Value。

Object 对象在 JSON 中是用 {} 包含一系列无序的 Key-Value 键值对表示的,key是string类型,value则可以是string、number、boolean、null、Object或Array类型。

“Object”和”Array”这两个术语来自JavaScript规范。

【JSON的优点】

  1. 数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小
  2. 易于解析, 客户端JavaScript可以简单的通过eval()进行JSON数据的读取
  3. 支持多种语言, 包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等语言服务器端语言, 便于服务器端的解析

【JSON的缺点】

  1. 没有XML格式这么推广的深入人心和使用广泛, 没有XML那么通用性
  2. JSON格式目前在Web Service中推广还属于初级阶段

【在PHP中使用JSON】
PHP中的json直接相关的函数只有json_encode和json_decode。其中json_encode只能接受 UTF-8 编码的字符串类型数据,所以此处我们可能用到iconv等编码转换函数。

在PHP5.2.0之后,可以使用json_encode直接操作服务器端的对象、数组等,能够直接生JSON格式, 便于客户端的访问提取。
另外,由于PHP中的数组是以HASH链表存在,可以使用非数字的关键字作为下标,所以,如果我们需要生成的数据是数组而不是对象时,需要数据的下标满足如下要求:

  • 必须是数字索引,
  • 必须从0开始,
  • 必须从小到依次增加,
  • 中间不可以弹跳下,
  • 位置不可变动.

这是由于在JS中数组是0开始的顺序序列,其余都只能是哈希表对象。如果要使用数组,可以使用array_values()函数。

【小结】
JSON 已经是 JavaScript. 标准的一部分。目前,主流的浏览器对 JSON 支持都非常完善。应用 JSON,我们可以从 XML 的解析中摆脱出来,对那些应用 Ajax 的 Web 2.0 网站来说,JSON 确实是目前最灵活的轻量级方案。

【参考资料】

http://ssgemail.javaeye.com/blog/36776

http://blog.csdn.net/kinglino520/archive/2009/03/30/4036449.aspx

http://hi.baidu.com/zhaofei299/blog/item/79ba4bf3473012c30b46e0d3.html