### php_hello.h
```c
// php_hello.h
extern zend_class_entry *person_ce_ptr;
PHP_METHOD(hello,__construct);
PHP_METHOD(hello,saying);
PHP_METHOD(hello,__destruct);
```
### hello.c
```c
// hello.c
zend_class_entry person_ce;
zend_class_entry *person_ce_ptr;
ZEND_BEGIN_ARG_INFO_EX(arginfo_person_saying, 0, 0, 1)
ZEND_ARG_INFO(0, msg) // zend_internal_arg_info宏定義
ZEND_END_ARG_INFO()
const zend_function_entry person_functions[] =
{
PHP_ME(hello, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) // ZEND_ACC_PUBLIC表示訪問級別為public,ZEND_ACC_CTOR表示是構造函數
PHP_ME(hello, saying, arginfo_person_saying, ZEND_ACC_PUBLIC)
PHP_ME(hello, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) // ZEND_ACC_DTOR表示析構函數
PHP_FE_END
};
PHP_METHOD(hello, saying)
{
char *content;
size_t content_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &content, &content_len) == FAILURE)
{
return;
}
// saying方法參數值賦值給name屬性,用zend_update_property_string快捷函數代替
// zval tmp;
// ZVAL_STRING(&tmp, content);
// Z_SET_REFCOUNT(tmp, 0);
// zend_update_property(scope, object, name, name_length, &tmp);
// saying方法參數值賦值給name屬性
zend_update_property_string(person_ce_ptr, getThis(), ZEND_STRL("name"), content);
zval *self = getThis(); // getThis返回一個zval指針
zval *name;
zval rv;
// 讀取name屬性并打印name的值
name = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("name"), 0 TSRMLS_CC, &rv); // Z_OBJECT_P展開后是(zval).value.obj->ce
php_printf("%s", Z_STRVAL(name)); // zend_read_property返回一個zval結構, Z_STRVAL(name)展開后name->value.str.val
}
PHP_MINIT_FUNCTION(hello)
{
INIT_CLASS_ENTRY(person_ce, "person", person_functions); // 類名和類方法
person_ce_ptr = zend_register_internal_class(&person_ce TSRMLS_CC); // 注冊
zend_declare_property_null(person_ce_ptr, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC); // 定義name屬性,默認值為null
return SUCCESS;
}
```
### 使用
```php
$person = new Person();
$person->saying("hello wolrd");
echo $person->name . "\n";
```
上面是一個類實現方法,代碼都有詳細的注釋,以下是一些知識點補充:
```c
// 讀取普通屬性
ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC);
// 讀取靜態屬性
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, int name_length, zend_bool silent TSRMLS_DC);
// 更新普通屬性
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC);
// 更新靜態屬性
ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC);
```
快捷函數
```c
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC);
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value, int value_length TSRMLS_DC);
ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC);
ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC);
ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, const char *value, int value_length TSRMLS_DC);
```
### PHP_METHOD
PHP_METHOD(classname, name)
```c
// php.h
#define PHP_METHOD ZEND_METHOD
// zend_API.h
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
ZEND_MN(name) zim_##name
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
```
例如PHP_METHOD(hello, saying)展開后如下:
```c
zim_hello_saying(zend_execute_data *execute_data, zval *return_value)
```
- php
- 編譯安裝
- 基本概念
- 垃圾回收機制
- 生命周期
- zval底層實現
- c擴展開發
- gdb調試工具
- 自定義擴展簡單demo
- 鉤子函數
- 讀取php.ini配置
- 數組
- 函數
- 類
- yaf擴展底層源碼
- swoole擴展底層源碼
- memoryGlobal內存池
- swoole協程使用記錄
- 單點登錄sso原理
- compser使用
- session實現機制
- c & linux
- gcc
- 指針
- 結構體,聯合和位字段
- 宏定義井號說明
- printf家族函數和可變參數
- 共享函數
- 靜態庫和動態庫
- makefile自動化構建
- 信號一
- 信號二
- inotify監控文件事件
- socket編程
- 簡介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路復用
- 內存管理
- 進程組,會話和控制終端
- daemon守護進程
- 多進程
- 多線程
- 常用進制轉換
- go
- 入門知識
- 字節和整數裝換
- python
- redis
- 應用場景
- 消息隊列
- 熱點數據
- 掃碼登錄
- 訂閱發布
- 次數限制
- 搶購超賣
- 持久化機制
- mysql
- 工作流程
- MyISAM和InnoDB區別
- 用戶和權限管理
- 執行計劃
- sql優化
- 事務和鎖
- 慢查詢日志
- case...when...then...end用法
- sql
- 參考
- linux
- 內核參數優化
- 防火墻設置
- docker
- docker入門知識
- 算法
- 多維數組合
- DFA算法
- 紅包金額分配