سطح C: اعتبارسنجی مدرن (PHP Filter)

تا اینجا، ما اعتبارسنجی‌های ساده‌ای (خالی نبودن، عددی بودن) را یاد گرفتیم. اما اگر بخواهیم یک «ایمیل» را اعتبارسنجی کنیم چه؟

چک کردن اینکه آیا @ وجود دارد؟ کافی نیست. (a@b هم @ دارد!). چک کردن با عبارات باقاعده (Regex)؟ بسیار پیچیده و مستعد خطا است.

خوشبختانه، PHP یک افزونه داخلی و بسیار قدرتمند به نام **Filter Extension** دارد که برای همین کارها ساخته شده است.

محتوای آموزشی

۱. تابع filter_var()

این تابع، قلب تپنده افزونه فیلتر است. این تابع یک متغیر و یک «نوع فیلتر» را می‌گیرد و به ما می‌گوید آیا متغیر با آن فیلتر مطابقت دارد یا نه.

filter_var($variable, $filter_type, $options);

۲. فیلترهای اعتبارسنجی (Validate Filters)

این فیلترها داده را «بررسی» می‌کنند و در صورت موفقیت، خود داده را برمی‌گردانند، و در صورت شکست، false برمی‌گردانند.

مثال ۱: اعتبارسنجی ایمیل (FILTER_VALIDATE_EMAIL)

این فیلتر بررسی می‌کند که آیا رشته، فرمت یک ایمیل استاندارد را دارد یا خیر.

$email = "info@corepro.ir";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "این ایمیل معتبر است.";
} else {
    echo "این ایمیل معتبر نیست.";
}

// مثال‌های دیگر:
filter_var("test@test", FILTER_VALIDATE_EMAIL);      // false (دامنه معتبر نیست)
filter_var("test@test.com", FILTER_VALIDATE_EMAIL);  // true
filter_var("test.com", FILTER_VALIDATE_EMAIL);       // false

مثال ۲: اعتبارسنجی عدد صحیح (FILTER_VALIDATE_INT)

این فیلتر از is_numeric() «سخت‌گیرتر» است. is_numeric() عدد "123.45" را می‌پذیرد، اما FILTER_VALIDATE_INT آن را رد می‌کند، چون عدد صحیح (Integer) نیست.

filter_var(123, FILTER_VALIDATE_INT);      // 123 (موفق)
filter_var("123", FILTER_VALIDATE_INT);     // 123 (موفق)
filter_var("123.45", FILTER_VALIDATE_INT);  // false
filter_var("123a", FILTER_VALIDATE_INT);    // false

فیلترهای بسیار دیگری هم وجود دارند: FILTER_VALIDATE_IP, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOLEAN و...

۳. معرفی filter_input() (روشی امن‌تر)

روشی که ما تا الان استفاده می‌کردیم، دو مرحله‌ای بود: اول $_POST['name'] را می‌خواندیم، بعد اعتبارسنجی می‌کردیم.

PHP یک روش امن‌تر و یک مرحله‌ای هم ارائه می‌دهد: filter_input(). این تابع مستقیماً به سراغ ورودی‌های POST یا GET می‌رود، آن‌ها را می‌خواند و همزمان فیلتر می‌کند.

// روش قدیمی (خوب):
$email = $_POST['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) { ... }

// روش مدرن (امن‌تر):
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
    // ایمیل معتبر نبود
}

filter_input() امن‌تر است چون مستقیماً با داده‌های خام ورودی کار می‌کند و از آلوده شدن متغیر $_POST جلوگیری می‌کند. فعلاً ما با filter_var() ادامه می‌دهیم، اما خوب است که از وجود filter_input() اطلاع داشته باشید.


کارگاه عملی: فرم اعتبارسنجی ایمیل

بیایید یک فرم خودپردازش بسازیم که ایمیل کاربر را می‌گیرد و با filter_var آن را اعتبارسنجی می‌کند.

