phpstrlen
‘壹’ php里这个strlen()-1减一是什么意思
是因为php的字符串变量的索引是从0开始的,所以最大长度减1就是实际长度,不减1就会发生数组越界
‘贰’ php strlen utf8一个中文算3个字节吗
utf8是变长编码, 不一定是3字节, 可能是2~3, 当然ASCII字符还是1字节.gbk也是变长编码, 非ASCII的2字节, ASCII还是1字节.这两个编码对于非ASCII字符, 都是多字节的, 并且多字节字符每个字节都是>127的, 也就是负数(最高位是1).另外, PHP里的strlen不是依靠判断字符串结尾的, 因为PHP是脚本语言, 它的字符串和C++的string是一样的, 将存储的字节个数当作字符串长度.另外, PHP里想数数有多少个字节用strlen, 想数数有多少个字符, 用mb系列函数, 自己去了解一下.还有些需求, 比如字符串匹配查找之类的, gbk是存在双字节匹配问题的, 两个连续汉字的中间2个字节可能被误认为其他字符, 所以不能用strstr之类的字节匹配函数(PHP里是纯字节匹配的, 不关心), 但utf-8是可以的, 它不会有类似的冲突, 另外最好的做法当然还是用mb系列, 安全可靠, 而且还支持猜编码功能.
‘叁’ php的strlen问题,为什么相同的一句话,输出结果不同呢
编码问题。
UTF8编码中,中文为3字节,也就是一个中文字占用3个字节。
GB编码中,中文为2字节。
你可以数一下(那个冒号应该是英文字符,占1字节),31的那个是UTF8编码,26的是GB编码
并且中文有5个字,两个差距正好差了5个字节。
‘肆’ PHP的strlen函数
返回字符串的长度。
计算字符串长度可以用于条件判断,例如限制某个变量值的长度。
strlen函数属于string字符串函数。
计算成功返回字符串长度,如果字符串为空返回0。
运行结果:
在 PHP 5.3.0 之前,该函数把数组当做字符串 Array,这样就返回一个长度为 5 的字符串,并产生一个 E_NOTICE 级别的错误。
在count函数的“应用经验”里提到的对$_GET做限制的应用,在编写SteelEC的miniblog功能时也用到strlen函数做限制“锚”字符串长度。
w3school:PHP strlen()函数
count:返回数组中的元素数量。
‘伍’ php中strlen什么意思
strlen获取变量的长度,判断是否等于2,这里有几个问题,比如如果$i是中文的话结果可能有问题,使用mb_strlen避免错误。
‘陆’ 为什么PHP中会出现strlen函数未定义的致命错误
(strlen($_POST['year']==4)这句当为空时,里面参数就会是空,从而导致函数失效
Warning: Wrong parameter count for strlen() in C:\AppServ\www\wocs.php on line 2
‘柒’ php哪个函数能取得字符串长度
1、首先新建一个php文件,命名为test.php。

‘捌’ PHP字符串长度计算 - strlen()函数使用介绍
strlen()函数和mb_strlen()函数
在PHP中,函数strlen()返回字符串的长度。函数原型如下:
复制代码
代码如下:
int
strlen(string
string_input);
参数string_input为要处理的字符串。
strlen()函数返回字符串所占的字节长度,一个英文字母、数字、各种符号均占一个字节,它们的长度均为1。一个中午字符占两个字节,所以一个中午字符的长度是2。例如
复制代码
代码如下:
<?php
echo
strlen("www.sunchis.com");
echo
strlen("三知开发网");
?>
“echo
strlen("www.sunchis.com");”的运行结果:15
“echo
strlen("三知开发网");”的运行结果:15
这里有一个疑问,一个中文字符不是占2个字节吗?“三知开发网”,明明是五个汉字,运行的结果怎么会是15?
原因出在这里:strlen()计算时,对于一个UTF-8的中文字符,会把它当做长度为3来处理。当出现中英文混排的情况下,怎么准确的计算字符串的长度呢?这里,得引入另外一个函数mb_strlen()。mb_strlen()函数的用法与strlen()几乎一摸一样,只是多了一个指定字符集编码的参数。函数原型为:
复制代码
代码如下:
int
mb_strlen(string
string_input,
string
encode);
PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在UTF-8编码下,一个汉字占3个字节)。
因此,下面的代码能准确计算出中文字符串的长度:
复制代码
代码如下:
<?php
$str
=
"三知sunchis开发网";
echo
strlen($str)."<br>";
//结果:22
echo
mb_strlen($str,"UTF8")."<br>";
//结果:12
$strlen
=
(strlen($str)+mb_strlen($str,"UTF8"))/2;
echo
$strlen;
//结果:17
?>
原理分析:
strlen()计算时,对待UTF-8的中文字符长度是3,所以“三知sunchis开发网”的长度为5×3+7×1=22
在mb_strlen计算时,选定内码为UTF8,则会将一个中文字符当作长度1来计算,所以“三知sunchis开发网”长度为5×1+7×1=12
剩下的就是纯数学问题了,在此就不啰嗦了……
注意:对于mb_strlen($str,'UTF-8'),如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过mb_internal_encoding()函数得到。需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函数的问题。
‘玖’ PHP的count(数组)和strlen(字符串)的内部实现。
翻了下PHP内核的定义,大概心中也有了答案了
count()和strlen()都是O(1)的时间复杂度
试想一下如果strlen()需要O(N)的复杂度那未免也太慢了,字符串长度起来的话服务器不是要直接挂掉吗
这两个函数都是典型的空间换时间的做法
我们可以先看看zvalue的结构:
typedefunion_zvalue_value{
longlval;/*longvalue*/
doubledval;/*doublevalue*/
struct{
char*val;
intlen;
}str;
HashTable*ht;/*hashtablevalue*/
zend_object_valueobj;
zend_ast*ast;
}zvalue_value;这里用的是一个联合体,当变量类型是string类型的时候附加存储多了一个len的整型变量,显而易见需要取长度直接利用记录值就可以了,自然就是O(1)
对于count()常用的参数类型应该为数组,对于继承Countable的类暂不作讨论
数组实现方式为Hashtable,直接看看他的结构吧
typedefstruct_hashtable{
uintnTableSize;//hashBucket的大小,最小为8,以2x增长。
uintnTableMask;//nTableSize-1,索引取值的优化
uintnNumOfElements;//hashBucket中当前存在的元素个数,count()函数会直接返回此值
ulongnNextFreeElement;//下一个数字索引的位置
Bucket*pInternalPointer;//当前遍历的指针(foreach比for快的原因之一)
Bucket*pListHead;//存储数组头元素指针
Bucket*pListTail;//存储数组尾元素指针
Bucket**arBuckets;//存储hash数组
dtor_func_tpDestructor;//在删除元素时执行的回调函数,用于资源的释放
zend_boolpersistent;//指出了Bucket内存分配的方式。如果persisient为TRUE,则使用操作系统本身的内存分配函数为Bucket分配内存,否则使用PHP的内存分配函数。
unsignedcharnApplyCount;//标记当前hashBucket被递归访问的次数(防止多次递归)
zend_boolbApplyProtection;//标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次
#ifZEND_DEBUG
intinconsistent;
#endif
}HashTable;count直接获取nNumOfElements大小,所以也是O(1)
补充------------------------------------------------
count() 函数的定义在这里
/*{{{protointcount(mixedvar[,intmode])
(usuallyanarray)*/
PHP_FUNCTION(count)
{
zval*array;
zend_longmode=COUNT_NORMAL;
zend_longcnt;
zval*element;
ZEND_PARSE_PARAMETERS_START(1,2)
Z_PARAM_ZVAL(array)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(mode)
ZEND_PARSE_PARAMETERS_END();
switch(Z_TYPE_P(array)){
caseIS_NULL:
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(0);
break;
caseIS_ARRAY:
if(mode!=COUNT_RECURSIVE){
//类型为数组时调用zend内核函数zend_array_count()
cnt=zend_array_count(Z_ARRVAL_P(array));
}else{
cnt=php_count_recursive(Z_ARRVAL_P(array));
}
RETURN_LONG(cnt);
break;
caseIS_OBJECT:{
zvalretval;
/*first,wecheckifthehandlerisdefined*/
if(Z_OBJ_HT_P(array)->count_elements){
RETVAL_LONG(1);
if(SUCCESS==Z_OBJ_HT(*array)->count_elements(array,&Z_LVAL_P(return_value))){
return;
}
}
/*()method*/
if(instanceof_function(Z_OBJCE_P(array),zend_ce_countable)){
zend_call_method_with_0_params(array,NULL,NULL,"count",&retval);
if(Z_TYPE(retval)!=IS_UNDEF){
RETVAL_LONG(zval_get_long(&retval));
zval_ptr_dtor(&retval);
}
return;
}
/*IfThere'snohandleranditdoesn'*/
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(1);
break;
}
default:
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(1);
break;
}
}如果没有特别指定mode参数为 COUNT_RECURSIVE 的话(即作遍历),跳转到 zend 的数组计数函数 zend_array_count()
#definezend_hash_num_elements(ht)
(ht)->nNumOfElements
...
...
staticuint32_tzend_array_recalc_elements(HashTable*ht)
{
zval*val;
uint32_tnum=ht->nNumOfElements;
ZEND_HASH_FOREACH_VAL(ht,val){
if(Z_TYPE_P(val)==IS_INDIRECT){
if(UNEXPECTED(Z_TYPE_P(Z_INDIRECT_P(val))==IS_UNDEF)){
num--;
}
}
}ZEND_HASH_FOREACH_END();
returnnum;
}
ZEND_APIuint32_tzend_array_count(HashTable*ht)
{
uint32_tnum;
if(UNEXPECTED(ht->u.v.flags&HASH_FLAG_HAS_EMPTY_IND)){
num=zend_array_recalc_elements(ht);
if(UNEXPECTED(ht->nNumOfElements==num)){
ht->u.v.flags&=~HASH_FLAG_HAS_EMPTY_IND;
}
}elseif(UNEXPECTED(ht==&EG(symbol_table))){
num=zend_array_recalc_elements(ht);
}else{
num=zend_hash_num_elements(ht);
}
returnnum;
}
IS_REFERENCE:间接 zval 指的就是其真正的值是存储在其他地方的。注意这个IS_REFERENCE类型是不同的,间接 zval 是直接指向另外一个 zval 而不是像zend_reference结构体一样嵌入 zval。
只有当数组中有HASH_FLAG_HAS_EMPTY_IND 这个 flag 时(间接zval)才会对数组进行遍历校验,其他情况下都是直接取 数组(hash table) 里面的 nNumOfElements 的值,答案显而易见了,就是O(1)
‘拾’ php 中的mb_strlen 与 strlen 哪个跟javascript 中的length 相同,如果不同应该怎么改的相同
额~ 如果是字符串长度的话 mb_strlen 和 Js 的 length 相同。
strlen是字符串长度,但是其实可以说是字节长度,因为PHP还不支持unicode,所以对于多字节字符没法通过strlen正确的取得长度。如果编码是gbk的话,一个汉字的长度是2, 如果是utf-8的话,一个汉字的长度一般是3,也可能不是,这个按照编码区间来区分。
如果要出里多字节字符字符串的话,就要用PHP 的一个 mb 扩展,mb族包含了一系列函数,可以去PHP 手册看http://www.php.net/manual-lookup.php?pattern=mb&lang=en&scope=quickref
我也表达不是很明白。建议你网络或者google 一下 Unicode、ASCII、UTF-8、GBK~ 都看一下,就很明白了。PHP和JS支持的编码不一样,所以很多不一样。
有问题可以Hi我。
