自己写PHP扩展之实现类的继承

如果我们想继承某一个类,我们怎么办?
比如 Siren类继承Secure类.

class Secure{
    public function test(){
           echo "this is Secure::test";
    }
}
class Siren extends Secure{

}

这样一个类,该怎么做?
其实没有什么大不同,跟创建一个普通类是一样的..只是有一些稍作改动..
1.在头文件中声明方法 Continue reading “自己写PHP扩展之实现类的继承” »

自己写PHP扩展之操作类的属性和方法

类创建好了..
那么类肯定不止这些东西,它由继承,属性,返回值等.

1.方法的参数.
有方法,该方法就可能要有参数.参数是如何传递过来的呢?
如果看过之前的文章.那么你肯定就知道了..是的 与普通函数的参数相同.
声明char类型的指针用来保存参数的值.
声明int类型的变量来保存的参数长度
然后用到 zend_parse_parameters函数
zend_parse_parameters(``,`< char *type_spec>`,`< ...>`)
该参数有几个重要的参数
第一个是参数的个数
第二个比较重要,它指定接收参数的类型
下面这份清单完整地列举出了我们可以指定接收的参数类型:
Continue reading “自己写PHP扩展之操作类的属性和方法” »

自己写PHP扩展之创建一个类

上一章用扩展创建了一个变量..

这次来个大的..我们创建一个类.

然后在php里面去调用这个类.

生成扩展及修改 不知道的请点击这里 http://imsiren.com/archives/568

这里就不谈了.

比如我们要创建一个类..PHP代码如下
Continue reading “自己写PHP扩展之创建一个类” »

自己写PHP扩展之创建一个普通变量

PHP写扩展..

如果您还么有读原:用C/C++扩展PHP

建议您先看一下这篇文章..

今天来个简单的..我们用扩展方式创建一个变量 $siren.

然后在PHP文件里面输出这个变量.

1. 执行源码目录中的 ext_skel –extname=siren

执行成功过后就会在php-src/ext/目录下生成一个siren的文件件,里面包含了扩展的基本结构.

2.修改config.m4

因为我的系统是Linux所以要修改此文件,我们采用so模块的形式加载,所以编辑config.m4文件

dnl PHP_ARG_WITH(siren, for siren support,
dnl Make sure that the comment is aligned:
dnl [  --with-siren             Include siren support])

去掉1,3行的注释dnl,这样我们就可以用PHP以模块的形式加载..具体可以参见我上一篇文章http://imsiren.com/archives/547

3.编辑php_siren.h

此文件是一个头文件,包含了我们函数的定义.

我要新建一个variable函数,首先需要在此文件里面加一行代码:PHP_FUNCTION(variable); 可以理解为声明一个函数

4.修改siren.c源文件

在siren_functions数组里面添加一行 PHP_FE(variable,NULL);

然后在 最下面添加如下代码

PHP_FUNCTION(variable){
        zval* val;
        MAKE_STD_ZVAL(val);
        ZVAL_STRING(val,"this is siren",1);
        ZEND_SET_SYMBOL(EG(active_symbol_table),"siren",val);
}

zval接口用来保存变量的信息
MAKE_STD_ZVAL宏用来分配内存空间
ZVAL_STRING宏给zval结构设置信息.

const char *__s=(s);                    \
Z_STRLEN_P(z) = strlen(__s);    \
Z_STRVAL_P(z) = (duplicate?estrndup(__s, Z_STRLEN_P(z)):(char*)__s);\
Z_TYPE_P(z) = IS_STRING;

如果不懂 请参见 原创:PHP内核研究:HASH表和变量
最后在php-src/ext/siren目录下执行
1. php安装目录/bin/phpize
2. ./configure –with-php-config=/php安装目录/bin/php-config
3. make && make install
这样 执行后就会在 php的扩展目录下生成一个 siren.so文件
4. 修改php.ini extension=siren.so 开启扩展
5. 编写PHP文件 执行 variable(); 然后 echo $siren;
看看是不是输出了 “this is siren”呢?
怎么样 是不是很简单..

正则表达式的研究

正则表达式是一个无比强大的工具.任何地方我们都可能用到它…
原来刻苦的啃过 正则表达式,但时间长了还是会忘…
今天又来温习一下..看到一篇不错的文章..所以就转过来收藏下.
如果你正为正则表达式迷糊.那这篇文章肯定会帮助你的. ^.^
原文链接:http://www.cnblogs.com/dragon/archive/2006/05/08/394078.html

