strlen($string) מחזירה את אורך המחרוזת בבתים. לתווים, וזה מה שרוצים בטקסט יפני, באותיות עם סימנים דיאקריטיים ובאימוג'י, השתמשו ב-mb_strlen($string). בטקסט באנגלית פשוטה שתיהן נותנות אותו מספר.
רווחים, סימני פיסוק וירידות שורה נספרים כולם. strlen("a b\n") הוא 4.
בתים מול תווים ב-UTF-8
מחרוזות ב-PHP הן רצפים של בתים, ו-UTF-8 משתמש במספר שונה של בתים לכל תו: 1 לאותיות וספרות ASCII, 2 לאותיות כמו é או ж, 3 לקאנה, לקאנג'י נפוצים, לתווים סיניים ולסמלים כמו €, ו-4 לרוב האימוג'י ולקאנג'י נדירים כמו 𠮷. strlen() מחברת את הבתים; mb_strlen() סופרת את התווים.
השתמשו ב-strlen() כשבתים חשובים: עמודה במסד נתונים שמוגבלת בבתים, גודל קובץ, פרוטוקול בינארי. השתמשו ב-mb_strlen() לכל דבר שאדם קורא: מונה תווים, כלל של "עד 20 תווים", חיתוך טקסט עם mb_substr().
אימוג'י ותווים שבנויים מכמה נקודות קוד
mb_strlen() סופרת נקודות קוד של Unicode. חלק מהדברים שקורא רואה כתו אחד הם כמה נקודות קוד שמחוברות יחד: אימוג'י של משפחה, דגל, גוון עור, או אות ועוד סימן דיאקריטי משולב.
ספירה של מה שקורא רואה כתווים בודדים (צבירי גרפמות) דורשת את grapheme_strlen() מהרחבת intl:
echo grapheme_strlen('👨👩👧'); // 1
echo grapheme_strlen('🇯🇵'); // 1
למונה תווים בטופס ביפנית, mb_strlen() מספיקה בדרך כלל: כל קאנה וקאנג'י הוא נקודת קוד אחת.
רוחב תצוגה עם mb_strwidth
בטרמינל או בפריסה ברוחב קבוע, תו יפני ברוחב מלא תופס שתי עמודות בעוד קטקנה בחצי רוחב או אות לטינית תופסות אחת. mb_strwidth() מחזירה את הרוחב הזה, וזה מה שכללי "全角は2文字" ביפנית מתכוונים אליו בדרך כלל.
בדיקה אם מחרוזת ריקה
הבדיקה הברורה ביותר היא השוואה מחמירה ל-''. strlen($s) === 0 נותנת אותה תשובה. empty($s) אינה אותו הדבר: היא מחזירה true גם למחרוזת "0", שהיא תשובה תקינה בטפסים רבים.
מחרוזת של רווחים אינה ריקה. העבירו אותה קודם דרך trim() אם רווחים בלבד צריכים להיחשב כלום.
strlen(null) וערכים שאינם מחרוזות
strlen() מצפה למחרוזת. העברה של null עדיין מחזירה 0, אבל מאז PHP 8.1 היא מדפיסה הודעת deprecation:
Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /home/index.php on line 2
מערך זורק TypeError: strlen(): Argument #1 ($string) must be of type string, array given.
המירו את הערך או תנו לו ברירת מחדל קודם, למשל strlen($value ?? ''). מספרים שלמים מומרים למחרוזות, ולכן strlen(12345) הוא 5. כדי לספור איברי מערך, השתמשו ב-count().
אימות האורך של קלט משתמש
כלל טיפוסי: שם משתמש של 3 עד 16 תווים, אחרי trim. השתמשו ב-mb_strlen() כדי ששם ביפנית יימדד בתווים, לא בבתים.
עם strlen() במקום mb_strlen(), やまだたろう היה נספר כ-18 ונדחה כארוך מדי, למרות שיש בו שישה תווים.
שאלות נפוצות
איך מקבלים את האורך של מחרוזת ב-PHP?
strlen($s) מחזירה את מספר הבתים ו-mb_strlen($s) את מספר התווים. בטקסט באנגלית פשוטה הם שווים; ביפנית, באותיות עם סימנים דיאקריטיים או באימוג'י השתמשו ב-mb_strlen().
למה strlen() מחזירה אורך שגוי לטקסט ביפנית?
הוא לא שגוי, היא סופרת בתים. UTF-8 שומר קאנה וקאנג'י נפוצים ב-3 בתים כל אחד, ולכן strlen('日本語') הוא 9 בעוד mb_strlen('日本語') הוא 3.
איך סופרים את התווים של מחרוזת עם אימוג'י?
mb_strlen() סופרת נקודות קוד של Unicode, ולכן אימוג'י פשוט נספר כ-1, אבל אימוג'י שבנוי מכמה נקודות קוד (משפחה, דגל, גוון עור) נספר כיותר. grapheme_strlen() מהרחבת intl סופרת את מה שקורא רואה כתו אחד.
מה ההבדל בין strlen ל-count ב-PHP?
strlen() מודדת מחרוזת, count() סופרת את האיברים של מערך. העברה של מערך ל-strlen() זורקת TypeError ב-PHP 8.
איך בודקים אם מחרוזת ריקה ב-PHP?
השוו אותה למחרוזת ריקה: $s === '', או strlen($s) === 0. הימנעו מ-empty($s) לשם כך, כי היא מתייחסת גם למחרוזת "0" כריקה.