PHP如何正確計算中文字串的長度

  在PHP程式設計中,我們常常遇到需要計算字串長度的場景。一般情況下,我們習慣用 strlen() 函數或 mb_strlen() 函數來計算字串長度。然而,在處理中文字串時,我們會發現使用 strlen() 函數會出現問題,因為中文字元不按照一般的字元計算方式來計算長度。那麼在PHP中,如何才能正確計算中文字串的長度呢?下面就來探討一下相關的問題。
一、PHP中字串長度的計算方式
在PHP中,計算字串長度的方式有兩種,一種是簡單的字元計數,另一種是按照實際字元長度計算。在計算字串長度時,我們會遇到兩種情況:
1.ASCII字元:在計算ASCII字元的長度時,直接使用 strlen() 函數即可。
2.中文字元:中文字元在Unicode佔用兩個字節,而在GBK中佔用兩個位元組或三個位元組。在計算中文字元長度時,需要按照字元的實際長度來計算。

二、誤用strlen() 函數的問題
strlen() 函數是PHP中一個用來計算字串長度的基本函數,它可以傳回指定字串的長度。然而,在處理中文字串時,使用 strlen() 函數會出現問題,計算長度不準確。這是由於 PHP 預設採用 ASCII 編碼,而對於 Unicode 編碼的中文字符,一個字元被解析成多個字節,導致計算長度時發生錯誤。

三、解決問題的方法
既然 strlen() 函數無法正常計算中文字元的長度,那麼我們該如何計算中文字元的長度呢?以下就是三種常用的解決方案:

1.使用 mb_strlen() 函數
PHP提供了 mb_strlen() 函數來解決字串長度問題。 mb_strlen() 函數是一個多位元組字串長度函數,它可以傳回字串的實際長度,包括中文字元在內。使用mb_strlen() 函數計算中文字串的長度時,需要傳入第二個參數來指定字元編碼,例如:
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$len=mb_strlen($my_str,'utf-8'); // len=27

2.使用iconv_strlen()函數
iconv_strlen() 函數可以用來計算字串的長度,它也可以正確處理中文字串的長度。 iconv_strlen() 函數結構類似strlen() 函數,只不過在計算長度時需要傳入第二個參數指定字元編碼,例如:
$my_str="不要在你的智慧中夾雜著傲慢。不要使你的謙虛新缺乏智慧。";
$len=iconv_strlen($my_str,'utf-8'); // len=27

3.計算位元組數再除以2 或3
除了使用PHP自帶的函數來處理之外,我們還可以透過計算中文字元的位元組數來解決長度計算問題。

把中文英文字串切成陣列-通用的方法

function mb_str_split($str){
	
	return preg_split('/(?<!^)(?!$)/u',$str);
}

PHP陣列

程式裡常常會出現陣列,不管是一維、二維、多維陣列,每每遇到陣列,我總是搞不清楚什麼是index,key,value。目前稍微懂一點,做一下筆記吧!

範例

$week=array(
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');

我們可以利用索引值來取得值,$week[0]值就是Monday。

0就是索引(index)    Monday就是值(value)

while迴圈去取值

while (list ($key,$value) = each ($week)){
   print $value;
   //印出Monday Tuesday Wednesday Thursday Friday Saturday Sunday
}

for 迴圈去取值

for ($i = 0 ; $i < count($week); $i++){
   print $week[$i];
   //印出Monday Tuesday Wednesday Thursday Friday Saturday Sunday
}

foreach陣列迴圈去取值

格式
foreach($陣列名稱 as $陣列元素變數)
{
echo $陣列元素變數;
}
foreach ($week as $key => $value){
   print $value;
}
   //印出Monday Tuesday Wednesday Thursday Friday Saturday Sunda
<?php
$array0 = array($row0= array(1,2),
$row1=array(3,4),
$row2=array(5,6));
$array1 = array($row3=array(7,8),
$row4=array(9,10),
$row5=array(11,12));
$array2 = array($row6=array(13,14),
$row7=array(15,16),
$row8=array(17,18));
$cubical = array($array0, $array1, $array2);

foreach ($cubical as $array)
{
foreach ($array as $row)
{
foreach ($row as $element)
{
echo $element."\t";
}
echo "|\t";
}
echo "<br>";
}
?>

印出

結合陣列

格式
$變數名稱["指定名稱"] = 陣列元素的值;

範例
<?php
$array["number1"] = 1;
$array["number2"] = 2;
$array[] = 3;
foreach ($array as $element)
{
echo $element."<br>";
}
?>

陣列相關函數

函數名稱說明
print_r($array)輸出陣列中每個元素索引或鍵值與元素內的值。
array_keys($array)回傳陣列中所有的索引或鍵值。
array_values($array)回傳陣列中所有元素的值。
current($array)回傳目前指標所在陣列元素的值。
key($array)回傳目前指標所在陣列元素的索引或鍵值。
each($array)回傳目前陣列元素的索引或鍵值和元素內的值,並移動自下一個元素。
reset($array)陣列指標回到第一個陣列元素。
end($array)陣列指標指到最後一個陣列元素。
next($array)陣列指標指向下一個陣列元素。
prev($array)陣列指標指向前一個陣列元素。
<?php
$array["a"] = 1; //新增結合陣列元素
$array[] = 2; //新增陣列元素
$array["b"] = 3; //新增結合陣列元素
$arrat[] = 4; //新增陣列元素

echo "1.\t";
print_r($array); //輸入陣列中每個元素索引或鍵值與元素的值
echo "<br>2.\t";
print_r(array_keys($array)); //輸出陣列中所有的索引或鍵值
echo "<br>3.\t";
print_rarray_values($array)); //輸出陣列中所有元素的值
echo "<br>4.\t";
echo current($array); //回傳目前指標所在陣列元素的值
echo "<br>5.\t";
echo key($array); //回傳目前指標所在元素的索引或鍵值
echo "<br>6.\t";
print_r(each($array)); //回傳目前的陣列元素的索引或鍵值和元素內
//的值,並移動自下一個元素
echo "<br>7.\t";
echo reset($array); //陣列指標回到第一個元素
echo "<br>8.\t";
echo end($array); //陣列指標回到最後一個元素
echo "<br>9.\t";
echo prev($array); //陣列指標指向前一個元素
echo "<br>10.\t";
echo next($array); //陣列指標指向下一個元素

陣列元素排序

函數使用格式說明
sort(陣列變數名稱)陣列元素的值從小到大排序。
rsort(陣列變數名稱)陣列元素的值從大到小排序。
asort(陣列變數名稱)結合陣列元素的值由小到大排序。
arsort(陣列變數名稱)結合陣列元素的值由大到小排序。
ksort(陣列變數名稱)結合陣列索引或鍵值由小到大排序。
krsort(陣列變數名稱)結合陣列索引或鍵值由大到小排序。
sort/rsort與asort/arsort 的差別,在於sort/rsort排序時,元素的索引或鍵值並不會留下來,並從0開始重新排序,而asort/arsort則會保留對應的索引或鍵值。

陣列元素搜尋

函數使用格式說明
in_array(數值,陣列變數名稱)檢查值是否在陣列元素中,傳回布林值。
array_search(數值,陣列變數名稱)檢查數值是否在陣列中,如果是,傳回鍵值,若沒有則傳回false。

範例

php +0

php 數字加上一個0會變成?

今天學習一組程式碼,一直納悶著為何sairwolf要加一個數字0,有甚麼用處呢?
原來,加數字零之後,取出的兩位數會變成一位數,當若是要取出兩位數,而需要是個位數時。
如:取出數是09,但是我要9時,加個數字0就會變成9。但是你會說:那不就取1位就好,但是常常是也需要2位數的。
<?php
$or_num="20045";
$count_num=substr($or_num,2,2);
echo $count_num."<br>";
$count_num +=0;
echo $count_num."<br>";

?>

結果

04
4

PHP isset() empty() is_null() 的區別

它們的區別   出處

