Menu

filter_var() ב-PHP: אימות אימייל, int, URL ועוד

filter_var($value, FILTER_VALIDATE_EMAIL) מחזירה את הערך אם הוא תקין ו-false אם לא; FILTER_VALIDATE_INT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL ו-FILTER_VALIDATE_IP עובדים באותה דרך. למדו את האפשרויות (min_range, default), הדגלים, מסנני הניקוי והמלכודת של false מול 0.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

filter_var($value, FILTER_VALIDATE_EMAIL) מחזירה את הערך כשהוא כתובת אימייל תקינה ו-false כשהוא לא. החליפו את המסנן כדי לבדוק פורמטים אחרים: FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL, FILTER_VALIDATE_IP. תמיד השוו את התוצאה עם === false.

שתי תוצאות מפתיעות אנשים. ada@example נדחית כי לדומיין אין נקודה, ו-' ada@example.com' נדחית בגלל הרווח המוביל, אז הפעילו trim() על הקלט לפני שאתם מאמתים אותו.

אימות אימייל מטופס

אותה בדיקה מאחורי טופס. הריצו את זה, הקלידו כתובת ולחצו על Check; הבלוק ירוץ שוב עם הקלט שלכם ב-$_POST.

FILTER_VALIDATE_EMAIL בודקת רק את הפורמט. nobody@example.com עוברת, וכך גם הייתה עוברת כתובת עם שגיאת הקלדה בדומיין. תווים שאינם ASCII נדחים: adä@example.com עוברת רק עם FILTER_FLAG_EMAIL_UNICODE, שמתיר אותם לפני ה-@, ודומיין כמו exämple.com נכשל גם עם הדגל אלא אם ממירים אותו קודם לצורת ה-xn-- שלו. הדרך היחידה לדעת שכתובת עובדת היא לשלוח אליה קישור אישור.

אימות מספר שלם עם min_range ו-max_range

FILTER_VALIDATE_INT הופך מחרוזת תקינה ל-int ודוחה כל השאר. מערך האפשרויות מוסיף טווח וברירת מחדל:

רווחים מסביב ו-+ מוביל מתקבלים, אפס מוביל ('042') לא, והתוצאה עבור '42' היא המספר השלם 42, לא המחרוזת. מחוץ לטווח נותן false; עם אפשרות default מקבלים את ברירת המחדל במקום false, וזה שימושי לדברים כמו ?page= (ראו GETו−_GET ו-_POST). הוסיפו FILTER_FLAG_ALLOW_HEX או FILTER_FLAG_ALLOW_OCTAL כדי לקבל 0x1A או 0755.

המלכודת של 0 ו-false

'0' תקין מחזיר את המספר השלם 0, ו-0 שקרי. if פשוט מתייחס אליו ככישלון:

אותו דבר חל על FILTER_VALIDATE_FLOAT ('0.0') ועל FILTER_VALIDATE_BOOL, שבו false היא תשובה תקינה. לזה נועד FILTER_NULL_ON_FAILURE.

בוליאנים, floats, כתובות URL וכתובות IP

FILTER_VALIDATE_BOOL הוא השם ב-PHP 8; FILTER_VALIDATE_BOOLEAN הוא אותו מסנן. בלי FILTER_NULL_ON_FAILURE, 'maybe' הייתה מחזירה false, שאי אפשר להבדיל אותו מ-'off'.

URL תקין אינו קישור בטוח

FILTER_VALIDATE_URL בודק שהמחרוזת בנויה כמו URL, עם כל סכמה. זה כולל סכמות שלעולם לא תרצו ב-href:

javascript://comment%0Aalert(1) עוברת את FILTER_VALIDATE_URL, ודפדפן מריץ אותה כ-JavaScript כשלוחצים על הקישור, כי %0A מסיים את ה-//comment. בדקו את הסכמה עם parse_url() לפני שאתם מדפיסים URL של משתמש לתוך דף. אפשר גם לדרוש חלקים עם FILTER_FLAG_PATH_REQUIRED ו-FILTER_FLAG_QUERY_REQUIRED.

מסנני ניקוי

מסנני ניקוי מסירים תווים במקום לומר כן או לא. הם שימושיים לנרמול קלט, לא להפיכתו לבטוח להדפסה:

הסתכלו על השורה הראשונה: Order #12-345 (x2) הופכת ל-12-3452, מספר שמעולם לא היה בקלט, והשורה השלישית היא כתובת שאף אחד לא הקליד. אם אתם מנקים, אמתו את התוצאה אחר כך. לכל דבר שאתם מדפיסים לתוך HTML, htmlspecialchars() בזמן הפלט היא הכלי הנכון (FILTER_SANITIZE_FULL_SPECIAL_CHARS עושה את אותו escape). FILTER_SANITIZE_STRING הוצא משימוש מאז PHP 8.1; ראו htmlspecialchars למה להשתמש במקומו.

אימות טופס שלם עם filter_var_array

filter_var_array() מפעילה מסנן אחד לכל מפתח ומחזירה מערך עם כל מפתח שביקשתם: הערך המסונן, false כשהאימות נכשל, או null כשהמפתח חסר.

role נעלם: מפתחות שלא רשמתם מושמטים, וזה מונע ממבקר להוסיף role=admin לטופס ולגרום לו להישמר. country הוא null כי הוא לא נשלח. בשרת web, filter_input_array(INPUT_POST, $rules) עושה את אותו הדבר וקוראת ישירות מהבקשה.

שאלות נפוצות

איך מאמתים כתובת אימייל ב-PHP?

השתמשו ב-filter_var($email, FILTER_VALIDATE_EMAIL), שמחזירה את מחרוזת האימייל אם היא תקינה ו-false אם לא: if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { /* invalid */ }. היא בודקת רק את הפורמט; כדי לדעת שהכתובת קיימת, שלחו אימייל אישור.

איך בודקים אם מחרוזת היא מספר שלם ב-PHP?

filter_var($s, FILTER_VALIDATE_INT) מחזירה את ה-int עבור "42", "-7" ו-" 42 ", ו-false עבור "4.2", "42abc" או "042". השוו עם !== false, כי "0" תקין מחזיר 0, שהוא שקרי.

למה filter_var מחזירה false עבור 0?

היא לא: filter_var('0', FILTER_VALIDATE_INT) מחזירה את המספר השלם 0. הבאג נמצא בבדיקה, if (filter_var(...)), שמתייחסת ל-0 כמו ל-false. כתבו if (filter_var($v, FILTER_VALIDATE_INT) !== false).

מה החליף את FILTER_SANITIZE_STRING ב-PHP 8.1?

שום דבר באופן ישיר; הוא הוצא משימוש כי השם שלו הבטיח בטיחות שהוא לא נתן. אמתו את הקלט שאתם מצפים לו, שמרו אותו כמו שהוא, ובצעו לו escape כשאתם מדפיסים אותו עם htmlspecialchars(). אם צריך להסיר תגיות, השתמשו ב-strip_tags().

מה ההבדל בין filter_var ל-filter_input?

filter_var() מסננת כל ערך שמעבירים לה. filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) קוראת ישירות מהבקשה המקורית, ולכן היא מחזירה null כשהפרמטר חסר ומתעלמת מכל שינוי שהקוד שלכם עשה ב-$_GET. שתיהן מקבלות את אותם מסננים ואפשרויות.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל