yaf_dispatcher.c 的 yaf_dispatcher_fix_default函數

前言

本小節主要是介紹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

處理邏輯

  • module先所有小寫,而後首字母大寫。
  • controller先所有小寫,而後以'_'或'\'爲分隔符首字母大寫。
  • action所有小寫

示例github

  • 處理前:demo\index_sub\index
  • 處理後:Demo\Index_Sub\index

參數說明

  • 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

  1. 字符數組
  2. 字符串常量

二者的區別體如今code

  1. 字符數組存儲在全局數據區或棧區,有讀取和寫入的權限。
  2. 字符串常量存儲在常量區,只有讀取權限,沒有寫入權限。

那麼在上述代碼裏是怎麼實現的字符修改呢?爲了理解上面的知識點,寫段測試代碼用於驗證。以下

#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;
}

參考資料

  1. yaf_dispatcher.c
  2. C語言字符串
  3. Yaf_Loader自動加載策略及Dispatcher路由分發策略
  4. 知乎
相關文章
相關標籤/搜索