php杂七杂八

By | 09月18日
Advertisement

PHP的启动
PHP的启动经历了
PHP_MINIT_FUNCTION->
PHP_RINIT_FUNCTION->
PHP_RSHUTDOWN_FUNCTION->
PHP_MSHUTDOWN_FUNCTION
4个阶段。
但是 这4个阶段会由于SAPI宿主的不同在不同阶段执行。
如果把PHP比作汽车,那么SAPI就是公路。
常见的SAPI可以是
CLI/CGI
一个请求过来,会执行以上4个阶段。
多进程模型
以APACHE的PRE-FORK为代表,在此模式下,APACHE会设定一个初始进程数量,然后请求增多以后,会以2的指数次方创建进程。
多线程模型
以APACHE的worker为代表,在这种模式下,只有一个服务器进程在运行着,但会同时运行很多线程,这样可以减少一些资源开销,向Module init和Module shutdown就只需要运行一遍就行了,一些全局变量也只需要初始化一次,因为线程独具的特质,使得各个请求之间方便的共享一些数据成为可能。
PHP的类型
struct _zval_struct {
zvalue_value value; /* 变量的值 */
zend_uint refcount__gc; //引用计数
zend_uchar type; /* 变量当前的数据类型 */
zend_uchar is_ref__gc; //是否被引用
};
typedef struct _zval_struct zval;

其中变量的值zvalue_value又是个union,具体如下
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str; //可以看到php的str与c的用\0结束不同,而是用一个int表示他的长度
HashTable *ht; /* hash table value PHP数组的保存方式*/
zend_object_value obj;
} zvalue_value;

如何判断PHP值的类型(zval->type),PHP定义了一些以IS_开头的常量
IS_NULL,IS_LONG,IS_DOUBLE,IS_STRING,IS_ARRAY,IS_OBJECT,IS_RESOURCE
还定义了三个检测变量类型的宏,分别接收zval,zval*,zval**类型的变量
define Z_TYPE(zval) (zval).type
define Z_TYPE_P(zval_p) Z_TYPE(*zval_p)
define Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp)
说明:本来也可以把zval->type和IS_开头的常量比较,但是如果以后PHP改变zval的定义,就不能保证兼容性。

如何操作PHP的值(zval->value)
PHP定义了基础宏获取zval->value
//操作整数的
#define Z_LVAL(zval) (zval).value.lval
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)

//操作IS_BOOL布尔型的
#define Z_BVAL(zval) ((zend_bool)(zval).value.lval)
#define Z_BVAL_P(zval_p) Z_BVAL(*zval_p)
#define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp)

//操作浮点数的
#define Z_DVAL(zval) (zval).value.dval
#define Z_DVAL_P(zval_p) Z_DVAL(*zval_p)
#define Z_DVAL_PP(zval_pp) Z_DVAL(**zval_pp)

//操作字符串的值和长度的
#define Z_STRVAL(zval) (zval).value.str.val
#define Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p)
#define Z_STRVAL_PP(zval_pp) Z_STRVAL(**zval_pp)

#define Z_STRLEN(zval) (zval).value.str.len
#define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)
#define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp)

//操作数组的
#define Z_ARRVAL(zval) (zval).value.ht
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p)
#define Z_ARRVAL_PP(zval_pp) Z_ARRVAL(**zval_pp)

对象和资源类型的暂时不考虑了。

PHP值的创建
第一步,通过MAKE_STD_ZVAL(pzv)初始化一个指向zval的指针pzv
第二步,通过之前学过的操作PHP类型的各种宏对zval->type,zval->value进行赋值。
比如:
Z_TYPE_P(pzv) = IS_LONG;
Z_LVAL_P(pzv) = l;
也可以用新的宏把它简化
ZVAL_LONG(pzv, l);
注意:字符串在php中的表示是
struct {
char *val;
int len;
} str;
所以赋值时候要即赋值val 还要赋值len
比如:
Z_TYPE_P(pzv) = IS_STRING;
Z_STRLEN_P(pzv) = len;
if (dup)
{Z_STRVAL_P(pzv) =estrndup(str, len + 1);} //estrndup重新申请内存,并复制字符串
else
{Z_STRVAL_P(pzv) = str;}
也可以用新的宏把它简化
ZVAL_STRINGL(pzv,str,len,dup);

变量的存储
struct _zend_executor_globals {
...
HashTable symbol_table;
HashTable *active_symbol_table;
...
};
创建一个zval结构,并设置其类型。
设置值为'bar'。
将其加入当前作用域的符号表,只有这样用户才能在PHP里使用这个变量。

具体的代码为:
{
zval *fooval;

MAKE_STD_ZVAL(fooval);
ZVAL_STRING(fooval, "bar", 1);
ZEND_SET_SYMBOL( EG(active_symbol_table) , "foo" , fooval);
}

上面解释了zval->type,zval->vale相关的,下面解释zval->refcount__gc,zval->is_ref_gc
相关文章检索copy-on-write

ZEND_FUNCTION返回值
ZEND_FUNCTION的宏展开是
void name(INTERNAL_FUNCTION_PARAMETERS) 展开INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAMETERS
int ht,
zval *return_value, //返回值的指针,给他赋值就行了。
zval **return_value_ptr,
zval *this_ptr,
int return_value_used TSRMLS_DC
返回值例子:
ZEND_FUNCTION(sample_long)
{
ZVAL_LONG(return_value, 42); //前面讲过的如何给zval* 赋值。
return;
}

