Undefined offset 13错误排查及UTF-8兼容数字千分位格式化函数求助
Hey there! Let's break down the two problems you're facing with your thousand separator function: the UTF-8 incompatibility and that frustrating Undefined offset 13 error.
First: Fixing the Undefined Offset 13 Error
That error pops up (usually in PHP) when you try to access an array or string index that doesn't exist—here, index 13 is out of bounds for your input. Here's how to track it down:
- Pinpoint the error line: Check the "Function Location" in your error message—it leads straight to the line where you're accessing an invalid index. Most often, this happens from hardcoding an index (like
$charArray[13]) or miscalculating offsets when processing the string (e.g., assuming the input is longer than it actually is). - Validate dynamic length handling: If your function builds the formatted string by counting from the end, always use the actual character length of the input (via
mb_strlen) instead of fixed numbers. This ensures you never try to access an index that doesn't exist.
Second: Making It Work with UTF-8
The original UTF-8 issue almost certainly stems from using byte-based string functions (like str_split, substr, strlen) instead of multi-byte-aware alternatives. UTF-8 characters (like accented digits or non-Latin numerals) take up multiple bytes, so byte-based tools will mangle them. Fix this by:
- Replacing
strlenwithmb_strlen(counts actual characters, not bytes) - Replacing
substrwithmb_substr(extracts characters without breaking multi-byte sequences) - Replacing
str_splitwithmb_str_split(splits strings into character arrays, not byte arrays)
Example Fixed Function
Here's a robust version that handles both UTF-8 correctly and avoids offset errors:
function formatToThousands($numberStr) { // Optional: Strip non-digit characters (adjust if you need to keep symbols like - or .) $cleanNumber = preg_replace('/[^\p{N}]/u', '', $numberStr); $charCount = mb_strlen($cleanNumber); $formatted = ''; $counter = 0; // Traverse the string from right to left for ($i = $charCount - 1; $i >= 0; $i--) { $formatted = mb_substr($cleanNumber, $i, 1) . $formatted; $counter++; // Add comma every 3 characters, except at the start of the string if ($counter % 3 === 0 && $i !== 0) { $formatted = ',' . $formatted; } } return $formatted; }
- The
preg_replacewith/[^\p{N}]/usafely removes non-digit characters while respecting UTF-8 encoding. - All string operations use
mb_*functions to handle multi-byte characters without corruption. - The loop adapts dynamically to the input's length, so no out-of-bounds index accesses will occur.
Final Checks
- Test edge cases: Empty strings, numbers shorter than 3 characters, and strings with UTF-8 digits (e.g., "۱۲۳۴۵۶۷" which is Persian for 1234567) to confirm everything works as expected.
- Double-check the line in your original code that triggered the offset error—if it uses a hardcoded index like
$str[13], replace it with a calculation based on the input's actual length.
内容的提问来源于stack exchange,提问作者Omid

