[转]自己写PHP扩展之创建一个类,php一个类
[转]自己写PHP扩展之创建一个类,php一个类
原文:http://www.imsiren.com/archives/572
比如我们要创建一个类..PHP代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Person {
public $name ;
public $age ;
public function __construct() {
echo "construct is running!
";
}
public function __destruct() {
echo "
destruct is running!";
}
public function getproperty( $key ) {
echo $this -> $key ;
}
public function setproperty( $key , $val ) {
$this -> $key = $val ;
}
}
|
用PHP来做,很简单..
那么用PHP扩展来写该怎么做?
OK.
1.在php_siren.h里面声明类
1 2 3 4 |
PHP_METHOD(Person,__construct);
PHP_METHOD(Person,__destruct);
PHP_METHOD(Person,setproperty);
PHP_METHOD(Person,getproperty);
|
PHP_METHOD宏.
PHP_METHOD 等于ZEND_METHOD
这个宏接受两个参数,第一个是类名,第二个是类的方法
1 2 3 4 |
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v alue_used TSRMLS_DC
//最后等于
void name( int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v alue_used TSRMLS_DC )
|
这个宏是用来声明我们的方法…
2.设置接收的参数
我们的方法如果需要接受参数.那么就要执行
1 2 3 |
ZEND_BEGIN_ARG_INFO_EX(arg_person_info,0,0,2)
ZEND_ARG_INFO(0,name)
ZEND_END_ARG_INFO()
|
详细讲这几个宏之前先看看zend_arg_info
1 2 3 4 5 6 7 8 9 10 11 |
typedef struct _zend_arg_info {
const char *name; //参数名称
zend_uint name_len; //长度
const char *class_name; //所属类名
zend_uint class_name_len; //类名长度
zend_bool array_type_hint;
zend_bool allow_null; //允许为空
zend_bool pass_by_reference; //引用传值
zend_bool return_reference; //引用返回
int required_num_args; //参数个数
} zend_arg_info;
|
ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h
1 2 3 |
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
static const zend_arg_info name[] = { \
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
|
很明显 声明一个zend_arg_info的数组name,然后初始化结构体的值
ZEND_ARG_INFO(0,name)的定义如下
1 |
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
|
这三个宏 执行代码 等于
1 2 3 |
static const zend_arg_info name[] = { { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
{ #name, sizeof (#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
};
|
3.创建zend_function_entry结构数组
1 2 3 4 5 6 7 |
const zend_function_entry person_functions[]={
PHP_ME(Person,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(Person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_ME(Person,getproperty,arg_person_info,ZEND_ACC_PUBLIC)
PHP_ME(Person,setproperty,arg_person_info,ZEND_ACC_PUBLIC)
PHP_FE_END
};
|
zend_function_entry定义如下
1 2 3 4 5 6 7 |
typedef struct _zend_function_entry {
const char *fname; //函数名称
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
const struct _zend_arg_info *arg_info; //参数
zend_uint num_args; //参数个数
zend_uint flags; //标示PUBLIC ?PRIVATE ?PROTECTED
} zend_function_entry;
|
PHP_ME宏接收四个参数
1 类名,
2 方法名,
3 zend_arg_info 的参数列表,
ZEND_ACC_PUBLIC ZEND_ACC_PRIVATE ZEND_ACC_PROTECTED是我们类里面的三个访问权限
ZEND_ACC_CTOR标示构造函数
ZEND_ACC_DTOR标示析构函数
4.修改PHP_MINIT_FUNCTION
前面我们说过 PHP_MINIT_FUNCTION是在模块启动的时候执行的函数
首先创建一个全局指针 zend_class_entry *person_ce;
在PHP_MINIT_FUNCTION加入如下代码
1 2 3 4 |
zend_class_entry person;
INIT_CLASS_ENTRY(person, "Person" ,person_functions);
person_ce=zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC);
zend_declare_property_null(person_ce,ZEND_STRL( "name" ),ZEND_ACC_PUBLIC TSRMLS_CC);
|
1行创建一个zend_class_entry对象person.
zend_class_entry这个结构体前面也讲过 PHP内核研究之类的实现
2行初始化zend_class_entry 它执行了如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
{ \
int _len = class_name_len; \
class_container.name = zend_strndup(class_name, _len); \
class_container.name_length = _len; \
class_container.builtin_functions = functions; \
class_container.constructor = NULL; \
class_container.destructor = NULL; \
class_container.clone = NULL; \
class_container.serialize = NULL; \
class_container.unserialize = NULL; \
class_container.create_object = NULL; \
class_container.interface_gets_implemented = NULL; \
class_container.get_static_method = NULL; \
class_container.__call = handle_fcall; \
class_container.__callstatic = NULL; \
class_container.__tostring = NULL; \
class_container.__get = handle_propget; \
class_container.__set = handle_propset; \
class_container.__unset = handle_propunset; \
class_container.__isset = handle_propisset; \
class_container.serialize_func = NULL; \
class_container.unserialize_func = NULL; \
class_container.serialize = NULL; \
class_container.unserialize = NULL; \
class_container.parent = NULL; \
class_container.num_interfaces = 0; \
class_container.interfaces = NULL; \
class_container.get_iterator = NULL; \
class_container.iterator_funcs.funcs = NULL; \
class_container.module = NULL; \
}
|
可以对应文章>> PHP内核研究之类的实现来分析
zend_declare_property_null(person_ce,ZEND_STRL(“name”),ZEND_ACC_PUBLIC TSRMLS_CC);
创建一个值为NULL的属性
第一个参数是类名,第二个参数是 属性名称,第三个参数是属性名的长度,因为ZEND_STRL宏定义了长度,所以这里不用再传递长度.
第四个参数是属性的访问权限.
还有其他几个函数用来创建不同类型的属性
1 2 3 4 5 6 7 |
zend_declare_property_bool
zend_declare_property_double
zend_declare_property_ex
zend_declare_property_long
zend_declare_property_null
zend_declare_property_string
zend_declare_property_stringl
|
5.创建 php_siren.h头文件中的方法体
1 2 3 4 5 6 7 8 9 10 11 12 |
PHP_METHOD(Person,__construct){
php_printf( "construct is running );
}
PHP_METHOD(Person,__destruct){
php_printf( "destruct is running );
}
PHP_METHOD(Person,setproperty){
}
PHP_METHOD(Person,getproperty){
}
|
6.最后make&& make install
编译我们的扩展,
重新启动apache.
$p=new Person();
?>
我们就能在浏览器里看到输出的内容
construct is running
destruct is running
这样 ..我们用扩展创建的一个基本类就完成了.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











C++ 함수 호출 성능 최적화에는 매개변수 전달 전략과 반환 값 유형 최적화라는 두 가지 측면이 포함됩니다. 매개변수 전달 측면에서 작은 객체와 수정 불가능한 매개변수에는 값 전달이 적합하고, 큰 객체와 수정 가능한 매개변수에는 참조나 포인터 전달이 적합하며 포인터 전달이 가장 빠릅니다. 반환값 최적화 측면에서 작은 값은 직접 반환할 수 있고, 큰 객체는 참조나 포인터를 반환해야 합니다. 적절한 전략을 선택하면 함수 호출 성능이 향상될 수 있습니다.

C++에서 모듈 전체에 걸쳐 함수 호출: 함수 선언: 대상 모듈의 헤더 파일에서 호출할 함수를 선언합니다. 함수 구현: 소스 파일에 함수를 구현합니다. 모듈 연결: 링커를 사용하여 함수 선언과 구현이 포함된 모듈을 서로 연결합니다. 함수 호출: 호출하려는 모듈에 대상 모듈의 헤더 파일을 포함시킨 후 함수를 호출합니다.

C++ 함수 호출 리플렉션 기술을 사용하면 런타임 시 함수 매개변수 및 반환 값 정보를 동적으로 얻을 수 있습니다. 매개변수 및 반환 값 유형 정보를 얻으려면 typeid(decltype(...)) 및 decltype(...) 표현식을 사용하십시오. 리플렉션을 통해 동적으로 함수를 호출하고 런타임 입력을 기반으로 특정 함수를 선택할 수 있으므로 유연하고 확장 가능한 코드가 가능해집니다.

PHP 함수를 호출하는 방법에는 직접 호출, 변수를 통한 호출, 익명 함수, 함수 포인터 및 리플렉션의 다섯 가지 방법이 있습니다. 상황에 가장 적합한 방법을 선택하면 성능을 최적화하고 코드 단순성을 향상시킬 수 있습니다.

C++의 함수 호출 메커니즘에는 함수에 인수를 전달하고 해당 코드를 실행하며 결과가 있는 경우 결과를 반환하는 작업이 포함됩니다. 매개변수를 전달하는 방법에는 두 가지가 있습니다. 값으로 전달(수정 사항은 함수 내부에서 수행됨)과 참조로 전달(수정 사항이 호출자에 반영됨)입니다. 값 전달 시 함수 내의 값 수정은 원래 값(예: printValue)에 영향을 주지 않는 반면, 참조 전달 시 수정은 원래 값(예: printReference)에 영향을 미칩니다.

단위 테스트에서 C++ 함수 호출을 확인할 때 다음 두 가지 사항을 확인해야 합니다. 매개변수 전달: 어설션을 사용하여 실제 매개변수가 예상 값과 일치하는지 확인합니다. 반환 값: 어설션을 사용하여 실제 반환 값이 예상 값과 같은지 확인합니다.

C++에서는 다음 단계를 포함하여 전처리기 매크로를 사용하여 함수를 호출할 수 있습니다. 매개변수 전달: 매크로 매개변수는 괄호로 묶이고 쉼표로 구분됩니다. 반환 값: 매크로 매개 변수를 사용하여 반환할 값을 지정하고 이를 변수에 할당합니다. 실제 사례: 매크로 최적화를 사용하여 배열의 최대값 인덱스 함수를 찾음으로써 계산 횟수가 줄어들고 효율성이 향상됩니다.

C++ 함수 호출에는 세 가지 매개변수 전달 메커니즘이 있습니다: 값에 의한 호출(매개변수 값 복사), 참조에 의한 호출(원래 변수를 수정할 수 있는 매개변수 참조 전달), 포인터 전달(매개변수 포인터 전달). 선택 메커니즘에서는 매개변수 크기, 원래 변수를 수정해야 하는지 여부 및 효율성을 고려해야 합니다.
