ویژگی تصویر

تابع setcookie() در PHP

  /  PHP   /  تابع setcookie() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع setcookie() یکی از ابزارهای اصلی برای ارسال کوکی از سمت سرور به مرورگر است. کوکی‌ها داده‌های کوچک متنی هستند که در مرورگر کاربر ذخیره می‌شوند و برای حفظ وضعیت (state)، احراز هویت ساده، پیگیری تنظیمات کاربری یا نگهداری اطلاعات غیرحساس کاربرد دارند. در این مقاله به صورت کامل پارامترها، نکات امنیتی، مثال‌های عملی و بهترین روش‌ها را بررسی می‌کنیم.

چه زمانی از کوکی استفاده کنیم و محدودیت‌ها

  • مناسب برای ذخیره‌سازی مقادیر کوچک (مانند شناسه غیرحساس، تنظیمات نمایش).
  • غیرمناسب برای ذخیره‌سازی اطلاعات حساس (رمزها، اطلاعات کارت بانکی).
  • هر کوکی معمولاً تا حدود 4KB حجم دارد و محدودیت تعداد کوکی‌ها به مرورگر بستگی دارد (معمولاً ~20-50).
  • کوکی‌ها به هر درخواست HTTP به سرور ارسال می‌شوند؛ نگهداری دادهٔ بزرگ باعث افزایش ترافیک می‌شود.

امضای تابع و پارامترها

نسخهٔ کلاسیک تابع:

bool setcookie ( string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )

از PHP 7.3 به بعد می‌توانید از آرایهٔ گزینه‌ها استفاده کنید:

setcookie(string $name, string $value = "", array $options = []): bool

پارامترهای اصلی:

پارامترتوضیح
nameنام کوکی (الزامی)
valueمقدار متن کوکی
expiresتایم‌استمپ یونیکس یا 0 برای کوکی نشست (session)
pathمسیر در دامنه که کوکی معتبر است (مثلاً / یا /app)
domainدامنه (برای اشتراک‌گذاری بین ساب‌دامنه‌ها از .example.com استفاده کنید)
secureارسال فقط از طریق HTTPS
httponlyدسترسی از طریق JavaScript را ممنوع می‌کند
SameSiteمحدودیت ارسال کوکی در درخواست‌های بین‌سایتی (Lax, Strict, None)

مثال پایه‌ای

<?php
// تنظیم یک کوکی ساده که 7 روز اعتبار دارد
setcookie('user_lang', 'fa', time() + 7*24*60*60, '/');
?>

این کد کوکی‌ای به نام user_lang با مقدار “fa” ایجاد می‌کند که برای کل مسیرهای دامنه معتبر است و به مدت 7 روز زنده می‌ماند. توجه کنید که setcookie() باید قبل از هر خروجی HTML اجرا شود زیرا هدرها باید ارسال شوند.

نسخهٔ مدرن با آرایهٔ options (توصیه‌شده)

<?php
setcookie('session_token', 'abc123', [
  'expires' => time() + 86400,
  'path' => '/',
  'domain' => '.example.com',
  'secure' => true,
  'httponly' => true,
  'samesite' => 'Lax' // 'Strict' | 'Lax' | 'None'
]);
?>

در این نمونه با استفاده از آرایهٔ options پارامترها به‌صورت مشخص و خواناتر تعیین شده‌اند. مقدار samesite کنترل می‌کند که آیا کوکی در درخواست‌های بین‌سایتی ارسال شود یا خیر. اگر از ‘None’ استفاده می‌کنید، باید secure برابر true باشد تا مرورگرهای جدید آن را قبول کنند.

خواندن و پاک‌سازی کوکی

<?php
// خواندن
if (isset($_COOKIE['user_lang'])) {
    $lang = $_COOKIE['user_lang'];
}

// حذف کوکی (ارسال مقدار خالی و تاریخ گذشته)
setcookie('user_lang', '', time() - 3600, '/');
?>

برای حذف کوکی، باید همان نام، path و domain را استفاده کنید و زمان منقضی در گذشته قرار دهید؛ در غیر این صورت ممکن است کوکی حذف نشود.

