در این صفحه
قانونهای اعتبارسنجی#
بعد از نصب بسته (راهاندازی Laravel)، شش قانون در دسترس است (با هفت نام، چون mobile نام کوتاه iran_mobile است). آنها را در هر validator، form request یا $request->validate() میتوانید بنویسید. هر قانون یکی از اعتبارسنجهای توضیحدادهشده در صفحههای اعتبارسنجی است.
| قانون | چه چیزی را قبول میکند | جزئیات |
|---|---|---|
national_code | کد ملی ایران | کد ملی |
sheba | شبا / IBAN، با IR یا بدون آن | شبا و کارت بانکی |
bank_card | شمارهٔ کارت بانکی ۱۶ رقمی (بررسی Luhn) | شبا و کارت بانکی |
iran_mobile | شمارهٔ موبایل ایران | موبایل، کدپستی، پلاک |
mobile | نام کوتاه iran_mobile | رفتار یکسان |
postal_code | کدپستی ۱۰ رقمی ایران | موبایل، کدپستی، پلاک |
vehicle_plate | پلاک خودروی ایران، مثلاً 12ب345-67 | موبایل، کدپستی، پلاک |
mobile اسم عمومی است. اگر بستهٔ دیگری یا کد خودتان قانونی با همین نام ثبت کند، همهجا iran_mobile را بنویسید تا اشتباه نشود.استفاده#
use Illuminate\Http\Request;
public function store(Request $request)
{
$data = $request->validate([
'national_code' => 'required|national_code',
'mobile' => 'required|iran_mobile',
'card' => 'nullable|bank_card',
'iban' => 'nullable|sheba',
'postal' => 'required|postal_code',
'plate' => 'nullable|vehicle_plate',
]);
}
اجرای واقعی با دادههای نادرست و زبان fa این نتیجه را داد:
// national_code = '1234567890'، mobile = '0912'، iban = 'IR000000000000000000000000'
// card و postal و plate درستاند و رد نمیشوند.
//
// national_code: national code کد ملی معتبر نیست.
// mobile: mobile شماره موبایل معتبر نیست.
// iban: iban شماره شبا معتبر نیست.
متن انگلیسی «The national code is not a valid Iranian national code.» است و متن عربی هم هست. ترجمهها و عوض کردن پیامها را ببینید.
چه ورودیای قبول میشود#
- رشته. رقمهای فارسی و عربی قبول میشوند.
۰۰۱۳۵۴۲۴۱۹قانونnational_codeرا رد میکند و میگذراند. - عدد صحیح و اعشاری اول به رشته تبدیل میشود. مراقب عددهایی باشید که با صفر شروع میشوند. عدد JSON با مقدار
13542419صفرهای اول0013542419را از دست داده و رد میشود. کد ملی، موبایل و کدپستی را رشته بفرستید. - آرایه، شیء و بولی به اعتبارسنج نمیرسند و قانون را رد میکنند.
- مقدار خالی. مثل قانونهای خود Laravel، رشتهٔ خالی و کلید غایب نادیده گرفته میشود، مگر فیلد
requiredباشد. مقدار صریحnullرد میشود، مگر فیلدnullableباشد. باrequiredیاnullableمنظورتان را روشن کنید.
$f->make(['n' => '۰۰۱۳۵۴۲۴۱۹'], ['n' => 'national_code'])->passes(); // true
$f->make(['n' => 13542419], ['n' => 'national_code'])->passes(); // false (صفرهای اول از دست رفته)
$f->make(['n' => null], ['n' => 'nullable|national_code'])->passes(); // true
$f->make(['n' => null], ['n' => 'national_code'])->passes(); // false
$f->make(['n' => ''], ['n' => 'national_code'])->passes(); // true (نادیده گرفته میشود)
$f->make(['n' => ''], ['n' => 'required|national_code'])->passes(); // false
$f->make([], ['n' => 'national_code'])->passes(); // true (کلید غایب)
اگر دلیل رد شدن را هم میخواهید (طول نادرست، رقم کنترل غلط، نوع نادرست)، خود اعتبارسنج را صدا بزنید که Result کامل میدهد. مرور اعتبارسنجها را ببینید.
cast در Eloquent با JalaliCast#
کلاس RtlyKit\Laravel\Casts\JalaliCast ستون پایگاه داده را میلادی (Y-m-d H:i:s) نگه میدارد، همانطور که همهٔ ابزارها انتظار دارند. در مدل، مقدار را به شکل یک شیء تغییرناپذیر RtlyKit\Calendar\Jalali نشان میدهد.
use Illuminate\Database\Eloquent\Model;
use RtlyKit\Laravel\Casts\JalaliCast;
class Post extends Model
{
protected $guarded = [];
protected $casts = [
'published_at' => JalaliCast::class,
];
}
$post = new Post();
$post->published_at = '1404/01/15 10:30';
echo $post->getAttributes()['published_at']; // 2025-04-04 10:30:00 (مقدار ذخیرهشده)
echo $post->published_at->format('Y/m/d H:i'); // 1404/01/15 10:30
echo get_class($post->published_at); // RtlyKit\Calendar\Jalali
echo $post->published_at->addDays(20)->format('Y/m/d'); // 1404/02/04
نوع ستون همان datetime یا timestamp میماند و migration عوض نمیشود.
مقدارهایی که میشود نوشت#
| مقداری که مینویسید | مقدار ذخیرهشده (میلادی) |
|---|---|
رشتهٔ جلالی '1404/01/15 10:30' | 2025-04-04 10:30:00 |
فقط تاریخ جلالی با رقم فارسی و خط تیره '۱۴۰۴-۰۱-۱۵' | 2025-04-04 00:00:00 |
رشتهٔ میلادی '2025-04-04 08:00:00' | 2025-04-04 08:00:00 |
زمان یونیکس (عدد صحیح) 1743753600 | 2025-04-04 08:00:00 (با منطقهٔ زمانی پیشفرض UTC) |
هر DateTimeInterface (از جمله Carbon) | همان لحظه، به شکل Y-m-d H:i:s |
شیء Jalali | معادل میلادی آن |
null یا '' | null |
رشتهای جلالی حساب میشود که سالش بین ۱۲۰۰ و ۱۵۹۹ باشد و جداکنندهاش / یا -، با ساعت اختیاری HH:MM یا HH:MM:SS بعد از فاصله یا T. بقیهٔ رشتهها مثل تاریخ میلادی خوانده میشوند.
خطاها#
ورودی نادرست موقع نوشتن RtlyKit\Exceptions\InvalidDateException میدهد، نه خطای خام PHP:
$post->published_at = '1404/13/01'; // Invalid Jalali date: 1404/13/1
$post->published_at = '1404/07/31'; // Invalid Jalali date: 1404/7/31 (مهر ۳۰ روز دارد)
$post->published_at = 'not a date'; // Unable to parse date: not a date
$post->published_at = 1.5; // Cannot cast value for 'published_at' to a date.
$post->published_at = ['x']; // Cannot cast value for 'published_at' to a date.
ورودی کاربر را قبل از رسیدن به مدل اعتبارسنجی کنید (مثال form request پایینتر است) تا اشتباه تایپی خطای فرم بدهد، نه استثنا. خواندن برای null و رشتهٔ خالی راحتگیر است (هر دو null میدهند). ولی اگر در پایگاه داده متنی باشد که خوانده نمیشود، خواندن ویژگی InvalidDateException میدهد.
تبدیل مدل به JSON#
کلاسهای Jalali و Hijri و Hebrew JsonSerializable هستند. در مدلی که JalaliCast دارد، toJson() همان (string) $date را میدهد، مثلاً {"published_at":"1404/01/01 10:00:00"}. toArray() خود شیء Jalali را نگه میدارد. اگر شکل دیگری میخواهید، خودتان قالببندی کنید.
form request#
قانون آمادهای برای فیلد تاریخ جلالی نیست. شکل را با قانون regex خود Laravel یا یک قانون کوچک دلخواه بررسی کنید و تبدیل را به cast بسپارید:
public function rules(): array
{
return [
'published_at' => ['required', 'regex:/^1[2-5]\d\d[\/-]\d{1,2}[\/-]\d{1,2}$/u'],
];
}
این الگو 1404/01/15 و 1404-1-5 را میگذراند و 2025/01/01 و abc را رد میکند. تاریخی که شکلش درست است ولی وجود ندارد، مثل 1404/07/31، به cast میرسد و همانجا خطا میدهد. اگر کاربر متن آزاد مینویسد، InvalidDateException را در یک قانون دلخواه یا در controller بگیرید.
Blade#
cast یک شیء Jalali میدهد. پس در Blade به تابع کمکی نیازی نیست:
{{ $post->published_at?->format('Y/m/d') }} {{-- 1404/01/15 --}}
{{ $post->published_at?->format('l j F Y') }} {{-- جمعه 15 فروردین 1404 --}}
{{ \RtlyKit\to_persian_digits($post->published_at->format('Y/m/d')) }} {{-- ۱۴۰۴/۰۱/۱۵ --}}
برای ستونی که cast ندارد، مثل created_at معمولی (یک Carbon)، از تابع فضاینامدار استفاده کنید. این توابع همیشه بارگذاری میشوند و ثبتنام نمیخواهند:
{{ \RtlyKit\jdate($post->created_at)->format('Y/m/d H:i') }} {{-- 1404/01/15 08:00 --}}
اگر زیاد به کار میبرید، بالای فایل Blade با @php use function RtlyKit\jdate; @endphp واردش کنید. با ماکروهای Carbon همین کار $post->created_at->jformat('Y/m/d') است. ماکروهای Carbon را ببینید.
null باشد خودکار قالببندی نمیشود. مثل بالا از ?-> استفاده کنید، وگرنه Blade روی null خطا میدهد. فهرست کامل توکنهای قالب در تقویم جلالی است.