2013-11-20 85 views
3

使用PHP,我試圖確定在字符串諸如這些的長度(字符數):PHP的strlen()也不mb_strlen()返回意外的結果

1 
1.1 
1.1.1 
1.1.2 
1.1.3 
1.1.3.1 
1.1.3.2 
1.1.4 
1.1.5 
1.1.6 
1.1.7 

當這些字符串的長度與mb_strlen()或strlen的(),結果測得

------------------------------ 
value | mb_strlen() | strlen() 
------------------------------ 
1  | 1   | 1 
------------------------------ 
1.1  | 5   | 5 
------------------------------ 
1.1.1 | 9   | 9 
------------------------------ 
1.1.1.1 | 13   | 13 
------------------------------ 
1.1.1.2 | 13   | 13 
------------------------------ 
1.1.1.3 | 13   | 13 
------------------------------ 

看來,它的計數「」作爲3個字符?我想知道做一個小功能來彌補可預測的「錯誤」,但是我想知道爲什麼它要計算「」。作爲3個字符開頭。

mb_language('uni'); 
mb_internal_encoding('UTF-8'); 
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); 

是什麼讓:

我已經經歷了好幾個地方,包括this SO articleread the article mentioned,將建議轉換到頁面已經看了?

編輯: 字符串作爲csv導入的一部分導入。

這裏是代碼:

<? 
    $f = fopen("s2db.csv", "r"); 
    while (($line = fgetcsv($f)) !== false) { 

      $colcount = 0; 
      foreach ($line as $cell) { 
       //lets get the lines into variables first 
       //there only five, so just count 
       switch ($colcount) { 
        case '0': 
         $item = $cell; 
         break; 
        case '1': 
         $itemtitle = htmlspecialchars($cell); 
         break; 
        case '2': 
         $itemsubject = htmlspecialchars($cell); 
         break; 
        case '3': 
         $itemnumber = htmlspecialchars($cell); 
         break; 
        case '4': 
         $itemqty = htmlspecialchars($cell); 
         break; 
        case '5': 
         $itemfilename = htmlspecialchars($cell); 
         break;      
       } 
       $colcount++; 
      } 
      $itemlen = strlen($item); 
      echo "Value = " . $item . " | strlen() Length = " . $itemlen . "| mb_strlen() = " . mb_strlen($item) . "</br>"; 
    } 
?> 

這裏有結果

Value = 1 | strlen() Length = 3| mb_strlen() = 3 
Value = 1.1 | strlen() Length = 7| mb_strlen() = 7 
Value = 1.1.1 | strlen() Length = 11| mb_strlen() = 11 
Value = 1.1.1.1 | strlen() Length = 15| mb_strlen() = 15 
Value = 1.1.1.2 | strlen() Length = 15| mb_strlen() = 15 
Value = 1.1.1.3 | strlen() Length = 15| mb_strlen() = 15 
Value = 1.1.1.3.1 | strlen() Length = 19| mb_strlen() = 19 
Value = 1.1.1.3.2 | strlen() Length = 19| mb_strlen() = 19 
Value = 1.1.1.3.3 | strlen() Length = 19| mb_strlen() = 19 
Value = 1.1.1.4 | strlen() Length = 15| mb_strlen() = 15 

SOLUTION:

我給@因爲他hexdump都可以幫我確定我是不是hek2mgl投票瘋狂,它真的在數「。」作爲3,as shown here

什麼我可以做一下導入格式,所以我只是要添加代碼來補償:

感謝大家的幫助!

+1

什麼字符代碼,你點了? 'php -r'echo ord(「。」)的輸出是什麼?' –

+1

你所建議的代碼不是很有效 - 你沒有引用字符串,所以它們被作爲數字處理,並且所以他們無效。值得一提的是...... –

+0

要清楚的是,你的代碼的*輸出是'strlen(1.1.1.3.3)',但它實際上調用了那些帶有* string *參數的函數? – delnan

回答

3

我:

<?php 

$str = '1.1.1'; 
var_dump(mb_strlen($str, 'utf-8')); // 5 
var_dump(strlen($str));    // 5 

預期。在你的情況下,似乎.不是常規點,而是一個特殊的Unicode字符。請顯示您的輸入數據的十六進制轉儲。您可以使用Hexdump(我寫的包這樣的情況下):

安裝