三個方法都是來判斷是否是空值或有沒有宣告變數的方法,比較容易混淆的是isset(),empty()。

  • isset()檢查變數是否存在
  • empty()檢查變數的值是否為空
  • is_null()檢查變數是否為null
gettype()isset()empty()is_null()
$x is undefinedNULLFALSETRUETRUE
$x = null;NULLFALSETRUETRUE
$x = 0;integerTRUETRUEFALSE
$x = “0”;stringTRUETRUEFALSE
$x = 1;intergerTRUEFALSEFALSE
$x = “”;stringTRUETRUEFALSE
$x = “PHP”;stringTRUEFALSEFALSE

PHP_正規表達式

正規表達式
開頭結尾:
^:比對字串的開始位置
$:比對字串的結束位置

指定匹配次數

*:比對前一個字元0次或以上
+:比對前一個字元1次或以上
?:比對前一個字元0次或1次以上
{數字}:比對前一個字母N次(n是整數數字),ex:/{3}/,意思比對字串aaapple,中的aaa3次,可是無法比對aa,因為已經指定3次,所以只能3次。
{,數字}:比對N次以下(N是整數)
{數字,}:比對前一個字母"至少"N次(N是整數數字),ex:/{3,}/,意思可比對aaa aaaapple,中的aaaa aaa3次,只能比對該字母3次或以上。
{數字1,數字2}:比對前字母N~M次(N跟M是整數),ex:/{3,4}/,意思可比對aaa aa aaaa apple,中的aaa aaaa符合,aa apple都不符合,只能比對a 3到4次,其他多的或少的,都無法比對。

特殊符號:

\:反斜線,避開特殊字元
.:比對任何次元

特定字元:

[字母或數字]:比對括號中出現的"任何"字元,只要一個不符合就false。
    ex:[A-Z]比對大寫英文字母A-Z,反之小寫[a-z]則是比對小寫字母,[0-9]比對數字。
[^字母或數字]:比對括號內以外的字元,也就是不要比括號裡出現的字母或數字。
    ex:/[^le],表示字串中apple中,不要比對le,指比對a,p,p
/字母/:比對字串內是否含有該字母。
    ex:/m/,就是比對該字串是否含有m字母。
/字母A字母B/:比對A或B。ex:/ab/,比對字串內是否有a或b。

其他:

\b:比對英文邊界,如空格
\d:比對任一數字,如[0-9]
\D:比對任何非數字,如[^0-9]
\w:比對數字字母跟底線,如[A-Za-z0-9_]
\W:比對非數字字母跟底線,[^A-Za-Z0-9_]
\s:比對任一空白字元
\S:比對任一非空白次元
\n:比對換行符號,是否換行
\t:比對定位字元

範例:

[^A-Za-z0-9]          代表接受英文大小寫及數字以外的字串

[0-9A-Za-z]           代表英文大小寫及數字的字串

[^0-9]          代表數字以外的字串

[0-9]          代表數字的字串

[A-Za-z]            代表英文大小寫的字串

[A-Za-z0-9_]           代表大小寫英數及符號的字串

[^A-Z]           代表大寫英文字母以外的字串

[A-Z]          代表大寫英文字母的字串

{3,7}           代表三個至七個字元的字串

{5,}          代表五個以上的字串

^[A-C]{3}            開頭是大寫的英文字母且在A-C間,且有三個字元的字串    20241015

PHP foreach

第一種為 key 從 0 開始依序遞增的陣列,這時只需取得 value 即可

 foreach (array_name as $value)

foreach ($a as $i){  
     $sum +=$i;
}
echo "1+2+3+.....+99+100=".$sum."<br/>";
  • 第二種則是任意的 key-value 組合,此時需要兩個變數 $key 為 key 的值, $value 為 value 的值

 foreach (array_name as $key => $value)

$b = array(
       "one" => 1,
       "two" => 2,
       "three" => 3,
       "four" => 4
         );

foreach ($b as $key => $value){
    echo "{$key}: => {$value} <br/>"; 
}