Menu

strlen() trong PHP: độ dài chuỗi theo byte và ký tự

strlen($string) trả về độ dài chuỗi tính theo byte; mb_strlen($string) trả về độ dài tính theo ký tự. Tìm hiểu vì sao chữ có dấu, tiếng Nhật và emoji cho kết quả khác nhau, cách kiểm tra chuỗi rỗng và cách kiểm tra độ dài dữ liệu nhập vào.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

strlen($string) trả về độ dài của chuỗi tính theo byte. Để đếm theo ký tự, điều bạn thật sự cần với tiếng Nhật, chữ có dấu và emoji, hãy dùng mb_strlen($string). Với văn bản tiếng Anh thông thường, hai hàm cho cùng một con số.

Khoảng trắng, dấu câu và ký tự xuống dòng đều được tính. strlen("a b\n") là 4.

Byte và ký tự trong UTF-8

Chuỗi PHP là một dãy byte, và UTF-8 dùng số byte khác nhau cho mỗi ký tự: 1 byte cho chữ cái và chữ số ASCII, 2 byte cho các chữ như é hay ж, 3 byte cho kana, kanji thông dụng, chữ Hán và các ký hiệu như €, và 4 byte cho phần lớn emoji cùng các chữ kanji hiếm như 𠮷. strlen() cộng số byte; mb_strlen() đếm số ký tự. Công cụ chuyển văn bản sang nhị phân cho bạn thấy các byte nằm sau bất kỳ chuỗi nào.

Dùng strlen() khi số byte là điều quan trọng: một cột cơ sở dữ liệu giới hạn theo byte, kích thước tệp, một giao thức nhị phân. Dùng mb_strlen() cho mọi thứ con người đọc: bộ đếm ký tự, quy tắc "tối đa 20 ký tự", cắt văn bản bằng mb_substr().

Emoji và ký tự ghép từ nhiều code point

mb_strlen() đếm code point Unicode. Một số thứ người đọc thấy là một ký tự thực ra là nhiều code point ghép lại: emoji gia đình, lá cờ, màu da, hoặc một chữ cái cộng với dấu thanh ghép (combining accent).

Muốn đếm những gì người đọc thấy là một ký tự (grapheme cluster), bạn cần grapheme_strlen() trong extension intl:

echo grapheme_strlen('👨‍👩‍👧');   // 1
echo grapheme_strlen('🇯🇵');     // 1

Với bộ đếm ký tự trên một form tiếng Nhật, mb_strlen() thường là đủ: mỗi chữ kana và kanji là một code point.

Độ rộng hiển thị với mb_strwidth

Trên terminal hoặc trong bố cục có độ rộng cố định, một ký tự tiếng Nhật toàn khổ (full-width) chiếm hai cột, còn katakana nửa khổ hoặc chữ Latin chiếm một cột. mb_strwidth() trả về độ rộng đó, cũng là điều mà quy tắc "全角は2文字" của người Nhật thường muốn nói.

Kiểm tra chuỗi rỗng

Cách kiểm tra rõ ràng nhất là so sánh nghiêm ngặt với ''. strlen($s) === 0 cho cùng kết quả. empty($s) thì khác: hàm này cũng trả về true với chuỗi "0", vốn là một câu trả lời hợp lệ trong nhiều form.

Một chuỗi chỉ toàn khoảng trắng không phải là chuỗi rỗng. Hãy cho nó qua trim() trước nếu chỉ có khoảng trắng thì cũng phải tính là không có gì.

strlen(null) và giá trị không phải chuỗi

strlen() cần một chuỗi. Truyền null vẫn trả về 0, nhưng từ PHP 8.1 sẽ có thông báo deprecation:

Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /home/index.php on line 2

Một mảng sẽ ném ra TypeError: strlen(): Argument #1 ($string) must be of type string, array given.

Hãy ép kiểu hoặc gán giá trị mặc định trước, ví dụ strlen($value ?? ''). Số nguyên được chuyển thành chuỗi, nên strlen(12345) là 5. Để đếm phần tử của mảng, dùng count().

Kiểm tra độ dài dữ liệu người dùng nhập

Một quy tắc điển hình: tên người dùng dài từ 3 đến 16 ký tự, sau khi đã trim. Dùng mb_strlen() để tên tiếng Nhật được đo theo ký tự, không phải theo byte.

Nếu dùng strlen() thay cho mb_strlen(), やまだたろう sẽ được tính là 18 và bị từ chối vì quá dài, dù nó chỉ có sáu ký tự.

Câu hỏi thường gặp

Làm sao để lấy độ dài chuỗi trong PHP?

strlen($s) trả về số byte, còn mb_strlen($s) trả về số ký tự. Với văn bản tiếng Anh thông thường, hai kết quả bằng nhau; với tiếng Nhật, chữ có dấu hoặc emoji, hãy dùng mb_strlen().

Vì sao strlen() trả về độ dài sai với văn bản tiếng Nhật?

Kết quả không sai, hàm này đếm byte. UTF-8 lưu mỗi chữ kana và chữ kanji thông dụng bằng 3 byte, nên strlen('日本語') là 9 trong khi mb_strlen('日本語') là 3.

Làm sao để đếm ký tự của một chuỗi có emoji?

mb_strlen() đếm code point Unicode, nên một emoji đơn giản được tính là 1, nhưng emoji ghép từ nhiều code point (gia đình, lá cờ, màu da) được tính nhiều hơn. grapheme_strlen() trong extension intl đếm đúng những gì người đọc thấy là một ký tự.

strlen và count trong PHP khác nhau thế nào?

strlen() đo độ dài một chuỗi, còn count() đếm số phần tử của một mảng. Truyền một mảng vào strlen() sẽ ném ra TypeError trong PHP 8.

Làm sao để kiểm tra chuỗi rỗng trong PHP?

So sánh với chuỗi rỗng: $s === '', hoặc strlen($s) === 0. Tránh dùng empty($s) cho việc này, vì nó cũng coi chuỗi "0" là rỗng.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu