int air_config_get_array(struct air_config_t *ach, char *key, struct air_config_value **result) { struct air_config_t *acp; if (air_config_get(ach, key, &acp) < 0) { fprintf(stderr, "no such key: %s\n", key); return -1; } if (acp->array == 0) { fprintf(stderr, "the value of [%s] is not array!\n", key); return -1; } *result = config_valueh(acp)->next; return 0; }
int air_config_get_string(struct air_config_t *ach, char *key, char **result) { struct air_config_t *acp; *result = NULL; air_config_get(ach, key, &acp); if (acp == NULL) { fprintf(stderr, "no such key: %s\n", key); goto failed; } if (acp->array == 1) { fprintf(stderr, "the value of [%s] is array!\n", key); goto failed; } *result = acp->value; return 0; failed: return -1; }
PHP_METHOD(air_view, render){ AIR_INIT_THIS; char *tpl_str; int tpl_len = 0; zend_bool ret_res = 0; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb", &tpl_str, &tpl_len, &ret_res) == FAILURE) { RETURN_FALSE; } smart_str ss_path = {0}; if(tpl_str[0] != '/'){ zval *root_path = NULL; MAKE_STD_ZVAL(root_path); if(zend_get_constant(ZEND_STRL("ROOT_PATH"), root_path) == FAILURE){ php_error_docref(NULL TSRMLS_CC, E_ERROR, "ROOT_PATH not defined"); } smart_str_appendl(&ss_path, Z_STRVAL_P(root_path), Z_STRLEN_P(root_path)); smart_str_appendc(&ss_path, '/'); if(root_path != NULL){ zval_ptr_dtor(&root_path); } zval *tmp = NULL; zval **tmp_pp; zval *config = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_config"), 0 TSRMLS_CC); if(config != NULL && Z_TYPE_P(config) == IS_ARRAY && zend_hash_find(Z_ARRVAL_P(config), ZEND_STRL("path"), (void **)&tmp_pp) == SUCCESS){ smart_str_appendl(&ss_path, Z_STRVAL_PP(tmp_pp), Z_STRLEN_PP(tmp_pp)); }else{ zval *app_conf; zval *view_conf; if(air_config_get(NULL, ZEND_STRS("app"), &app_conf TSRMLS_CC) == FAILURE){ AIR_NEW_EXCEPTION(1, "@error config: app"); } zval *app_path = NULL; if(air_config_get(app_conf, ZEND_STRS("path"), &app_path) == FAILURE){ AIR_NEW_EXCEPTION(1, "@error config: app.path"); } zval *view_path = NULL; if(air_config_get_path(app_conf, ZEND_STRS("view.path"), &view_path) == FAILURE){ AIR_NEW_EXCEPTION(1, "@view config not found"); } smart_str_appendl(&ss_path, Z_STRVAL_P(app_path), Z_STRLEN_P(app_path)); smart_str_appendc(&ss_path, '/'); smart_str_appendl(&ss_path, Z_STRVAL_P(view_path), Z_STRLEN_P(view_path)); } smart_str_appendc(&ss_path, '/'); } smart_str_appendl(&ss_path, tpl_str, tpl_len); smart_str_0(&ss_path); //php_printf("full view path: %s\n", ss_path.c); //构造运行时所需基本变量 HashTable *origin_symbol_table = NULL; zval *output_handler = NULL; long chunk_size = 0; long flags = PHP_OUTPUT_HANDLER_STDFLAGS; zval *view_ret = NULL; //尝试缓存当前符号表 if(EG(active_symbol_table)){ origin_symbol_table = EG(active_symbol_table); } if (ret_res) { MAKE_STD_ZVAL(view_ret); if(php_output_start_user(output_handler, chunk_size, flags TSRMLS_CC) == FAILURE) { php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to create buffer"); RETURN_FALSE; } } ALLOC_HASHTABLE(EG(active_symbol_table)); zval *data = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_data"), 0 TSRMLS_CC); zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0); //将当前的模板变量放到符号表去 ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), "var", 4, data, Z_REFCOUNT_P(data) + 1, PZVAL_IS_REF(data)); if(air_loader_include_file(ss_path.c TSRMLS_CC) == FAILURE){ air_throw_exception_ex(1, "tpl %s render failed!\n", ss_path.c); return ; } if(ret_res){ php_output_get_contents(view_ret TSRMLS_CC); php_output_discard(TSRMLS_C); RETVAL_ZVAL(view_ret, 1, 0); zval_ptr_dtor(&view_ret); } zend_hash_destroy(EG(active_symbol_table)); FREE_HASHTABLE(EG(active_symbol_table)); EG(active_symbol_table) = origin_symbol_table; smart_str_free(&ss_path); }