摘要:通過對底層源代碼的分析來說一下為什么會出現這種情況。從代碼可以看到,函數接受了個字符串類型的參數,一個就是需要處理的字符串,第二個參數是用來表示需要去除的字符。實現返回的操作。
在實際開發中遇到關于 trim 函數的2個問題:
????1:使用trim函數不能去除2個以上的連續點號(.)
????2 : 使用trim函數去除字符串的問題
先說一下第一個問題。
下面的一段代碼:
????php -r "echo trim("abcdcba...","...");"
我的本意是要將字符串abcdcba...最后三個點去掉,結果是報錯。
PHP Warning: trim(): Invalid ".."-range, no character to the left of ".." in Command line code on line 1 Warning: trim(): Invalid ".."-range, no character to the left of ".." in Command line code on line 1 PHP Warning: trim(): Invalid ".."-range, no character to the right of ".." inCommand line code on line 1 Warning: trim(): Invalid ".."-range, no character to the right of ".." in Command line code on line 1
這個問題其實很好解釋,因為 trim 函數本書可以范圍操作,例如 如果trim函數的第二個參數 a..d,它就會把a b c d 都去掉。因為省略號的原因,所以trim函數的第二個參數不能用..開頭或者結尾。
第二個問題:
再看一個例子:
php -r "echo trim("abcdcba","abc")."
";"
我的本意是將字符串abcdcba最前面的abc去掉保留dcba,但結果卻是這樣的:
d
也就是說他會把a b c分別去掉。這應該算是個坑吧。
通過對底層源代碼的分析來說一下為什么會出現這2種情況。
trim函數的源代碼師在php代碼根目錄開始的 ext/standard/string.c
函數的定義如下:
PHP_FUNCTION(trim) { php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3); }
可以看到,定義調用了另外的函數,函數體如下:
static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode) { char *str; char *what = NULL; int str_len, what_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRM\_CC, "s|s", &str, &str_len, &what, &what_len) == FAILURE) { return; } php_trim(str, str_len, what, what_len, return_value, mode TSRMLS_CC); }
zend_parse_parameters函數的作用就是接受參數,有興趣的同學可以查閱相關資料。從代碼可以看到,函數接受了2個字符串類型的參數,一個str,就是需要處理的字符串,第二個參數是what,用來表示需要去除的字符。
這個函數在最后用調用了另外一個函數,函數php_trim,函數體如下:
PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC) { register int i; int trimmed = 0; char mask[256]; if(what) { php_charmask((unsigned char*)what, what_len, mask TSRMLS_CC); } else { php_charmask((unsigned char*)" v