Similar Posts:

  • Gradle 1.12 翻译——第十四章. 教程 - 杂七杂八

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com/1.12/userguide/userguide.html 本文原创,转载请注明出处:http://blog.csdn.net/maosidiaoxian/article/details/41006627 关于我对Gradle的翻译,以Github上的项目及http://gradledoc.qin

  • 稳扎稳打Silverlight(48) - 4.0其它之打印, 动态绑定, 增强的导航系统, 杂七杂八

    [索引页] [源码下载] 稳扎稳打Silverlight(48) - 4.0其它之打印, 动态绑定, 增强的导航系统, 杂七杂八 作者:webabcd 介绍 Silverlight 4.0 其它: 打印 - Silverlight 4.0 中新增的对打印的支持 动态绑定 - 新增的 C# 4.0 的特性及其应用 增强的导航系统 杂七杂八 在线DEMO http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html 示例 1.演示在 S

  • 【Asp.Net MVC--资料汇总】杂七杂八

    Html.RenderPartial与Html.RenderAction的区别 http://blog.sina.com.cn/s/blog_8278b1800100zkn0.html ASP.NET MVC HtmlHelper用法大全 http://blog.sina.com.cn/s/blog_8278b1800100zpvt.html HTML扩展类的所有方法都有2个参数: 以textbox为例子 public static string TextBox( this HtmlHelper

  • Jetty直接调试,不用部署,不用弄一些杂七杂八的设置

    以前调试web程序的,搭建Tomcat实在是费劲,就想找一个比较简单的方式,我就想调试一下我写的某一个servlet形式,看到<how Tomcat works>这本书,才明白确实可以,不过使用的web容器是jetty,还是比较的方便,特记载这里. 1. 新建一个工程 2. 把代码拷贝进去,添加依赖的jar 3. 启动调试,ok. 工程的样式: JettyStarter的代码: package jetty; import org.mortbay.jetty.Connector; import

  • javascript 杂七杂八,也许用得上

    1.获得浏览器body的宽度和高度: var h = document.body.scrollHeight; var w = document.body.scrollWidth; 2.document.location中的几个方法: (1).设置或获取对象指定的文件名或路径. alert(window.location.pathname); (2).设置或获取整个 URL 为字符串. alert(window.location.href); (3).设置或获取与 URL 关联的端口号码. ale

  • 游戏辅助,汇编学习等杂七杂八

    最近突然对游戏外挂开发产生兴趣,准备花点时间研究研究. 不过,好记性不如烂笔头,所以在这里对相关资料和常去网站做个记录. 以下仅为网上收集的一些资料. 相关文章: 外挂基础知识入门教学 http://hack.gameres.com/thread_142398.html 微软研究院Detour开发包之API拦截技术 http://www.cnblogs.com/flying_bat/archive/2008/04/18/1159996.html API Hooking with MS Detou

  • 杂七杂八股

    对大盘贡献前五个股为:西山煤电(44.98点).五粮液(24.34点).中兴通讯(24.1点).泸州老窖(19.52点).鞍钢股份(19.53点):目前无拖累大盘逾1个点个股.(11: 16) 盘中个股交投活跃,除去ST类股,两市涨停个股增至16家,其中建筑建材板块占3家,无跌停.(11: 07) 近期受天气以及交通影响,以及对今年冬天气候的忧虑,可能对农产品价格.煤炭价格以及燃油价格产生上涨压力,建议逢低关注可能再次催生通胀受益板块的行情.(10: 57) 暴雪或致短期煤价上扬 煤炭股涨逾6%

  • emWin -- 杂七杂八

    1. 利用GUI_Builder()创建了窗口,并且在主函数中调用了,为什么屏幕上没有显示? WM_HWIN hWin; hWin = CreateWindow(); 答: 可能是没有调用GUI_Exec()函数来执行回调函数,通常为重新绘制窗口.在默认情况下,用户不需要主动调用此函数,,它自动由GUI_Delay()调用. 2. 如何在同一个地方多次显示长短不一致的字符串? 答: 可调用GUI_DispStringAtCEOL()来显示字符.该函数和GUI_DispStringAt()完全相同

  • 整理一下杂七杂八的postfix+extmail的mail服务器架设维护笔记(2)

    --------------------------------------------------------------------- 安装extman: tar -zxvf extman-0.2.2.tar.gz mv extman-0.2.2 /var/www/extsuite/extman cd /var/www/extsuite/extman vi webman.cf SYS_MAILDIR_BASE = /home/domains 此处即为您在前文所设置的用户邮件的存放目录,可改作

  • js自定义消息机制研究学习(四)之杂七杂八

    一.可测试的代码 早些时候,我向锐同学描述我的js程序结构,他问了我一个问题:你的js代码可测么? 我蒙了~虽然一直关注敏捷,一直也向往测试驱动开发,但还从没想过js代码的可测试(当然,也有测试,但基本上整测加局部测试),没有想过js的测试驱动. 当时,我迟疑了一会,才说应该是可测的. 写完上一篇文章(原谅我,觉得太简单,直接写的,忘了测试驱动),回头看了看,还好,基于消息的代码确实可以做到可测. 比如: Animal function Animal(config) { config=confi

Tags: