php7 拡張機能の開発 [11] ファイルを解析してロードするための MVC ルート

WBOY
リリース: 2016-06-23 13:09:30
オリジナル
1205 人が閲覧しました

```
シナリオ: PHP で MVC 構造のルート解析とファイル読み込み機能を実装するために C を使用したい場合は、合計でいくつかの問題を解決する必要があります
1. MVC は複数の C ファイルを読み込む必要があるため、config .m4を変更する必要があります。config.m4の10行目あたりの内容を変更し、dnl、
PHP_ARG_WITH(dora、ルートサポート用、
dnl)を削除します。コメントが整列していることを確認してください:
[ --with-ルート以下を追加します:
if test -z "$PHP_DEBUG" then
AC_ARG_ENABLE(debug, [--enable-debug combing with debugging system], [PHP_DEBUG=$enableval],[PHP_DEBUG=]いいえ])
fi

最後の行は、次のように、必要な C ファイルをすべてロードします:
PHP_NEW_EXTENSION(dora, dora.c common/utilts.c loader/loader.c Route/route.ccontroller/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])
D_BUI LD_DIR([$ext_builddir/コントローラー])
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 _ハンドル_FILENAME;
zfd .filename = filepath;
zfd.free_filename = 0;
zfd.opened_pa​​th = NULL;

//zend_execute_scripts(int type, zval *retval, int file_count, ...);
//失敗または成功
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 = (CG(function_table));
}

zend_fcall_info fci ;
fci.size = sizeof(fci);
fci.function_table = function_table;
fci.object = obj : NULL; fci.params = params;
fci.symbol_table;



//失敗または成功
return zend_call_function(&fci, NULL TSRMLS_CC); // 関数呼び出しが終了します。

}


```
````c
3. php_route.h ヘッダー ファイルの内容を変更します

50 行目あたりに、次の内容を追加します

//Define class
extern zend_class_entry *route_ce;
/ /ローダークラスのメソッドを定義します
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);

}



/**
* ビューをロード
* @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( "インデックス"),0);

zval *c_result;
zval *a_result;
int flag;



//设置站点目录
zval *app_dir = erty(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("コントローラ", sizeof("コントローラ")-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, "コントローラー パラメーターが見つかりませんでした");

}
//释放キーの变量
zend_string_release(c_key);


//获取action_name
zend_string *a_key= zend_string_init("action" 、sizeof("アクション")-1、0 );

if ((a_result = zend_hash_find(ht, a_key)) != NULL) {

action_name = zval_get_string(a_result);
//php_printf("%sn", Z_STRVAL_P(a_ result));
//php_printf ("%sn", zval_get_string(a_result));
}else{

zend_error_noreturn(E_CORE_ERROR,"URL にアクション パラメータが見つかりませんでした。");

}

//释解放キーの变量
zend_string_release(a_key );


//拼装コントローラー文件路径
char *path = Z_STRVAL_P(app_dir);
char *c_2 = "controllers/";
strcat(path,c_2);

//zend_string-& gt;char *
char *c_3 = ZSTR_VAL(controller_name);
strcat(path,c_3);

char *c_4 = ".php";
strcat(path,c_4);

//php_printf("%sn", c_1);
// php_printf("%sn",controller_name);
// php_printf("%sn", action_name);
//PHPWRITE(Z_STRVAL_P(app_dir), Z_STRLEN_P(app_dir));



/ /加下执行コントローラー文件
flag = zend_execute_scripts_ext(c_1);

if(flag == FAILURE){

zend_error_noreturn(E_CORE_ERROR,"ファイルが見つかりませんでした: %s.",c_1);

}


//查找コントローラー应的
//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,"ファイルが見つかりませんでした: %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 、関数名、0、NULL);

if(flag = = FAILURE){


zend_error_noreturn(E_CORE_ERROR,
「メソッド %s%s%s の実装が見つかりませんでした」
コントローラー_ce ? ZSTR_VAL(コントローラー_ce->名前) : "",
コントローラー_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 /* Route_functions[] の最後の行である必要があります */
};

PHP_MINIT_FUNCTION(ルート)
{

//注册route类
zend_class_entry ce;

// INIT_NS_CLASS_ENTRY(class_container, ns, class_name, function) を定義します
INIT_NS_CLASS_ENTRY(ce,"Dora" ,"Route", 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_d ir", 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 コア グローバル 主要に存在するphp.ini 内の情報
SG -> SAPI Global SAPI情報

//========================================= =====================================
PHP7 の zval の種類:
/* 通常のデータタイプ */
define IS_UNDEF 0
define IS_NULL 1
define IS_FALSE 2
IS_TRUE 3
IS_LONGを定義します 4
IS_DOUBLEを定義します 5
IS_STRINGを定義します 6
IS_ARRAY の定義 7.IS_OBJECT ABLE の定義 14

IS_INDIRECT の定義 15
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) 、レン);

//================== ======================= ========================== ===========

PHP7 の画像の zval の値と長さ:
define Z_LVAL(zval) (zval).value.lval
Z_LVAL_P(zval_p) Z_LVAL(*(zval_p))

Z_DVAL(zval) zval_p))

Z_STRVAL(zval) を定義_STR(zval))
定義Z_STRVAL_P(zval_p) Z_STRVAL(*(zval_p)) Z_STRLEN(*(zval_p))

Z_STRHASH(zval)を定義 ZSTR_HASH(Z_STR(zval))
Z_STRHASH_P(zval_p) Z_STRHASH(*(zval_p))

Z_ARR( zval) (zval).value.arr
Z_ARR_P(zval_p) Z_ARR(*(zval_p))を定義

Z_ARRVAL(zval)を定義Z_OBJ_P(zval_p) Z_OBJ(*(zval_p))

Z_OBJ_HT(zval)を定義( zval)->handlers ((zval))->hf
define Z_OBJ_HANDLER_P(zv_p, hf) Z_OBJ_HANDLER(*(zv_p), hf)

define Z_OBJ_HANDLE(zval) (Z_OBJ((zval)))->ハンドル
Z_OBJ_HANDLE_P(zval_p Z_OBJ_HANDLE(*(zval_p))を定義

Z_OBJCE(zval)を定義Z_OBJPROP(zval) Z_OBJ_HT((zval)) を定義します->get_properties(&(zval))
Z_OBJPROP_P(zval_p) Z_OBJPROP(*(zval_p))を定義します

Z_OBJDEBUG(zval,tmp) get_debug_info)?Z_OBJ_HANDLER((zval) ),get_debug_info)(&(zval),&tmp):(tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
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)-&g t;ハンドル
Z_RES_HANDLE_P(zval_p) を定義します Z_RES_HANDLE( *zval_p)

Z_RES_TYPE(zval) を定義する Z_RES(zval)->type
Z_RES_TYPE_P(zval_p) を定義する Z_RES_TYPE(*zval_p)

Z_RES_VAL(zval) を定義する Z_RES(zval)-& gt; ptr
Z_RES_VAL_P(zval_p を定義) ) Z_RES_VAL(*zval_p)

Z_REF(zval) (zval).value.ref ->val
define Z_REFVAL_P(zval_p) Z_REFVAL(*(zval_p))

Z_AST(zval) (zval).value。 ast
define Z_AST_P(zval_p) ) (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) ))