前言:
半年前我对正则表达式产生了兴趣,在网上查找过不少资料,看过不少的教程,最后在使用一个正则表达式工具RegexBuddy时发现他的教程写的非常好,可以说是我目前见过最好的正则表达式教程。于是一直想把他翻译过来。这个愿望直到这个五一长假才得以实现,结果就有了这篇文章。关于本文的名字,使用“深入浅出”似乎已经太俗。但是通读原文以后,觉得只有用“深入浅出”才能准确的表达出该教程给我的感受,所以也就不能免俗了。
本文是Jan Goyvaerts为RegexBuddy写的教程的译文,版权归原作者所有,欢迎转载。但是为了尊重原作者和译者的劳动,请注明出处!谢谢!
Continue reading “正则表达式的研究” »

原:用C/C++扩展PHP

一个简单的扩展模块
PHP非常容易扩展,因为它提供了我们想用的所有API.
如果要新建一个扩展,需要在PHP源码中执行ext_skel
位置 PHP源码目录/ext/ext_skel
它有几个参数
–extname=module module is the name of your extension
–proto=file file contains prototypes of functions to create
–stubs=file generate only function stubs in file
–xml generate xml documentation to be added to phpdoc-cvs
–skel=dir path to the skeleton directory
–full-xml generate xml documentation for a self-contained extension
(not yet implemented)
–no-help don’t try to be nice and create comments in the code
and helper functions to test if the module compiled
如果我们要建一个 扩展名称为siren的模块,那么我们只要执行
ext_skel –extname=siren 它就会在 ext/目录下生成以 模块名称为名的文件夹.而且还会创建一些文件:
config.m4 config.w32 CREDITS EXPERIMENTAL php_siren.h siren.c siren.php tests
config.m4 和config.w32是我们的配置文件,我是在linux下编译的 所以要修改config.m4文件
两种加载方式 with 和 enable

dnl PHP_ARG_WITH(siren, for siren support,
dnl Make sure that the comment is aligned:
dnl [  --with-siren             Include siren support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(siren, whether to enable siren support,
dnl Make sure that the comment is aligned:
dnl [  --enable-siren           Enable siren support])

enable方式 需要重新编译PHP ,这样是非常浪费时间的,所以我把它编译为so模块..
所以就用 with啦
dnl PHP_ARG_WITH(siren, for siren support,
dnl Make sure that the comment is aligned:
dnl [ --with-siren Include siren support])

PHP_ARG_WITH(siren, for siren support,
Make sure that the comment is aligned:
[ --with-siren Include siren support])
这样在编译PHP的时候 –with-siren就可以加载此模块,也可以在php.ini中extension 模块.
在ext/siren目录下有一个siren.c文件
它提供了一个默认函数

PHP_FUNCTION(confirm_siren_compiled)
{
        char *arg = NULL;
        int arg_len, len;
        char *strg;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                return;
        }   

        len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "siren", arg);
        RETURN_STRINGL(strg, len, 0);
}

如果看过 我之前的文章,你肯定明白 如果不知道 那就看看这篇文章
http://imsiren.com/archives/196
下面看看如何编译到PHP Continue reading “原:用C/C++扩展PHP” »

原:PHP的执行流程,PHP扩展加载过程

为了以后能够明白的开发PHP扩展..就一定要了解PHP的执行顺序..这篇文章就是为C开发PHP扩展做铺垫.
web环境 我们假设为 apache.
在编译PHP的时候,为了能够让Apache支持PHP,我们会生成一个mod_php5.so的模块.apache加载这个模块..
在url访问.php文件的时候就会转给mod_php5.so模块来处理.这个玩意是什么..就是我们常说的SAPI
英文名字是:Server abstraction API.
SAPI说的其实是一个统称,其下有 ISAPI,CLI SAPI, CGI等.
有了它,就可以很容易的跟其他东西交互.比如APACHE,IIS,CGI等.
好了回到正题.
apache启动后会将mod_pho5.so模块的hook handler注册进来.apache今天不是主角,所以不细说.
当APACHE检测到 访问的url是一个php文件时,这时候就会把控制权交给sapi.
进入到sapi后,首先会执行sapi/apache/mod_php5.c 文件的php_init_handler函数

static void php_init_handler(server_rec *s, pool *p)
{
        register_cleanup(p, NULL, (void (*)(void *))apache_php_module_shutdown_wrapper, (void (*)(void *))php_module_shutdown_for_exec);
        if (!apache_php_initialized) {
                apache_php_initialized = 1;
#ifdef ZTS
                tsrm_startup(1, 1, 0, NULL);
#endif
                sapi_startup(&apache_sapi_module);
                php_apache_startup(&apache_sapi_module);
        }
#if MODULE_MAGIC_NUMBER >= 19980527
        {
                TSRMLS_FETCH();
                if (PG(expose_php)) {
                        ap_add_version_component("PHP/" PHP_VERSION);
                }
        }
#endif
}

该函数主要调用 两个函数 Continue reading “原:PHP的执行流程,PHP扩展加载过程” »

jquery源码分析之扩展函数 extend, $.extend

好久没写jquery源码的内容了..
jquery的发展有很大因素是因为它非常易于扩展,究其原因就得益于 extend函数
该函数是一个扩展函数…说是一个扩展函数,其实就是一个浅拷贝和深拷贝的函数而已.
该函数 确实很强大,而且写的很优雅..
先来看看用法,有三种用法.
1、$.extend(dest,src1,src2,src3…);
2、$.extend(src)
3、$.extend(boolean,dest,src1,src2,src3…)
意思就是将 src1,src2,src3合并到dest对象中..
特别说一下第三种,第一个参数的意义就在于 是否对src1,src2等进行深copy.
那么什么是深copy呢?
var ret=$.extend(true,{},
{name:”siren”,about:{age:24,country:”beijing”}},
{from:”hebei”,birthday:{year:1988,month:02}}
); Continue reading “jquery源码分析之扩展函数 extend, $.extend” »

原:PHP内核函数研究之 intval

趁热打铁 顺便说说 intval函数.该函数好像我们用的最多的就是在POST或者GET某个参数的时候,将其强制转换为int型,
为了保证我们传入到SQL的时候是一个整形.,当然这只是其中一种用法..
该函数接受两个参数,第一个是要转换的字符串,第二个要转换成的进制数,默认为十进制.
我们先用PHP 来看看它的用法.

class a{
    public $b;
    function c(){

    }
}
$a=new a();
echo intval($a); //输出1.
$a=array('a'=>1,'b'=>2);
echo intval($a);//输出1
$a=false;
echo intval($a);//输出0
$a=true;
echo intval($a);//输出1
$a=1.9;
echo intval($a);//输出1
$a=null;
echo intval($a);//输出0

OK,看看它的定义.
同样定义在ext/standard/type.c文件中. Continue reading “原:PHP内核函数研究之 intval” »

原:PHP数组函数研究:is_null,is_object,is_array,is_string,is_resource等

前面有一篇文章 讲的是 PHP内核源码分析:isset与 empty

但是好像忘记了一系列is函数

is_null,is_object,is_array,is_string,is_resource,is_bool,is_long,is_float
今天就补充一下..他们的判断方法是一样的,只讲一个is_null其他的就能明白了.
is_null是一个函数.定义在 ext/standard/type.c文件中.
所有 类型的操作都在这个文件里,settype,gettype,intval等函数也在这里.

PHP_FUNCTION(is_null)
{
        php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
}

它调用了 php_is_type函数,该函数 后面传递的是要检测的类型.

static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
{
        zval **arg;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
                RETURN_FALSE;
        }

        if (Z_TYPE_PP(arg) == type) {
                if (type == IS_OBJECT) {
                        zend_class_entry *ce;
                        if(Z_OBJ_HT_PP(arg)->get_class_entry == NULL) {
                        /* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
                                RETURN_TRUE;
                        }
                        ce = Z_OBJCE_PP(arg);
                        if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
                                RETURN_FALSE;
                        }
                }
                if (type == IS_RESOURCE) {
                        char *type_name;
                        type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
                        if (!type_name) {
                                RETURN_FALSE;
                        }
                }
                RETURN_TRUE;
        } else {
                RETURN_FALSE;
        }
}

第九行 会调用 Z_TYPE_PP来获取传递进来的值的类型..前面文章有讲到.
如果不等于该函数的第二个参数type直接返回FALSE;
如果等于我们要检测的类型,但是 对象或者是资源 就还要做相应的判断.
是对象的话,十六行会获取 _zend_class_entry 结构的name值,该值必须等于INCOMPLETE_CLASS
INCOMPLETE_CLASS是一个宏,
#define INCOMPLETE_CLASS “__PHP_Incomplete_Class”
也就是说必须是一个类的实例化才行.