声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。
博客地址:
PHP技术博客在CSDN也会同步更新的哦.
欢迎转载,转载请注明出处
在PHP里 有两个计算 字符串个数的函数
一个是 strlen,一个是mb_strlen;
先来看看帮助手册的定义
strlen — 获取字符串长度
int strlen ( string $string )
返回给定的字符串 string 的长度。
intmb_strlen( string$str[,
string$encoding] )
返回给定的字符串 string 的长度。
encoding参数为字符编码。如果省略,则使用内部字符编码。
这么看 除了mb_strlen可以传递一个 字符编码好像没有其他区别
写一个PHP程序来看看
[php]
$a="我是s斯t人";
echo strlen($a);
echo "<br>";
echo mb_strlen($a,'utf8');
[/php]
输出结果
14
6
很明显 strlen对于中文来讲,每个汉字占三个字节,$a的字节数就是14,说明 strlen计算的是字符串所占的字节数
在mb_strlen计算时,如果encoding设置为utf8,那么,中文将占一个字节 那么$a就是6
需要注意的是 mb_strlen并不是PHP内置函数,需要修改php.ini,开启 php_mbstring
好了..
我们下面就深入到PHP内核源码去看看两个函数的不同.
先看mb_strlen的定义
[c]
PHP_FUNCTION(mb_strlen)
{
int n;
mbfl_string string;
char *enc_name = NULL; int enc_name_len;
mbfl_string_init(&string);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {
RETURN_FALSE;
}
string.no_language = MBSTRG(language);
if (enc_name == NULL) { string.no_encoding = MBSTRG(current_internal_encoding);
} else {
string.no_encoding = mbfl_name2no_encoding(enc_name);
if (string.no_encoding == mbfl_no_encoding_invalid) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name); RETURN_FALSE;
}
}
n = mbfl_strlen(&string);
if (n >= 0) {
RETVAL_LONG(n);
} else {
RETVAL_FALSE;
}
}
[/c]
mbfl_string 是一个结构体
[c]
typedef struct _mbfl_string {
enum mbfl_no_language no_language;
enum mbfl_no_encoding no_encoding;
unsigned char *val; unsigned int len;
} mbfl_string;
[/c]
看定义就知道,这两个保存了当前字符串的语言,编码,保存的值和长度
mbfl_string_init(&string);
这个函数是初始化string;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {
RETURN_FALSE;
}
这里接收传递过来的两个参数,也就是前面看到的 string和encoding,
enc_name保存编码,enc_name_len保存编码名字的长度
string.no_language = MBSTRG(language);
展开后
#define MBSTRG(v) (mbstring_globals.v)
这里将mbstring的language赋给string的no_language;
[c]
if (enc_name == NULL) {//如果没有手动设置编码,那么就使用PHP内置的编码 这个时候就与strlen相同
string.no_encoding = MBSTRG(current_internal_encoding);
}else {
//检查是否是有效的编码
string.no_encoding = mbfl_name2no_encoding(enc_name);
//如果传递来的编码无效 抛出异常
if (string.no_encoding == mbfl_no_encoding_invalid) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
RETURN_FALSE;
}
}
n = mbfl_strlen(&string);//计算字符串的长度
[/c]
原来这个函数里只是验证编码
真正计算长度的函数是mbfl_strlen
[c]
int mbfl_strlen(mbfl_string *string)
{
int len, n, m, k;
unsigned char *p;
const unsigned char *mbtab;
const mbfl_encoding *encoding;
//验证编码是否有效
encoding = mbfl_no2encoding(string->no_encoding);
if (encoding == NULL || string == NULL) {
return -1;
}
len = 0;
//下面是几种不同的
if (encoding->flag & MBFL_ENCTYPE_SBCS) {//是单字节字符集 直接返回
len = string->len;
} else if (encoding->flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE)) { //宽字节每个字占2位
len = string->len/2;
} else if (encoding->flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) {//宽字节每个字占4位
len = string->len/4;
} else if (encoding->mblen_table != NULL) { //mblen_table是做什么的没搞清楚,望赐教
mbtab = encoding->mblen_table;
n = 0;
p = string->val;
k = string->len;
/* count */
if (p != NULL) {
while (n < k) {
m = mbtab[*p];
n += m;
p += m;
len++;
};
}
} else { //其他编码 转换成mbfl_no_encoding_wchar再计算
/* wchar filter */
mbfl_convert_filter *filter = mbfl_convert_filter_new(
string->no_encoding,
mbfl_no_encoding_wchar,
filter_count_output, 0, &len);
if (filter == NULL) {
return -1;
}
/* count */
n = string->len;
p = string->val;
if (p != NULL) {
while (n > 0) {
(*filter->filter_function)(*p++, filter);
n--;
}
}
mbfl_convert_filter_delete(filter);
}
return len;
}
[/c]
注释很清楚了..
mb_strlen就是根据encoding不同的编码,来分别计算..好像可以计算世界大部分不同的编码格式
相比 mb_strlen ,strlen就简单的多多的多的多了
开始 没有找到 strlen定义的地方,
它在 Zend/zend_builtin_functions.c里定义的
[c]
ZEND_FUNCTION(strlen)
{
char *s1;
int s1_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) {
return;
}
RETVAL_LONG(s1_len);
}
[/c]
很简单 只是获取长度而已...
这下 他们俩的区别就很清楚了...
相关推荐
主要介绍了自己写的php中文截取函数mb_strlen和mb_substr,在服务器没mbstring库时可以使用本文函数代替,需要的朋友可以参考下
字符串长度函数strlen和mb_strlen的区分示例介绍_.docx
在PHP中,strlen与mb_strlen是求字符串长度的函数,但是对于一些初学者来说,如果不看手册,也许不太清楚其中的区别
主要介绍了php常用字符串长度函数strlen()与mb_strlen()用法,结合实例形式分析了php字符串长度函数strlen()与mb_strlen()功能、用法及相关操作注意事项,需要的朋友可以参考下
在PHP中,strlen与mb_strlen是求字符串长度的函数,但是对于一些初学者来说,如果不看手册,也许不太清楚其中的区别。 下面通过例子,讲解这两者之间的区别。 先看例子: <?php //测试时文件的编码方式要是UTF8 ...
在php中常见的计算字符串长度的函数有:strlen和mb_strlen.当字符全是英文字符的时候,两者是一样。这里主要比较一下,中英文混排的时候,两个计算结果。
本文实例分析了php中strlen和mb_strlen用法。分享给大家供大家参考,具体如下: 首先看如下代码(文件编码utf8): <?php $utf8_string = "abcd我你他她它"; var_dump(strlen($utf8_string)); var_dump(mb_...
在php中常见的计算字符串长度的函数有:strlen和mb_strlen.当字符全是英文字符的时候,两者是一样。这里主要比较一下,中英文混排的时候,两个计算结果。 先来看一个例子: 复制代码 代码如下: <?php //测试时...
C语言中strcpy_strcmp_strlen_strcat函数原型
在php中常见的计算字符串长度的函数有:strlen和mb_strlen,下面是对这两个函数的比较说明(编码方式UTF8)
目的:文章对strlen 和 wcslen 以及_tcslen做了简单的介绍。 语言:C++ 编译器:VisualStudio2010 作者:Lefter 说明: 1、strlen & wcslen & _tcslen.zip中...2、strlen & wcslen & _tcslen.pdf中含有函数说明。
c语言本身有strlen函数,这个是利用递归自己写的
网上收集而来的PHP专题精讲文档,免积分给大家分享,所有代码全部测试通过。 9个实用的PHP函数.doc ...strlen与mb_strlen字符串长度函数.doc strtok()函数实际应用.doc 文件函数.txt 研究批量删除数据的方法.doc
使用AVX2指令集实现的strlen函数,一般情况下较新的CPU都支持avx2指令集,使用avx2指令集可以加快程序的运行速度