فصل هفتم - جمع آوری و پردازش داده های کاربران
جمع آوری و پردازش داده های کاربران
وبسایتهایی که از فریمورکی مثل لاراول استفاده میکنند، معمولاً فقط محتوای ایستا ارائه نمیدهند. خیلی از آنها با منابع دادهای پیچیده و متنوع سروکار دارند. یکی از رایجترین (و البته پیچیدهترین) این منابع، ورودی کاربر در شکلهای مختلف آن است: مسیرهای URL، پارامترهای query، دادههای POST و فایلهایی که کاربران آپلود میکنند.
لاراول مجموعهای از ابزارها را برای جمعآوری، اعتبارسنجی، نرمالسازی و فیلتر کردن دادههایی که کاربران وارد میکنند فراهم کرده است. در اینجا به بررسی آنها میپردازیم.
تزریق شی Request
رایجترین ابزار برای دسترسی به دادههای کاربر در Laravel، تزریق نمونهای از شی Illuminate\Http\Request است. این شی دسترسی آسانی به تمام روشهایی که کاربران میتوانند اطلاعات ارسال کنند فراهم میکند: دادههای فرم POST یا JSON، درخواستهای GET (پارامترهای کوئری) و بخشهای URL.
گزینههای دیگر برای دسترسی به دادهی درخواست همچنین یک هلپر سراسری به نام request() و یک facade به نام Request وجود دارد که هر دو همین متدها را ارائه میدهند. هرکدام از این گزینهها شی کامل Illuminate Request را در اختیار شما قرار میدهند، اما فعلاً فقط متدهایی را بررسی میکنیم که مشخصاً مربوط به دادههای کاربر هستند. |
از آنجا که قصد داریم شی Request را تزریق کنیم، بیایید سریع ببینیم چطور میتوانیم به شی $request که این متدها را روی آن صدا میزنیم، دسترسی داشته باشیم:
Route::post('form', function (Illuminate\Http\Request $request) {
// $request->etc()
});
$request->all()
همانطور که از اسمش پیداست، $request->all() آرایهای شامل تمام ورودیهایی که کاربر ارائه کرده است را، از تمام منابع، برمیگرداند. فرض کنید به هر دلیلی تصمیم گرفتهاید یک فرم را به URLای با یک پارامتر کوئری ارسال کنید — مثلاً یک POST به http://myapp.com/signup?utm=12345. به مثال 7-1 نگاه کنید تا ببینید خروجی $request->all() چه خواهد بود. (توجه داشته باشید که $request->all() همچنین شامل اطلاعاتی دربارهی فایلهای آپلود شده نیز هست، ولی آن را بعداً در همین فصل بررسی خواهیم کرد.)
مثال 7-1. $request->all()
<!-- GET route form view at /get-route -->
<form method="post" action="/signup?utm=12345">
@csrf
<input type="text" name="first_name">
<input type="submit">
</form>
// routes/web.php
Route::post('signup', function (Request $request) {
var_dump($request->all());
});
// Outputs:
/**
* [
* '_token' => 'CSRF token here',
* 'first_name' => 'value',
* 'utm' => 12345,
* ]
*/
$request->except() و $request->only()
متد $request->except() خروجی مشابه $request->all() ارائه میدهد، اما میتوانید یک یا چند فیلد را حذف کنید — مثلاً _token. میتوانید به آن یک رشته یا آرایهای از رشتهها بدهید.
مثال 7-2 نشان میدهد که استفاده از $request->except() روی همان فرم مثال 7-1 چگونه خواهد بود.
مثال 7-2. $request->except()
Route::post('post-route', function (Request $request) {
var_dump($request->except('_token'));
});
// Outputs:
/**
* [
* 'firstName' => 'value',
* 'utm' => 12345
* ]
*/
$request->only() برعکس $request->except() است، همانطور که در مثال ۷-۳ میبینید.
مثال 7-3. $request->only()
Route::post('post-route', function (Request $request) {
var_dump($request->only(['firstName', 'utm']));
});
// Outputs:
/**
* [
* 'firstName' => 'value',
* 'utm' => 12345
* ]
*/
$request->has() و $request->missing()
$request->whenHas()
با متد $request->whenHas() میتوانید رفتار زمانی که یک فیلد وجود دارد یا وجود ندارد را مشخص کنید. اگر فیلد موجود باشد، کلوزر اول اجرا میشود، و اگر وجود نداشته باشد، کلوزر دوم اجرا میشود.
برای نمونهای از این موضوع با پارامتر utm، به مثال ۷-۵ توجه کنید.
مثال 7-5. $request->whenHas()
// POST route at /post-route
$utm = $request->whenHas('utm', function($utm) {
return $utm;
}, function() {
return 'default';
});
$request->filled()
$request->whenFilled()
مشابه متد whenHas()، متد $request->whenFilled() به شما اجازه میدهد تا مقدارها را هم در حالتی که فیلد پر شده است و هم در حالتی که پر نشده تعریف کنید. کلوزر اول زمانی اجرا میشود که فیلد مقدار داشته باشد و کلوزر دوم زمانی اجرا میشود که نداشته باشد. مثال ۷-۷ نحوه استفاده از این متد را نشان میدهد.
مثال 7-7. $request->whenFilled()
// POST route at /post-route
$utm = $request->whenFilled('utm', function($utm) {
return $utm;
}, function() {
return 'default';
});
$request->mergeIfMissing()
با متد mergeIfMissing() میتوانید در صورتی که فیلدی در درخواست وجود نداشته باشد، آن را همراه با مقدار مورد نظر اضافه کنید. این کار میتواند مفید باشد، مثلاً وقتی فیلدی از یک چکباکس میآید و فقط زمانی وجود دارد که تیک خورده باشد. مثال ۷-۸ یک پیادهسازی از این حالت را نشان میدهد.
مثال 7-8. $request->mergeIfMissing()
// POST route at /post-route
$shouldSend = $request->mergeIfMissing('send_newsletter', 0);
$request->input()
در حالی که متدهای $request->all()، $request->except() و $request->only() روی آرایه کامل دادههای ورودی کار میکنند، متد $request->input() به شما اجازه میدهد فقط مقدار یک فیلد خاص را دریافت کنید. مثال ۷-۹ یک نمونه از این استفاده را نشان میدهد. توجه داشته باشید که پارامتر دوم مقدار پیشفرض است؛ بنابراین اگر کاربر مقداری وارد نکرده باشد، یک مقدار جایگزین مناسب و بدون خطا دریافت میکنید.
مثال 7-9. $request->input()
Route::post('post-route', function (Request $request) {
$userName = $request->input('name', 'Matt');
});
$request->method() و $request->isMethod()
$request->integer()، $request->float()، $request->string() و $request->enum()
این متدها ورودیها را مستقیماً به نوع عدد صحیح، عدد اعشاری، رشتهای یا enum تبدیل میکنند. برای نمونههایی از نحوه استفاده، به مثال ۷-۱۱ مراجعه کنید.
مثال 7-11. $request->integer()، $request->float()، $request->string() و $request->enum()
dump(is_int($request->integer('some_integer'));
// true
dump(is_float($request->float('some_float'));
// true
dump(is_string($request->string('some_string'));
// true
dump($request->enum('subscription', SubscriptionStatusEnum::class));
// 'active', assuming that's a valid status for the SubscriptionStatusEnum
$request->dd() و $request->dump()
$request->dump() و $request->dd() متدهای کمکی برای dump کردن درخواست هستند. برای هر دو، میتوانید با عدم ارسال هیچ پارامتری، کل درخواست را dump کنید یا با ارسال یک آرایه، فقط فیلدهای انتخابشده را dump نمایید. $request->dump() اطلاعات را dump کرده و سپس ادامه میدهد، در حالی که $request->dd() اطلاعات را dump کرده و سپس اجرای اسکریپت را متوقف میکند. مثال 7-12 استفاده از آنها را نشان میدهد.
مثال ۷-۱۲. استفاده از $request->dd() و $request->dump()
// dump کردن کل درخواست
$request->dump();
$request->dd();
// فقط نمایش دو فیلد
$request->dump(['name', 'utm']);
$request->dd(['name', 'utm']);
ورودیهای آرایهای
ورودی JSON (و $request->json())
تا به اینجا ورودیهایی از رشتههای کوئری (GET) و ارسال فرمها (POST) را بررسی کردهایم. اما نوع دیگری از ورودی کاربر وجود دارد که با پیشرفت JavaScript SPAs رایجتر شده است: درخواست JSON. این اساساً یک درخواست POST است که بدنه آن به جای ارسال فرم سنتی، به JSON تنظیم شده است.
بیایید نگاهی به این بیندازیم که ارسال JSON به یک مسیر لاراول چگونه ممکن است باشد و چگونه از $request->input() برای استخراج این دادهها استفاده کنیم (مثال 7-14).
مثال 7-14. گرفتن دادهها از JSON با $request->input()
POST /post-route HTTP/1.1
Content-Type: application/json
{
"firstName": "Joe",
"lastName": "Schmoe",
"spouse": {
"firstName": "Jill",
"lastName":"Schmoe"
}
}
// Post-route
Route::post('post-route', function (Request $request) {
$firstName = $request->input('firstName');
$spouseFirstname = $request->input('spouse.firstName');
});
از آنجا که $request->input() به اندازه کافی هوشمند است که دادههای کاربر را از GET، POST یا JSON استخراج کند، ممکن است از خود بپرسید چرا لاراول حتی $request->json() را ارائه میدهد. دو دلیل برای ترجیح دادن $request->json() وجود دارد. اول اینکه ممکن است بخواهید به طور مشخصتر به سایر برنامهنویسانی که روی پروژه شما کار میکنند، بگویید که از کجا انتظار دارید دادهها بیایند. دوم اینکه اگر POST هدرهای صحیح application/json را نداشته باشد، $request->input() آن را به عنوان JSON شناسایی نمیکند، اما $request->json() این کار را خواهد کرد.
فضاهای نام فسادها، کمککننده سراسری request() و تزریق $request هر زمان که از فسادها در کلاسهای دارای فضای نام استفاده میکنید (مثلاً کنترلرها)، باید مسیر کامل فساد را به بلوک واردات در بالای فایل خود اضافه کنید (مثلاً use Illuminate\Support\Facades\Request). |
دادههای مسیر
از طریق Request
اشیاء Request تزریق شده (و فساد Request و کمککننده request()) چندین متد دارند که وضعیت URL صفحه جاری را نمایش میدهند، اما در حال حاضر بیایید روی گرفتن اطلاعات از بخشهای URL تمرکز کنیم.
اگر با این ایده آشنا نیستید، هر گروه از حروف بعد از دامنه در یک URL به عنوان یک بخش شناخته میشود. پس، http://www.myapp.com/users/15/ دو بخش دارد: users و 15.
همانطور که احتمالا حدس میزنید، دو متد در دسترس داریم: $request->segments() یک آرایه از همه بخشها برمیگرداند و $request->segment($segmentId) به ما این امکان را میدهد که مقدار یک بخش خاص را دریافت کنیم. توجه کنید که بخشها با اندیس 1 شروع میشوند، بنابراین در مثال قبلی، $request->segment(1) مقدار users را برمیگرداند.
اشیاء Request، فساد Request و کمککننده جهانی request() متدهای دیگری نیز برای کمک به استخراج دادهها از URL فراهم میکنند. برای یادگیری بیشتر، به فصل 10 مراجعه کنید.
از طریق پارامترهای مسیر
روش اصلی دیگر برای گرفتن دادهها از URL، پارامترهای مسیر هستند که به روش یا بستن کنترلری که مسیر جاری را سرویس میدهد، تزریق میشوند، همانطور که در مثال 7-15 نشان داده شده است.
مثال 7-15. گرفتن جزئیات URL از پارامترهای مسیر
// routes/web.php
Route::get('users/{id}', function ($id) {
// اگر کاربر به myapp.com/users/15/ مراجعه کند، $id برابر 15 خواهد بود
});
برای یادگیری بیشتر در مورد مسیرها و اتصال مسیرها، به فصل 3 مراجعه کنید.
آپلود فایلها
اعتبارسنجی لاراول
راههای مختلفی برای اعتبارسنجی دادههای ورودی دارد. در بخش بعدی درخواستهای فرم را پوشش خواهیم داد، بنابراین دو گزینه اصلی برای ما باقی میماند: اعتبارسنجی دستی یا استفاده از متد validate() روی شیء Request. بیایید با validate() که سادهتر و رایجتر است شروع کنیم.
validate() روی شیء Request
شیء Request دارای متد validate() است که یک میانبر راحت برای جریان کار اعتبارسنجی معمول فراهم میکند. به مثال 7-19 نگاهی بیندازید.
مثال 7-19. استفاده پایه از اعتبارسنجی درخواست
// routes/web.php
Route::get('recipes/create', [RecipeController::class, 'create']);
Route::post('recipes', [RecipeController::class, 'store']);
// app/Http/Controllers/RecipeController.php
class RecipeController extends Controller
{
public function create()
{
return view('recipes.create');
}
public function store(Request $request)
{
$request->validate([
'title' => 'required|unique:recipes|max:125',
'body' => 'required'
]);
// Recipe is valid; proceed to save it
}
}
ما تنها چهار خط کد برای اجرای اعتبارسنجی داریم، اما این خطوط کار زیادی انجام میدهند.
اول، ما به طور صریح فیلدهایی که انتظار داریم را تعریف کرده و قوانین (که در اینجا با کاراکتر لوله | جدا شدهاند) را به هرکدام به طور جداگانه اعمال میکنیم.
بعد، متد validate() دادههای ورودی از $request را بررسی کرده و تعیین میکند که آیا دادهها معتبر هستند یا خیر.
اگر دادهها معتبر باشند، متد validate() تمام میشود و میتوانیم به متد کنترلر ادامه دهیم، دادهها را ذخیره کنیم یا هر کار دیگری.
اما اگر دادهها معتبر نباشند، یک ValidationException پرتاب میشود. این استثنا دستوراتی به مسیریاب میدهد که چگونه باید با این استثنا برخورد کند. اگر درخواست از جاوااسکریپت باشد (یا اگر درخواست JSON به عنوان پاسخ باشد)، استثنا یک پاسخ JSON حاوی خطاهای اعتبارسنجی ایجاد میکند. در غیر این صورت، استثنا یک ریدایرکت به صفحه قبلی همراه با تمام ورودیهای کاربر و خطاهای اعتبارسنجی باز میگرداند—مناسب برای بازسازی یک فرم ناموفق و نمایش خطاها.
بیشتر در مورد قوانین اعتبارسنجی لاراول
اعتبارسنجی دستی
اگر در حال کار با یک کنترلر نیستید یا به هر دلیلی جریان کاری که قبلاً توصیف شد برای شما مناسب نیست، میتوانید به صورت دستی یک نمونه از Validator ایجاد کرده و موفقیت یا شکست آن را مانند مثال 7-20 بررسی کنید.
مثال 7-20. اعتبارسنجی دستی
Route::get('recipes/create', function () {
return view('recipes.create');
});
Route::post('recipes', function (Illuminate\Http\Request $request) {
$validator = Validator::make($request->all(), [
'title' => 'required|unique:recipes|max:125',
'body' => 'required'
]);
if ($validator->fails()) {
return redirect('recipes/create')
->withErrors($validator)
->withInput();
}
// Recipe is valid; proceed to save it
});
همانطور که میبینید، ما با ارسال ورودی به عنوان پارامتر اول و قوانین اعتبارسنجی به عنوان پارامتر دوم، یک نمونه از یک اعتبارسنج ایجاد میکنیم. اعتبارسنج متد fails() را در اختیار میگذارد که میتوانیم آن را بررسی کنیم و آن را به متد withErrors() در ریدایرکت ارسال کنیم.
استفاده از دادههای معتبر
پس از اینکه دادههای خود را اعتبارسنجی کردید، میتوانید آنها را از درخواست استخراج کنید به طوری که فقط با دادههای معتبر کار کنید. دو گزینه اصلی وجود دارد: validated() و safe(). شما میتوانید این متدها را یا روی شیء $request اجرا کنید، یا اگر اعتبارسنجی دستی ایجاد کردهاید، روی نمونه $validator.
متد validated() یک آرایه از تمام دادههایی که اعتبارسنجی شدهاند برمیگرداند.
مثال 7-21. گرفتن دادههای معتبر با validated()
// هر دو آرایهای از ورودیهای معتبر کاربر را برمیگردانند
$validated = $request->validated();
$validated = $validator->validated();
از طرفی متد only() یک شیء برمیگرداند که به شما دسترسی به متدهای all()، only() و except() میدهد، همانطور که در مثال 7-22 میبینید.
مثال 7-22. گرفتن دادههای معتبر با safe()
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['password']);
$validated = $request->safe()->all();
اشیاء قانون سفارشی
نمایش پیامهای خطای اعتبارسنجی
ما قبلاً بسیاری از این موارد را در فصل 6 پوشش دادهایم، اما در اینجا یک مرور سریع در مورد چگونگی نمایش خطاها از اعتبارسنجی آورده شده است.
متد validate() روی درخواستها (و متد withErrors() روی ریدایرکتهایی که به آن وابسته است) هر گونه خطا را به جلسه میفرستد. این خطاها برای نمایی که به آن ریدایرکت میشوید، در متغیر $errors در دسترس خواهند بود. و به یاد داشته باشید که به عنوان بخشی از جادوی لاراول، متغیر $errors هر بار که نمای را بارگذاری میکنید در دسترس خواهد بود، حتی اگر خالی باشد، بنابراین نیازی به بررسی وجود آن با isset() ندارید.
این بدین معنی است که شما میتوانید چیزی مانند مثال 7-24 را در هر صفحهای انجام دهید.
مثال 7-24. نمایش خطاهای اعتبارسنجی
@if ($errors->any())
<ul id="errors">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
شما همچنین میتوانید به طور شرطی پیام خطای یک فیلد خاص را نمایش دهید. برای این کار از دستور Blade @error استفاده خواهید کرد تا بررسی کنید که آیا خطایی برای فیلد خاصی وجود دارد یا نه.
@error('first_name')
<span>{{ $message }}</span>
@enderror
درخواست های فرم
ایجاد یک درخواست فرم
شما میتوانید یک درخواست فرم جدید را از خط فرمان ایجاد کنید:
php artisan make:request CreateCommentRequest
اکنون یک شیء درخواست فرم در مسیر app/Http/Requests/CreateCommentRequest.php در دسترس شما است.
هر کلاس درخواست فرم حداقل یکی یا دو متد عمومی دارد. اولی متد rules() است که باید یک آرایه از قوانین اعتبارسنجی برای این درخواست را برگرداند. متد دوم (اختیاری) متد authorize() است؛ اگر این متد true را برگرداند، کاربر مجاز به انجام این درخواست است و اگر false باشد، کاربر رد میشود. به مثال 7-25 نگاه کنید تا یک درخواست فرم نمونه را ببینید.
مثال 7-25. درخواست فرم نمونه
<?php
namespace App\Http\Requests;
use App\BlogPost;
use Illuminate\Foundation\Http\FormRequest;
class CreateCommentRequest extends FormRequest
{
public function authorize(): bool
{
$blogPostId = $this->route('blogPost');
return auth()->check() && BlogPost::where('id', $blogPostId)
->where('user_id', auth()->id())->exists();
}
public function rules(): array
{
return [
'body' => 'required|max:1000',
];
}
}
بخش rules() در مثال 7-25 کاملاً واضح است، اما بیایید به طور مختصر به authorize() نگاه کنیم.
ما بخش مسیری را با نام blogPost میگیریم. این به این معنی است که احتمالاً تعریف مسیر اینطور به نظر میرسد:
Route::post('blogPosts/blogPost', function () { // Do stuff });
همانطور که میبینید، ما پارامتر مسیر را blogPost نامگذاری کردهایم که باعث میشود در درخواست خود با استفاده از $this->route('blogPost') به آن دسترسی داشته باشیم.
سپس بررسی میکنیم که آیا کاربر وارد شده است و اگر بله، آیا پستهای وبلاگی با آن شناسه وجود دارند که متعلق به کاربر وارد شده فعلی باشند. شما قبلاً روشهای سادهتری برای بررسی مالکیت را در فصل 5 یاد گرفتهاید، اما برای تمیزی بیشتر، اینجا روش واضحتری را نگه میداریم. ما به زودی تبعات این را پوشش خواهیم داد، اما نکته مهم این است که اگر true برگشت داده شود، یعنی کاربر مجاز به انجام عمل مشخص شده (در این مورد ایجاد یک نظر) است و اگر false برگشت داده شود، یعنی کاربر مجاز نیست.
استفاده از درخواست فرم
حالا که یک شیء درخواست فرم ایجاد کردهایم، چگونه از آن استفاده کنیم؟ این کمی جادوی لاراول است. هر مسیری (بسته یا متد کنترلر) که یک درخواست فرم را به عنوان یکی از پارامترهای خود تایپ کرده باشد، از تعریف آن درخواست فرم بهرهمند خواهد شد.
بیایید آن را در مثال 7-26 امتحان کنیم.
مثال 7-26. استفاده از درخواست فرم
Route::post('comments', function (App\Http\Requests\CreateCommentRequest $request) {
// Store comment
});
ممکن است از خود بپرسید که کجا درخواست فرم را فراخوانی میکنیم، اما لاراول این کار را برای ما انجام میدهد. این سیستم ورودی کاربر را اعتبارسنجی کرده و درخواست را احراز هویت میکند. اگر ورودی معتبر نباشد، مانند متد validate() شیء درخواست عمل میکند، و کاربر را به صفحه قبلی با ورودیهای حفظشده و پیامهای خطای مناسب هدایت میکند. و اگر کاربر مجاز نباشد، لاراول خطای 403 Forbidden را باز میگرداند و کد مسیر را اجرا نمیکند.
تخصیص انبوه مدل Eloquent
{{ در مقابل {!!
هر زمان که محتوایی را که توسط کاربر ایجاد شده است در یک صفحه وب نمایش میدهید، باید در برابر ورودیهای مخرب، مانند تزریق اسکریپت محافظت کنید.
فرض کنید به کاربران خود اجازه میدهید تا پستهای وبلاگ بنویسند. احتمالاً نمیخواهید که آنها بتوانند جاوااسکریپت مخربی را تزریق کنند که در مرورگرهای بازدیدکنندگان شما بهطور غیرمنتظره اجرا شود، درست است؟ بنابراین، باید هر ورودی کاربر را که در صفحه نمایش میدهید، از نظر امنیتی_escape کنید تا از این موضوع جلوگیری کنید.
خوشبختانه، این تقریباً بهطور کامل برای شما انجام شده است. اگر از موتور قالببندی Blade لاراول استفاده کنید، دستور پیشفرض "echo" ({{ $stuffToEcho }}) بهطور خودکار خروجی را از طریق htmlentities() (بهترین روش PHP برای ایمن کردن محتوای کاربر جهت نمایش) میبرد. در واقع شما باید کار اضافی انجام دهید تا از فرار دادن خروجی جلوگیری کنید، با استفاده از دستور {!! $stuffToEcho !!}.
تست
اگر به آزمایش تعاملات خود با ورودیهای کاربر علاقهمند هستید، احتمالاً بیشتر به شبیهسازی ورودیهای معتبر و نامعتبر کاربر و اطمینان از این که اگر ورودی نامعتبر باشد، کاربر ریدایرکت شود، و اگر ورودی معتبر باشد، در مکان مناسب قرار گیرد (برای مثال، در پایگاه داده) علاقه دارید.
چارچوب آزمایشهای اپلیکیشن لاراول این کار را ساده میکند.
لاراول داسک برای آزمایش تعاملات کاربر این آزمایشها لایه HTTP برنامه شما را تست میکنند، اما فیلدها و تعاملات فرم واقعی را آزمایش نمیکنند. اگر میخواهید تعاملات خاص کاربر را در صفحه و با فرمهای خود آزمایش کنید، باید بسته آزمایشی لاراول داستک را وارد کنید. برای یادگیری نحوه نصب و استفاده از داسک در آزمایشهایتان، به "تست با داسک" مراجعه کنید. |
بیایید با یک مسیر نامعتبر شروع کنیم که انتظار داریم رد شود، مانند مثال 7-29.
مثال 7-29. آزمایش اینکه ورودی نامعتبر رد میشود
public function test_input_missing_a_title_is_rejected()
{
$response = $this->post('posts', ['body' => 'This is the body of my post']);
$response->assertRedirect();
$response->assertSessionHasErrors();
}
در اینجا ما بررسی میکنیم که پس از ورودی نامعتبر، کاربر ریدایرکت میشود، با خطاهایی که پیوست شدهاند. میبینید که ما از برخی از تأییدهای PHPUnit سفارشی که لاراول اینجا اضافه کرده است استفاده میکنیم.
پس، چگونه موفقیت مسیر خود را آزمایش کنیم؟ به مثال 7-30 نگاه کنید.
مثال 7-30. آزمایش اینکه ورودی معتبر پردازش میشود
public function test_valid_input_should_create_a_post_in_the_database()
{
$this->post('posts', ['title' => 'Post Title', 'body' => 'This is the body']);
$this->assertDatabaseHas('posts', ['title' => 'Post Title']);
}
توجه داشته باشید که اگر در حال آزمایش چیزی با استفاده از پایگاه داده هستید، باید بیشتر در مورد مایگریشنها و تراکنشهای پایگاه داده یاد بگیرید. بیشتر در این مورد در فصل 12 بخوانید.
خلاصه
راههای زیادی برای بهدست آوردن همان دادهها وجود دارد: استفاده از فساد Request، استفاده از هلپر سراسری request() و تزریق یک نمونه از Illuminate\Http\Request. هرکدام از اینها قابلیت دریافت تمام ورودی، برخی ورودیها، یا بخشهای خاصی از دادهها را ارائه میدهند، و ممکن است برخی ملاحظات ویژه برای فایلها و ورودیهای JSON وجود داشته باشد.
بخشهای مسیر URI نیز میتوانند منبع ورودی کاربر باشند و اینها نیز از طریق ابزارهای درخواست قابل دسترسی هستند.
اعتبارسنجی میتواند بهصورت دستی با استفاده از Validator::make() یا بهطور خودکار با استفاده از متد validate() درخواست یا درخواستهای فرم انجام شود. هر ابزار خودکار، پس از شکست اعتبارسنجی، کاربر را به صفحه قبلی با ورودیهای قدیمی ذخیرهشده و خطاها منتقل میکند.
ویوها و مدلهای Eloquent نیز باید در برابر ورودیهای مخرب کاربر محافظت شوند. ویوهای Blade را با استفاده از دستور براکتهای دوگانه ({{ }}) که ورودی کاربر را فرار میدهند، محافظت کنید و مدلها را با ارسال تنها فیلدهای خاص به متدهای انبوه با استفاده از $request->only() و تعریف قوانین تخصیص انبوه در خود مدل محافظت کنید.