وقوع خطاها و نکات عملی

  • خطای معمول: “Headers already sent” — حتماً setcookie را قبل از هر خروجی اجرا کنید یا از buffering استفاده کنید.
  • اگر نیاز به ذخیره داده پیچیده دارید، از JSON یا رمزنگاری استفاده کنید؛ اما اندازه را کنترل کنید.
  • همیشه دادهٔ حساس را در کوکی ذخیره نکنید؛ به‌جای آن از توکن‌های کوتاه و بررسی سمت سرور (مثلاً session id) استفاده کنید.
  • برای ارسال مقادیر که ممکن است شامل کاراکترهای خاص باشند از urlencode/urldecode یا setrawcookie استفاده کنید.

مثال: ذخیره‌سازی داده ساختاریافته با رمزنگاری

<?php
// رمزنگاری ساده (مثال آموزشی، در تولید از روش‌های قوی‌تر استفاده کنید)
$key = 'secretkey123';
$data = ['id' => 42, 'role' => 'editor'];
$payload = base64_encode(json_encode($data));
$signature = hash_hmac('sha256', $payload, $key);
$value = $payload . '.' . $signature;

setcookie('user_info', $value, [
  'expires' => time() + 3600,
  'path' => '/',
  'httponly' => true,
  'secure' => true,
  'samesite' => 'Lax'
]);
?>

در این قطعه ابتدا آرایه را JSON کرده و Base64 گرفته می‌شود؛ سپس با HMAC امضا می‌شود. در سمت سرور هنگام خواندن، امضا بررسی می‌شود تا از تغییر غیرمجاز جلوگیری شود. توجه داشته باشید که این روش برای آموزش است—برای امنیت واقعی از کتابخانه‌های معتبر و الگوریتم‌های مدیریت کلید استفاده کنید.

SameSite و مسائل مربوط به cross-site

از سال‌های اخیر مرورگرها رفتار پیش‌فرض کوکی‌ها را سخت‌گیرانه‌تر کرده‌اند. مقادیر مرسوم:

  • Strict: کوکی در درخواست‌های بین‌سایتی ارسال نمی‌شود.
  • Lax: در برخی شرایط (مثلاً GET لینک بالای سطح) ارسال می‌شود و برای احراز هویت ساده مناسب است.
  • None: کوکی همیشه ارسال می‌شود، اما باید همراه با secure=true باشد.

مقایسه setcookie با header(‘Set-Cookie’)

می‌توانید هدر Set-Cookie را دستی با header() ارسال کنید اما setcookie() راحتی و تولید خودکار فرمت صحیح و برخی اعتبارسنجی‌ها را فراهم می‌کند. استفاده از آرایهٔ options خوانایی و ایمنی را بالا می‌برد.

بهترین روش‌ها (Best Practices)

  • همیشه HttpOnly را فعال کنید مگر زمانی که واقعاً نیاز به دسترسی JavaScript دارید.
  • برای تولید توکن‌ها از توابع امن مانند random_bytes و bin2hex استفاده کنید.
  • اطمینان حاصل کنید که کوکی‌های مهم فقط از طریق HTTPS ارسال شوند (secure=true).
  • از نگهداری دادهٔ حساس در کوکی خودداری کنید؛ به‌جای آن از شناسهٔ تصادفی و ذخیرهٔ داده روی سرور استفاده کنید.
  • برای اشتراک بین ساب‌دامنه‌ها از domain=’.example.com’ استفاده کنید.

خلاصه

تابع setcookie() ابزار ساده اما قدرتمندی برای مدیریت وضعیت در وب است. رعایت نکات امنیتی (HttpOnly، Secure، SameSite)، محدودیت‌های اندازه و فراخوانی پیش از خروجی نتیجهٔ ایمن‌تر و پایدارتر خواهد داشت. در پروژه‌های تولیدی از الگوهای امن برای رمزنگاری و مدیریت توکن‌ها بهره ببرید و کوکی‌ها را فقط برای اطلاعات غیرحساس یا شناسه‌های کوتاه استفاده کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: