```
场景:想要用c实现php的一个mvc结构的路由解析和加载文件的功能,一共要解决几个问题
1.由于mvc要加载多个c文件,所以要修正config.m4,修改config.m4内容第十行左右,去掉dnl,
php_arg_with(dora, for route support,
dnl make sure that the comment is aligned:
[ --with-route include dora support])
在下面追加到以下内容:
if test -z "$php_debug" ; then
ac_arg_enable(debug, [--enable-debug compile with debugging system], [php_debug=$enableval],[php_debug=no] )
fi
最后一行,加载所需所有c文件,如下:
php_new_extension(dora, dora.c common/utilts.c loader/loader.c route/route.c controller/controller.c model/model.c, $ext_shared,, -dzend_enable_static_tsrmls_cache=1)
php_add_build_dir([$ext_builddir/common])
php_add_build_dir([$ext_builddir/loader])
php_add_build_dir([$ext_builddir/route])
php_add_build_dir([$ext_builddir/controller])
php_add_build_dir([$ext_builddir/model])
```
```c
#include "utilts.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "zend/zend_list.h"
#include "zend/zend_interfaces.h"
//执行php文件函数
int zend_execute_scripts_ext(char *filepath){
zval retval;
zend_file_handle zfd;
zfd.type = zend_handle_filename;
zfd.filename = filepath;
zfd.free_filename = 0;
zfd.opened_path = null;
//zend_execute_scripts(int type, zval *retval, int file_count, ...);
//failure or success
return zend_execute_scripts(zend_include tsrmls_cc,&retval,1,&zfd);
}
//调用类中的方法
int call_user_class_method(zval *retval, zend_class_entry *obj_ce,
zval *obj, zval func, uint32_t params_count, zval params[]){
hashtable *function_table;
if(obj) {
function_table = &z_objce_p(obj)->function_table;
}else{
function_table = (cg(function_table));
}
zend_fcall_info fci;
fci.size = sizeof(fci);
fci.function_table = function_table;
fci.object = obj ? z_obj_p(obj) : null;;
fci.function_name = func;
fci.retval = retval;
fci.param_count = params_count;
fci.params = params;
fci.no_separation = 1;
fci.symbol_table = null;
//failure or success
return zend_call_function(&fci, null tsrmls_cc); //函数调用结束。
}
```
```c
3.修改php_route.h头文件内容
在第五十行左右,加入以下内容
//定义类
extern zend_class_entry *route_ce;
//定义loader类中的方法
php_method(route_ce,__construct);
php_method(route_ce,run);
```
```c
4.修改route.c文件内容
/**
* 声明构造函数
* @param
* @return
*/
zend_method(route,__construct){
zval *app_dir;
if( zend_parse_parameters(zend_num_args() tsrmls_cc, "z", &app_dir) == failure )
{
return_null();
}
//zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length);
zend_update_static_property(route_ce, "app_dir", sizeof("app_dir")-1, app_dir tsrmls_cc);
}
/**
* 加载view
* @param
* @return
*/
zend_method(route,run){
zend_string* controller_name = zend_string_init("index",strlen("index"),0);
zend_string* action_name = zend_string_init("index",strlen("index"),0);
zval *c_result;
zval *a_result;
int flag;
//设置站点目录
zval *app_dir = zend_read_static_property(z_objce_p(getthis()), "app_dir", sizeof("app_dir")-1, 0 tsrmls_dc);
//获取get请求参数hashtable
zval *get_arr = &pg(http_globals)[track_vars_get];
hashtable *ht= hash_of(get_arr);
//int array_count = zend_hash_num_elements(z_arrval_p(get_arr));
//获取controller_name
zend_string *c_key= zend_string_init("controller", sizeof("controller")-1, 0);
if ((c_result = zend_hash_find(ht, c_key)) != null) {
controller_name = zval_get_string(c_result);
}else{
zend_error_noreturn(e_core_error, "couldn't find controller param in url.");
}
//释放key的变量
zend_string_release(c_key);
//获取action_name
zend_string *a_key= zend_string_init("action", sizeof("action")-1, 0);
if ((a_result = zend_hash_find(ht, a_key)) != null) {
action_name = zval_get_string(a_result);
//php_printf("%s\n", z_strval_p(a_result));
//php_printf("%s\n", zval_get_string(a_result));
}else{
zend_error_noreturn(e_core_error,"couldn't find action param in url.");
}
//释放key的变量
zend_string_release(a_key);
//拼装controller文件路径
char *path = z_strval_p(app_dir);
char *c_2 = "controllers/";
strcat(path,c_2);
//zend_string->char *
char *c_3 = zstr_val(controller_name);
strcat(path,c_3);
char *c_4 = ".php";
strcat(path,c_4);
//php_printf("%s\n", c_1);
// php_printf("%s\n", controller_name);
// php_printf("%s\n", action_name);
//phpwrite(z_strval_p(app_dir), z_strlen_p(app_dir));
//加载执行controller文件
flag = zend_execute_scripts_ext(c_1);
if(flag == failure){
zend_error_noreturn(e_core_error,"couldn't find file: %s.",c_1);
}
//查找controller对应的
//zend_class_entry *zend_lookup_class(zend_string *name);
zend_class_entry *controller_ce = zend_lookup_class(controller_name);
if(controller_ce == null){
zend_error_noreturn(e_core_error,"couldn't find file: %s.",c_1);
}
zval obj;
object_init_ex(&obj, controller_ce);
zval function_name;
zval_string(&function_name,zstr_val(action_name));
flag = call_user_class_method(return_value, controller_ce, &obj, function_name, 0, null);
if(flag == failure){
zend_error_noreturn(e_core_error,
"couldn't find implementation for method %s%s%s",
controller_ce ? zstr_val(controller_ce->name) : "",
controller_ce ? "::" : "",
function_name);
}
//return_zval(get_arr, 1, 0);
}
const zend_function_entry route_functions[] = {
//注册route类中的方法
zend_me(route, __construct, null, zend_acc_public|zend_acc_ctor)
zend_me(route,run,null,zend_acc_public)
php_fe_end /* must be the last line in route_functions[] */
};
php_minit_function(route)
{
//注册route类
zend_class_entry ce;
//define init_ns_class_entry(class_container, ns, class_name, functions)
init_ns_class_entry(ce,"dora" ,"route", route_functions);
route_ce = zend_register_internal_class(&ce tsrmls_cc);
//声明一个静态数据成员app_dir
//zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type);
zend_declare_property_string(route_ce, "app_dir", strlen("app_dir"), "",zend_acc_public|zend_acc_static tsrmls_dc);
return success;
}
```
```c
5.编译安装
phpize
./configure --with-php-config=/usr/bin/php-config
make && make install
```
```c
6.php7创建类所有到的知识点
常见的变量操作宏
cg -> complier global 编译时信息,包括函数表等(zend_globals_macros.h:32)
eg -> executor global 执行时信息(zend_globals_macros.h:43)
pg -> php core global 主要存储php.ini中的信息
sg -> sapi global sapi信息
//===============================================================================
php7中的zval的类型:
/* regular data types */
define is_undef 0
define is_null 1
define is_false 2
define is_true 3
define is_long 4
define is_double 5
define is_string 6
define is_array 7
define is_object 8
define is_resource 9
define is_reference 10
define is_constant 11
define is_constant_ast 12
define _is_bool 13
define is_callable 14
define is_indirect 15
define is_ptr 17
//===============================================================================
php7中获取的zval赋值:
- zval_string(zv, str, 1);
+ zval_string(zv, str);
- zval_stringl(zv, str, len, 1);
+ zval_stringl(zv, str, len);
- zval_string(zv, str, 0);
+ zval_string(zv, str);
+ efree(str);
- zval_stringl(zv, str, len, 0);
+ zval_stringl(zv, str, len);
//===============================================================================
php7中获取的zval的值和长度:
define z_lval(zval) (zval).value.lval
define z_lval_p(zval_p) z_lval(*(zval_p))
define z_dval(zval) (zval).value.dval
define z_dval_p(zval_p) z_dval(*(zval_p))
define z_str(zval) (zval).value.str
define z_str_p(zval_p) z_str(*(zval_p))
define z_strval(zval) zstr_val(z_str(zval))
define z_strval_p(zval_p) z_strval(*(zval_p))
define z_strlen(zval) zstr_len(z_str(zval))
define z_strlen_p(zval_p) z_strlen(*(zval_p))
define z_strhash(zval) zstr_hash(z_str(zval))
define z_strhash_p(zval_p) z_strhash(*(zval_p))
define z_arr(zval) (zval).value.arr
define z_arr_p(zval_p) z_arr(*(zval_p))
define z_arrval(zval) z_arr(zval)
define z_arrval_p(zval_p) z_arrval(*(zval_p))
define z_obj(zval) (zval).value.obj
define z_obj_p(zval_p) z_obj(*(zval_p))
define z_obj_ht(zval) z_obj(zval)->handlers
define z_obj_ht_p(zval_p) z_obj_ht(*(zval_p))
define z_obj_handler(zval, hf) z_obj_ht((zval))->hf
define z_obj_handler_p(zv_p, hf) z_obj_handler(*(zv_p), hf)
define z_obj_handle(zval) (z_obj((zval)))->handle
define z_obj_handle_p(zval_p) z_obj_handle(*(zval_p))
define z_objce(zval) (z_obj(zval)->ce)
define z_objce_p(zval_p) z_objce(*(zval_p))
define z_objprop(zval) z_obj_ht((zval))->get_properties(&(zval))
define z_objprop_p(zval_p) z_objprop(*(zval_p))
define z_objdebug(zval,tmp) (z_obj_handler((zval),get_debug_info)?z_obj_handler((zval),get_debug_info)(&(zval),&tmp):(tmp=0,z_obj_handler((zval),get_properties)?z_objprop(zval):null))
define z_objdebug_p(zval_p,tmp) z_objdebug(*(zval_p), tmp)
define z_res(zval) (zval).value.res
define z_res_p(zval_p) z_res(*zval_p)
define z_res_handle(zval) z_res(zval)->handle
define z_res_handle_p(zval_p) z_res_handle(*zval_p)
define z_res_type(zval) z_res(zval)->type
define z_res_type_p(zval_p) z_res_type(*zval_p)
define z_res_val(zval) z_res(zval)->ptr
define z_res_val_p(zval_p) z_res_val(*zval_p)
define z_ref(zval) (zval).value.ref
define z_ref_p(zval_p) z_ref(*(zval_p))
define z_refval(zval) &z_ref(zval)->val
define z_refval_p(zval_p) z_refval(*(zval_p))
define z_ast(zval) (zval).value.ast
define z_ast_p(zval_p) z_ast(*(zval_p))
define z_astval(zval) (zval).value.ast->ast
define z_astval_p(zval_p) z_astval(*(zval_p))
define z_indirect(zval) (zval).value.zv
define z_indirect_p(zval_p) z_indirect(*(zval_p))
define z_ce(zval) (zval).value.ce
define z_ce_p(zval_p) z_ce(*(zval_p))
define z_func(zval) (zval).value.func
define z_func_p(zval_p) z_func(*(zval_p))
define z_ptr(zval) (zval).value.ptr
define z_ptr_p(zval_p) z_ptr(*(zval_p))
//===============================================================================
php7 用来判断类型和取值
void display_value(zval zv,zval *zv_p,zval **zv_pp)
{
if( z_type(zv) == is_null )
{
php_printf("类型是 is_null!\n");
}
if( z_type_p(zv_p) == is_long )
{
php_printf("类型是 is_long,值是:%ld" , z_lval_p(zv_p));
}
if(z_type_pp(zv_pp) == is_double )
{
php_printf("类型是 is_double,值是:%f" , z_dval_pp(zv_pp) );
}
}
//================================================================================
php7中的定义返回值的宏 zend/zend_api.h
define retval_bool(b) zval_bool(return_value, b)
define retval_null() zval_null(return_value)
define retval_long(l) zval_long(return_value, l)
define retval_double(d) zval_double(return_value, d)
define retval_str(s) zval_str(return_value, s)
define retval_interned_str(s) zval_interned_str(return_value, s)
define retval_new_str(s) zval_new_str(return_value, s)
define retval_str_copy(s) zval_str_copy(return_value, s)
define retval_string(s) zval_string(return_value, s)
define retval_stringl(s, l) zval_stringl(return_value, s, l)
define retval_empty_string() zval_empty_string(return_value)
define retval_res(r) zval_res(return_value, r)
define retval_arr(r) zval_arr(return_value, r)
define retval_obj(r) zval_obj(return_value, r)
define retval_zval(zv, copy, dtor) zval_zval(return_value, zv, copy, dtor)
define retval_false zval_false(return_value)
define retval_true zval_true(return_value)
define return_bool(b) { retval_bool(b); return; }
define return_null() { retval_null(); return;}
define return_long(l) { retval_long(l); return; }
define return_double(d) { retval_double(d); return; }
define return_str(s) { retval_str(s); return; }
define return_interned_str(s) { retval_interned_str(s); return; }
define return_new_str(s) { retval_new_str(s); return; }
define return_str_copy(s) { retval_str_copy(s); return; }
define return_string(s) { retval_string(s); return; }
define return_stringl(s, l) { retval_stringl(s, l); return; }
define return_empty_string() { retval_empty_string(); return; }
define return_res(r) { retval_res(r); return; }
define return_arr(r) { retval_arr(r); return; }
define return_obj(r) { retval_obj(r); return; }
define return_zval(zv, copy, dtor) { retval_zval(zv, copy, dtor); return; }
define return_false { retval_false; return; }
define return_true { retval_true; return; }
array_init(return_value);//初始化return_value成数组,此操作完后就可以返回一个空的数组
object_init(return_value);//初始化return_value成object,此操作完成后返回一个空的对像
//===============================================================================
grep "define zend_acc" zend/*.h
内核中提供了定义类以方法的修饰词 zend/zend_compile.h声明定义
define zend_acc_static 0x01
define zend_acc_abstract 0x02
define zend_acc_final 0x04
define zend_acc_implemented_abstract 0x08
define zend_acc_implicit_abstract_class 0x10
define zend_acc_explicit_abstract_class 0x20
define zend_acc_interface 0x40
define zend_acc_trait 0x80
define zend_acc_anon_class 0x100
define zend_acc_anon_bound 0x200
define zend_acc_public 0x100
define zend_acc_protected 0x200
define zend_acc_private 0x400
define zend_acc_ppp_mask (zend_acc_public | zend_acc_protected | zend_acc_private)
define zend_acc_changed 0x800
define zend_acc_implicit_public 0x1000
define zend_acc_ctor 0x2000
define zend_acc_dtor 0x4000
define zend_acc_clone 0x8000
//===============================================================================
1. grep zend_acc zend/*.h
内核中提供了定义类属性的宏 zend/zend_api.h声明定义
zend_api int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment);
zend_api int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type);
zend_api int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type);
zend_api int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
zend_api int zend_declare_property_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
zend_api int zend_declare_property_double(zend_class_entry *ce, const char *name, size_t name_length, double value, int access_type);
zend_api int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type);
zend_api int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type);
更新类中的数据成员 zend/zend_api.h声明定义
zend_api void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value);
zend_api void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value);
zend_api void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length);
zend_api void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value);
zend_api void zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value);
zend_api void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, size_t name_length, double value);
zend_api void zend_update_property_str(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_string *value);
zend_api void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value);
zend_api void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value, size_t value_length);
grep "zend_read_" ../../zend/*.h
读取类中的数据成员 在zend/zend_api.h声明定义
zend_api zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv);
//===============================================================================
2. grep "zend_declare_class_constant" zend/*.h
创建类中的常量的方法在zend/zend_api.h声明定义
zend_api int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value);
zend_api int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length);
zend_api int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value);
zend_api int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value);
zend_api int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value);
zend_api int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length);
zend_api int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value);
更新类中的常量数据成员 zend/zend_api.h声明定义
zend_api int zend_update_class_constants(zend_class_entry *class_type);
//=================================================================================
3. grep "zend_update_static_" ../../zend/*.h
更新类中的静态数据成员 在zend/zend_api.
zend_api int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value);
zend_api int zend_update_static_property_null(zend_class_entry *scope, const char *name, size_t name_length);
zend_api int zend_update_static_property_bool(zend_class_entry *scope, const char *name, size_t name_length, zend_long value);
zend_api int zend_update_static_property_long(zend_class_entry *scope, const char *name, size_t name_length, zend_long value);
zend_api int zend_update_static_property_double(zend_class_entry *scope, const char *name, size_t name_length, double value);
zend_api int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value);
zend_api int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length);
grep "zend_read_" ../../zend/*.h
读取类中的数据成员 在zend/zend_api.h声明定义
zend_api zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent);
```
- 请尊重本人劳动成功,可以随意转载但保留以下信息
- 作者:岁月经年
- 时间:2016年04月
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号