sudo pear channel-discover www.metashock.de/pear 
sudo pear install metashock/Hexdump 

用法:

<?php 

require_once 'Hexdump.php'; 
hexdump('1.1.1'); 

將是有趣的,看看什麼是真正的字符在幕後。

+0

用於引用Hexdump的+1(具有適當的免責聲明= P) – Tivie

+0

第一:這是一個可愛的小包裝!以下是結果:http://pastebin.com/Barz1Y5P# – Edward

+0

是的,這是我想要的輸出! :) ..你會發現每個'.'前面都有一個'0'字節。你從哪裏得到字符串? – hek2mgl

0

沒有答案,只是想知道你的代碼,這似乎無效。

strlen預計字符串參數不是小數。

strlen(1.1) // 3 (here 1.1 is cast to string) 
strlen(1.1.1) // PHP Parse Error 
+0

不是答案應該是評論... –

+2

評論無法格式化不夠好... – marekful

+0

@MikeB不適合我,我跑了它。 – marekful

0

我知道這不是一個答案,但代碼格式的原因。

下,保存在UTF-8的文件,在我的設置...

<?php 

echo 'mbstring.internal_encoding: ' . ini_get('mbstring.internal_encoding') . "\r\n"; 
echo 'mbstring.func_overload: '  . ini_get('mbstring.func_overload') . "\r\n"; 
echo 'mbstring.language: '    . ini_get('mbstring.language') . "\r\n"; 
echo 'mbstring.strict_detection: '  . ini_get('mbstring.strict_detection') . "\r\n"; 
echo 'mbstring.substitute_character: ' . ini_get('mbstring.substitute_character') . "\r\n"; 
echo 'mbstring.detect_order: '   . ini_get('mbstring.detect_order') . "\r\n"; 
echo 'mbstring.encoding_translation: ' . ini_get('mbstring.encoding_translation') . "\r\n"; 
echo "\r\n"; 

function outputLengths($sString) { 
    echo("mb_strlen('$sString', 'utf-8') = " . mb_strlen($sString, 'utf-8') ."\r\n"); 
    echo("strlen('$sString') = " . strlen($sString) ."\r\n\r\n"); 
} 

outputLengths('1'); 
outputLengths('1.1'); 
outputLengths('1.1.1'); 
outputLengths('1.1.3.1'); 

輸出:

mbstring.internal_encoding: UTF-8 
mbstring.func_overload: 0 
mbstring.language: neutral 
mbstring.strict_detection: 0 
mbstring.substitute_character: 
mbstring.detect_order: 
mbstring.encoding_translation: 0 

mb_strlen('1', 'utf-8') = 1 
strlen('1') = 1 

mb_strlen('1.1', 'utf-8') = 3 
strlen('1.1') = 3 

mb_strlen('1.1.1', 'utf-8') = 5 
strlen('1.1.1') = 5 

mb_strlen('1.1.3.1', 'utf-8') = 7 
strlen('1.1.3.1') = 7 

您能得到什麼?

+0

將您的代碼複製並粘貼到我的系統中,可以獲得與您顯示的結果相同的結果。 – Edward

+0

聽起來像你在@ hek2mglm的右邊線,測試只是幫助確認答案的狀態 - 這是一個數據問題。所以我會離開這個線程。 –

0

你的變量來自哪裏? 你能告訴我們真正的代碼(而不是僞代碼)嗎?

我試圖重現所描述的行爲,不能。下面是一些測試我進行:

$strArray = array(
    '.', 
    '1', 
    '1.1', 
    '1.1.1', 
    1, 
    1.1, 
); 

for ($i = 0; $i<count($strArray); ++$i) { 
    print "{$strArray[$i]} -> strlen: ".strlen($strArray[$i])." <br/>"; 
    print "{$strArray[$i]} -> mb_strlen: ".mb_strlen($strArray[$i])." <br/>"; 
    print '<br>'; 
} 

此輸出:

. -> strlen: 1 
. -> mb_strlen: 1 

1 -> strlen: 1 
1 -> mb_strlen: 1 

1.1 -> strlen: 3 
1.1 -> mb_strlen: 3 

1.1.1 -> strlen: 5 
1.1.1 -> mb_strlen: 5 

1 -> strlen: 1 
1 -> mb_strlen: 1 

1.1 -> strlen: 3 
1.1 -> mb_strlen: 3 

預期