define Z_CE(zval) (*(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("type is IS_NULL!n");
}

if( Z_TYPE_P(zv_p) == IS_LONG )
{
php_printf("typeは IS_LONG,值是:%ld" Z_LVAL_P(zv_p)); //================================= ============== RETVAL_BOOL (b) ZVAL_BOOL(return_value, b)
RETVAL_NULL() を定義します ZVAL_NULL(return_value)
define RETVAL_LONG(l) ZVAL_LONG(return_value, l)
define DOUBLE(d) ZVAL_DOUBLE(return_value, d)
RETVAL_STR(s) を定義 ZVAL_STR(return_value, s)
RETVAL_INTERNED_ STR ZVAL_INTERNED_STR(return_value, s)
RETVAL_NEW_STR(s) を定義します ZVAL_NEW_STR(return_value, s)
RETVAL_STR_COPY(s) を定義しますZVAL_STR_COPY(return_value, s)
RETVAL_STRING(s) を定義します ZVAL_STRING(return_value, s)
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)
RETVAL_ARR(r)を定義します ZVAL_ARR(return_value, r)
RETVAL_OBJ(r) ZVAL_OBJ(return_value 、r)
RETVAL_ZVAL(zv, copy, dtor)を定義します ZVAL_ZVAL(return_value, zv, copy, dtor)
RETVAL_FALSEを定義します ZVAL_FALSE(return_value)
RETを定義VAL_TRUE ZVAL_TRUE(return_value)


RETURN_BOOL(b) を定義 { RETVAL_BOOL(b) ;戻る; }
RETURN_NULL() を定義します { RETVAL_NULL(); return;}
RETURN_LONG(l) を定義します { RETVAL_LONG(l);戻る; }
RETURN_DOUBLE(d) を定義します { RETVAL_DOUBLE(d);戻る; }
RETURN_STR(s) を定義します { RETVAL_STR(s);戻る; }
RETURN_INTERNED_STR(s) を定義します { RETVAL_INTERNED_STR(s);戻る; }
RETURN_NEW_STR(s) を定義します { RETVAL_NEW_STR(s);戻る; }
RETURN_STR_COPY を定義します { RETVAL_STR_COPY;戻る; }
RETURN_STRING を定義します { RETVAL_STRING;戻る; }
RETURN_STRINGL(s, l) を定義します { RETVAL_STRINGL(s, l);戻る; }
RETURN_EMPTY_STRING() を定義します { RETVAL_EMPTY_STRING();戻る; }
RETURN_RES(r) を定義します { RETVAL_RES(r);戻る; }
RETURN_ARR(r) を定義します { RETVAL_ARR(r);戻る; }
RETURN_OBJ(r) を定義します { RETVAL_OBJ(r);戻る; }
RETURN_ZVAL(zv, copy, dtor) を定義します { RETVAL_ZVAL(zv, copy, dtor);戻る; }
RETURN_FALSE を定義します { RETVAL_FALSE;戻る; }
RETURN_TRUE を定義します { RETVAL_TRUE;戻る; }
array_init(return_value);//初期化return_value成数組、この操作が完了すると空の数組を返すことができます
object_init(return_value);//初期化return_value成Object、この操作が完了すると空の数組を返します




//============================================ ==================================
grep "define ZEND_ACC" Zend/*.h
内核中提供Zend/zend_compile.h 規定の方法の修正 Zend/zend_compile.h 規定END_ACC_IMPLEMENTED_ABSTRACT 0x08
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS を定義する 0x10
ZEND_ACC_EXPLICIT_ABSTRACT_CLASS を定義する 0x20
ZEND_ACC_INTERFACE を定義する 0x40
ZEND_ACC_TRAIT を定義します 0x80
ZEND_ACC_ANON_CLASS を定義します0x100
ZEND_ACC_ANON_BOUNDを定義します 0x200
ZEND_ACC_PUBLICを定義します 0x100
ZEND_ACC_PROTECTEDを定義します 0x200
ZEND_ACC_PRIVATEを定義します 0x400
を定義しますZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
ZEND_ACC_CHANGEDを​​定義します 0x800
ZEND_ACC_IMPLICIT_PUBLICを定義します 0x1000
ZEND_ACC_CTORを定義します
Zを定義しますEND_ACC_DTOR 0x4000
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 );
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 付録セント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_con stant_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 *値, 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_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 zen d_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);


```

- 私の仕事の成功を尊重し、自由に転載してください。ただし、以下の情報は保持してください
- 著者: Years and Years
- 時間: 2016 年 4 月

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート