導航:首頁 > 編程語言 > phpstrlen0

phpstrlen0

發布時間:2022-04-01 06:25:43

『壹』 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 substr($string,0,strlen($string)-1); 字元串$string很長會影響速度之類的嗎

<?php
$start=microtime();
$string="";

for($i=1;$i<1000000;$i++){
$string.="s";
}
$end=microtime();
echo$time=$end-$start;
substr($string,0,strlen($string)-1);
echomicrotime()-$end;//在千萬級內還是只需0.0幾秒的
?>

『叄』 php中strlen測漢字位元組數

呵呵,因為utf-8編碼的漢字是3個位元組的,平常的gbk和ansi編碼的才是兩個位元組。

『肆』 ajax php那加if (strlen($q) > 0)判斷有什麼用

js判斷是客戶端, 客戶端的任何東西都是可以改變的!
比如, 用戶如果懂編程的話, 不一定要用你寫好的js
完全可以自己構造一些東西進行提交!
可想而知, 如在伺服器端沒有進行驗證的話, 是多麼的無力?
而伺服器端驗證, 雖然理論上, 高手也可以更改!
但總歸沒那麼簡單不是?

『伍』 在php的mt_rand(0,strlen)-1,為什麼要減丨

沒有看到完整代碼,根據strlen可以知道這塊是用strlen或mb_strlen計算的字元串長度,如果,為什麼減1,如果我推論沒錯這段代碼應該是
mt_rand(0,strlen-1);舉個例子,從一個字元串隨機取出一段一定長度的隨機字元串,驗證碼就是樣的。

$randStr = '';
$strlen = strlen($randStr);
$code = '';
for($i=0;$i<4;++$i){
$code .= $randStr[mt_rand(0,$strlen-1)];
}
echo $code;

『陸』 php代碼 字元串有中文也有數字,如何取數字

使用字元串拆分成數組。然後在判斷數組元素是否為數值型。

字元串涉及字元編碼。比較麻煩。簡單點的。替換date 值。

將 「上午」「點」「下午」「晚上」「早上」「中午」等能出現的字元。全部替換成空

『柒』 php寫一個方法只保留前4個字元其餘用...表示

/**
*只保留字元串首尾字元,隱藏中間用.代替,默認顯示頭尾各一位(兩個字元時只顯示第一個)
*@paramstring$string字元串
*@paramstring$firstStrlen頭要顯示的字元長度
*@paramstring$lastStrlen尾要顯示的字元長度
*@returnstring格式化後的姓名
*/
functionsubstr_cut($string,$firstStrlen=1,$lastStrlen=1){
$strlen=mb_strlen($string,'utf-8');
$Str=$firstStrlen+$lastStrlen;
if($strlen<=1||$Str>$strlen)
returnfalse;

$firstStr=mb_substr($string,0,$firstStrlen,'utf-8');
$lastStr=mb_substr($string,-$lastStrlen,$lastStrlen,'utf-8');
return$strlen==2?$firstStr.str_repeat('.',mb_strlen($string,'utf-8')-1):$firstStr.str_repeat(".",$strlen-$Str).$lastStr;
}

『捌』 php strlen跟mb_strlen有什麼區別

strlen與mb_strlen是求字元串長度的函數

下面通過例子,講解這兩者之間的區別。

<?php
//測試時文件的編碼方式要是UTF8
$str='中文a字1符';
echostrlen($str).'<br>';//14
echomb_strlen($str,'utf8').'<br>';//6
echomb_strlen($str,'gbk').'<br>';//8
echomb_strlen($str,'gb2312').'<br>';//10
?>

需要注意的是,mb_strlen並不是PHP核心函數,使用前需要確保在php.ini中載入了php_mbstring.dll,即確保「extension=php_mbstring.dll」這一行存在並且沒有被注釋掉,否則會出現未定義函 數的問題。

『玖』 php截取字元串

這個問題我回答了好幾個了:
/* 截取一定長度的完整的中文字元 */

function cnsubstr($str,$strlen=10) {

if(empty($str)||!is_numeric($strlen)){
return false;
}
if(strlen($str)<=$strlen){
return $str;
}

//得到第$length個字元 並判斷是否為非中文 若為非中文
//直接返回$length長的字元串
$last_word_needed=substr($str,$strlen-1,1);
if(!ord($last_word_needed)>128){
$needed_sub_sentence=substr($str,0,$strlen);
return $needed_sub_sentence;
}else{
for($i=0;$i<$strlen;$i++){
if(ord($str[$i])>128){
$i++;
}
}//end of for
$needed_sub_sentence=substr($str,0,$i);
return $needed_sub_sentence;
}
}
直接調用這個函數就可以了。

『拾』 PHP里這個strlen()-1減一是什麼意思

是因為php的字元串變數的索引是從0開始的,所以最大長度減1就是實際長度,不減1就會發生數組越界

閱讀全文

與phpstrlen0相關的資料

熱點內容
優信二手車解壓後過戶 瀏覽:61
Windows常用c編譯器 瀏覽:778
關於改善國家網路安全的行政命令 瀏覽:833
安卓如何下載網易荒野pc服 瀏覽:654
javainetaddress 瀏覽:104
蘋果4s固件下載完了怎麼解壓 瀏覽:1002
命令zpa 瀏覽:285
python編譯器小程序 瀏覽:944
在app上看視頻怎麼光線調暗 瀏覽:540
可以中文解壓的解壓軟體 瀏覽:592
安卓卸載組件應用怎麼安裝 瀏覽:913
使用面向對象編程的方式 瀏覽:339
程序員項目經理的年終總結範文 瀏覽:929
內衣的加密設計用來幹嘛的 瀏覽:432
淮安數據加密 瀏覽:292
魔高一丈指標源碼 瀏覽:982
松下php研究所 瀏覽:168
c回調java 瀏覽:399
夢幻端游長安地圖互通源碼 瀏覽:745
電腦本地文件如何上傳伺服器 瀏覽:313