<?php
$message = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    
    $email_from_form = trim($_POST['email']);

    // گام ۱: اول چک می‌کنیم خالی نباشد (سطح A)
    if (empty($email_from_form)) {
        $message = "<div class='alert alert-danger'>فیلد ایمیل اجباری است.</div>";
    
    // گام ۲: اگر خالی نبود، فرمت آن را چک می‌کنیم (سطح C)
    } elseif (filter_var($email_from_form, FILTER_VALIDATE_EMAIL) === false) {
        $message = "<div class='alert alert-danger'>فرمت ایمیل وارد شده معتبر نیست.</div>";
    
    } else {
        // گام ۳: اگر معتبر بود، برای چاپ امنش می‌کنیم (سطح B)
        $safe_email = htmlspecialchars($email_from_form);
        $message = "<div class='alert alert-success'>ایمیل شما (" . $safe_email . ") با موفقیت ثبت شد.</div>";
    }
}
?>

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<!-- ... بخش head ... -->
<body>
    <div class="container">
        <h2>فرم اعتبارسنجی ایمیل (سطح C)</h2>
        
        <?php echo $message; ?>

        <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST">
            <label for="email">ایمیل شما:</label>
            <input type="email" id="email" name="email" class="form-control" style="direction: ltr;">
            <button type="submit" class="btn btn-primary mt-2">بررسی</button>
        </form>
    </div>
</body>
</html>

تحلیل: ما در این کد، هر سه سطح را ترکیب کردیم: اول با empty (سطح A) چک کردیم، سپس با filter_var (سطح C) اعتبارسنجی کردیم، و در نهایت با htmlspecialchars (سطح B) آن را برای چاپ امن کردیم. این یک نمونه عالی از اعتبارسنجی چندلایه است.


تمرین شما

صورت تمرین: فرم ثبت‌نام پیشرفته

یک فرم خودپردازش (advanced_register.php) بسازید که سه فیلد دارد:

  1. نام کاربری (username)
  2. ایمیل (email)
  3. سن (age)

منطق PHP شما باید این موارد را **به ترتیب** بررسی کند و به محض برخورد با اولین خطا، متوقف شده و پیام مناسب را نشان دهد:

  1. چک کند که **هر سه فیلد** empty() (بعد از trim()) نباشند. (پیام: "همه فیلدها اجباری هستند.")
  2. چک کند که فیلد email با FILTER_VALIDATE_EMAIL معتبر باشد. (پیام: "فرمت ایمیل اشتباه است.")
  3. چک کند که فیلد age با FILTER_VALIDATE_INT معتبر باشد. (پیام: "سن باید یک عدد صحیح باشد.")
  4. اگر همه موارد درست بود، پیام موفقیت (شامل هر سه متغیر امن‌شده با htmlspecialchars) را چاپ کند.

باشگاه ذهن: فیلترها با آپشن

چالش شما: فیلتر FILTER_VALIDATE_INT عالی است، اما اگر بخواهیم مطمئن شویم که سن کاربر «بین ۱۸ تا ۶۵» است چه؟

تابع filter_var() یک پارامتر سوم به نام $options می‌پذیرد. این پارامتر به ما اجازه می‌دهد تا برای فیلترها «قوانین اضافی» تعریف کنیم، مانند حداقل یا حداکثر محدوده.

وظیفه: یک پرامپت برای هوش مصنوعی بنویسید و از او بخواهید:

  1. توضیح دهد که چگونه می‌توان به تابع filter_var() آپشن‌ها (Options) را در قالب یک آرایه پاس داد.
  2. یک قطعه کد PHP بنویسد که متغیر $age = 25 را دریافت کند و با استفاده از filter_var()، FILTER_VALIDATE_INT و آرایه آپشن‌ها، بررسی کند که آیا این متغیر یک عدد صحیح **و** در محدوده min_range = 18 و max_range = 65 قرار دارد یا خیر.
  3. از او بخواهید نشان دهد که خروجی کد برای ورودی 17، 25 و "abc" چه خواهد بود.