本小節主要是介紹yaf_dispatcher_fix_default函數的做用以及實現細節。php
static inline void yaf_dispatcher_fix_default(yaf_dispatcher_t *dispatcher, yaf_request_t *request)html
該函數用於對module/controller/action三個值進行標準化處理。以便於後續對具體類文件進行檢索定位。git
示例github
yaf_dispatcher_t *dispatcher數組
zval數據類型, Yaf_Dispatcher類實例。函數
yaf_request_t *request測試
zval數據類型, Yaf_Reqeust_Http實例spa
/** * 對module/controller/action作相應的大小寫處理 * 處理邏輯以下 * 1) 從yaf_request_ce中讀取出module, constorller, action * 2) 若是1)讀取的參數爲空或非字符類型, 則從yaf_dispatcher_ce中讀取相應的default值 * 3) module的處理是先所有小寫而後首字母大寫 * 4) controller是先所有小寫,而後依據'_'爲分隔符作首字母大寫處理, 例如 Index_sub => Index_Sub * 5) action的處理是所有小寫 * 6) 以上處理完成後均將處理後的結果值回寫yaf_request_ce對應的成員屬性 */ static inline void yaf_dispatcher_fix_default(yaf_dispatcher_t *dispatcher, yaf_request_t *request) /* {{{ */ { zval *module, *controller, *action; module = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1, NULL); action = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), 1, NULL); controller = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), 1, NULL); // module先所有小寫而後首字母大寫 if (Z_TYPE_P(module) != IS_STRING || !Z_STRLEN_P(module)) { zval *default_module = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), 1, NULL); zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), default_module); } else { char *p = zend_str_tolower_dup(Z_STRVAL_P(module), Z_STRLEN_P(module)); *p = toupper(*p); zend_update_property_stringl(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), p, Z_STRLEN_P(module)); efree(p); } // controller先所有小寫而後以'_'或'\\'爲界首字母大寫, 例 index_sub => Index_Sub if (Z_TYPE_P(controller) != IS_STRING || !Z_STRLEN_P(controller)) { zval *default_controller = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), 1, NULL); zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), default_controller); } else { char *q, *p = zend_str_tolower_dup(Z_STRVAL_P(controller), Z_STRLEN_P(controller)); /** * Upper controller name * eg: Index_sub -> Index_Sub */ q = p; *q = toupper(*q); while (*q != '\0') { if (*q == '_' || *q == '\\') { if (*(q+1) != '\0') { *(q+1) = toupper(*(q+1)); q++; } } q++; } zend_update_property_stringl(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), p, Z_STRLEN_P(controller)); efree(p); } // action所有小寫 if (Z_TYPE_P(action) != IS_STRING || !Z_STRLEN_P(action)) { zval *default_action = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), 1, NULL); zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), default_action); } else { char *p = zend_str_tolower_dup(Z_STRVAL_P(action), Z_STRLEN_P(action)); zend_update_property_stringl(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), p, Z_STRLEN_P(action)); efree(p); } } /* }}} */
在這裏,須要注意一個細節, 就是controller的那段處理邏輯。在C語言中有兩種定義字符串的方式.net
二者的區別體如今code
那麼在上述代碼裏是怎麼實現的字符修改呢?爲了理解上面的知識點,寫段測試代碼用於驗證。以下
#include<stdio.h> #include<ctype.h> #include<string.h> int main() { const char *controller = "index_sub"; char *q, *p = strdup(controller); q = p; *q = toupper(*q); while (*q != '\0') { if (*q == '_') { if (*(q+1) != '\0') { *(q+1) = toupper(*(q+1)); q++; } } q++; } printf("%s\n", p); return 0; }