2023-09-25 分類: 網站建設
typedef struct _php_sample_descriptor_data {
char *filename;
FILE *fp;
} php_sample_descriptor_data; 行使這個結構可以存儲文件名和文件句柄資源,從而能夠在不同的請求之間進行共享。
static void php_sample_descriptor_dtor( //這個是進行資源回收的回調函數,定義在資源的初始化處。
zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_sample_descriptor_data *fdata =
(php_sample_descriptor_data*)rsrc->ptr;
fclose(fdata->fp);
efree(fdata->filename);
efree(fdata);
} 這個靜態函數用來進行資源的回收,需要在初始化資源的時候進行指定回調。
PHP_FUNCTION(sample_fopen) //修改后的fopen
{
php_sample_descriptor_data *fdata;
FILE *fp;
char *filename, *mode;
int filename_len, mode_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
&filename, &filename_len,
&mode, &mode_len) == FAILURE) {// 獲取文件名和文件長度
RETURN_NULL();
}
if (!filename_len !mode_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Invalid filename or mode length");
RETURN_FALSE;
}
fp = fopen(filename, mode);
if (!fp) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Unable to open %s using mode %s",
filename, mode);
RETURN_FALSE;
}
fdata = emalloc(sizeof(php_sample_descriptor_data)); //給包含了文件資源和文件名的結構分配空間
fdata->fp = fp;
fdata->filename = estrndup(filename, filename_len);
ZEND_REGISTER_RESOURCE(return_value, fdata,
le_sample_descriptor); // 注冊資源
}PHP_FUNCTION(sample_fwrite)
{
php_sample_descriptor_data *fdata;
zval *file_resource;
char *data;
int data_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",
&file_resource, &data, &data_len) == FAILURE ) {
RETURN_NULL();
}
ZEND_FETCH_RESOURCE(fdata, php_sample_descriptor_data*,
&file_resource, -1,
PHP_SAMPLE_DESCRIPTOR_RES_NAME, le_sample_descriptor);
RETURN_LONG(fwrite(data, 1, data_len, fdata->fp));
} PHP_FUNCTION(sample_fname)
{
php_sample_descriptor_data *fdata;
zval *file_resource;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r",
&file_resource) == FAILURE ) {
RETURN_NULL();
}
ZEND_FETCH_RESOURCE(fdata, php_sample_descriptor_data*,
&file_resource, -1,
PHP_SAMPLE_DESCRIPTOR_RES_NAME, le_sample_descriptor);
RETURN_STRING(fdata->filename, 1);
} static int le_sample_descriptor_persist;
static void php_sample_descriptor_dtor_persistent(
zend_rsrc_list_entry *rsrc TSRMLS_DC)
{//這是一個持久化的資源析構函數
php_sample_descriptor_data *fdata =
(php_sample_descriptor_data*)rsrc->ptr;
fclose(fdata->fp);
pefree(fdata->filename, 1);
pefree(fdata, 1);
}
PHP_MINIT_FUNCTION(sample)
{
le_sample_descriptor = zend_register_list_destructors_ex(
php_sample_descriptor_dtor, NULL,
PHP_SAMPLE_DESCRIPTOR_RES_NAME, module_number);
le_sample_descriptor_persist =
zend_register_list_destructors_ex(
NULL, php_sample_descriptor_dtor_persistent,
PHP_SAMPLE_DESCRIPTOR_RES_NAME, module_number);//注冊一個持久化的資源
return SUCCESS;
}
PHP_FUNCTION(sample_fopen)
{
php_sample_descriptor_data *fdata;
FILE *fp;
char *filename, *mode;
int filename_len, mode_len;
zend_bool persist = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"ssb",
&filename, &filename_len, &mode, &mode_len,
&persist) == FAILURE) {
RETURN_NULL();
}
if (!filename_len !mode_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Invalid filename or mode length");
RETURN_FALSE;
}
fp = fopen(filename, mode);
if (!fp) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Unable to open %s using mode %s",
filename, mode);
RETURN_FALSE;
}
if (!persist) {//非持久化的資源
fdata = emalloc(sizeof(php_sample_descriptor_data));
fdata->filename = estrndup(filename, filename_len);//這個做了申請內存和賦值兩步操作
fdata->fp = fp;
ZEND_REGISTER_RESOURCE(return_value, fdata,
le_sample_descriptor);
} else {//持久化的資源
list_entry le;
char *hash_key;
int hash_key_len;
fdata =pemalloc(sizeof(php_sample_descriptor_data),1);
fdata->filename = pemalloc(filename_len + 1, 1);
memcpy(fdata->filename, filename, filename_len + 1);
fdata->fp = fp;
ZEND_REGISTER_RESOURCE(return_value, fdata,
le_sample_descriptor_persist);
/* Store a copy in the persistent_list 在persistent_list存儲一份副本 */
le.type = le_sample_descriptor_persist;
le.ptr = fdata;
hash_key_len = spprintf(&hash_key, 0,
"sample_descriptor:%s:%s", filename, mode);
zend_hash_update(&EG(persistent_list),
hash_key, hash_key_len + 1,
(void*)&le, sizeof(list_entry), NULL);
efree(hash_key);
}
} PHP_FUNCTION(sample_fopen)
{
php_sample_descriptor_data *fdata;
FILE *fp;
char *filename, *mode, *hash_key;
int filename_len, mode_len, hash_key_len;
zend_bool persist = 0; //判斷是否持久
list_entry *existing_file;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"ssb",
&filename, &filename_len, &mode, &mode_len,
&persist) == FAILURE) {
RETURN_NULL();
}
if (!filename_len !mode_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Invalid filename or mode length");
RETURN_FALSE;
}
/* 通過獲得一個hash_key嘗試尋找一個已經打開的文件 */
hash_key_len = spprintf(&hash_key, 0,
"sample_descriptor:%s:%s", filename, mode);
if (zend_hash_find(&EG(persistent_list), hash_key,
hash_key_len + 1, (void **)&existing_file) == SUCCESS) {
/* 成功的找到了這個已經打開的文件句柄資源 */
ZEND_REGISTER_RESOURCE(return_value,
existing_file->ptr, le_sample_descriptor_persist);
efree(hash_key);
return;
}
fp = fopen(filename, mode);
if (!fp) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Unable to open %s using mode %s",
filename, mode);
RETURN_FALSE;
}
if (!persist) {
fdata = emalloc(sizeof(php_sample_descriptor_data));
fdata->filename = estrndup(filename, filename_len);
fdata->fp = fp;
ZEND_REGISTER_RESOURCE(return_value, fdata,
le_sample_descriptor);
} else {
list_entry le;
fdata =pemalloc(sizeof(php_sample_descriptor_data),1);
fdata->filename = pemalloc(filename_len + 1, 1);
memcpy(data->filename, filename, filename_len + 1);
fdata->fp = fp;
ZEND_REGISTER_RESOURCE(return_value, fdata,
le_sample_descriptor_persist);
/* Store a copy in the persistent_list */
le.type = le_sample_descriptor_persist;
le.ptr = fdata;
/* hash_key has already been created by now */
zend_hash_update(&EG(persistent_list),
hash_key, hash_key_len + 1,
(void*)&le, sizeof(list_entry), NULL);
}
efree(hash_key);
}if (zend_hash_find(&EG(persistent_list), hash_key,
hash_key_len + 1, (void**)&socket) == SUCCESS) {
if (php_sample_socket_is_alive(socket->ptr)) {
ZEND_REGISTER_RESOURCE(return_value,
socket->ptr, le_sample_socket);
return;
}
zend_hash_del(&EG(persistent_list),
hash_key, hash_key_len + 1); //這里會去調用之前注冊好的析構函數
}
分享標題:php擴展與嵌入--資源數據類型2
本文URL:http://www.js-pz168.com/news31/283731.html
成都網站建設公司_創新互聯,為您提供網站建設、面包屑導航、App設計、軟件開發、品牌網站制作、品牌網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯
猜你還喜歡下面的內容