coاگر از فصل ۱ تا فصل ۹ این سری از دورههای آموزشی را طی کرده باشید قطعا این سوال برای شما پیش آمده است که هر نرمافزار که با الگوی معماری ۳ لایه MVC طراحی شده است. از سه بخش عمده تشکیل شده درحالیکه تنها دو بخش Controller و View در این مجموعه آموزش داده شده است. پس بخش سوم چه میشود؟ هم اکنون زمان پاسخگویی به سوال شما. از آنجا که مبحث Model ها به عنوان یک واسط بین دیتابیس و کنترلر است بر آن شدیم تا یک فصل کامل را به آن اختصاص دهیم.
در معنای لغوی Eloquent معادل یک سخنران، سخنور است اما در لاراول معنای کاربردیتری دارد و آن:
«Eloquent را میتوان به عنوان یک ابزار طراحی جهت پیادهسازی انواع مختلف عملیاتهای محاسباتی و پردازشی پایگاهداده (ORM مخفف Object-relational mapping)، معرفی کرد»
با استفاده از Eloquent میتوانید عملیاتهایی مانند ایجاد، حذف، بروزرسانی و اضافه کردن را در قالب کوئریهای مختلف به س
ادهترین شکل ممکن ارائه دهید. هنگامیکه شما یک مدل (Model) ایجاد میکنید (مثلا مدل Song) این مدل با جدول موجود در پایگاه دادهی شما ارتباط برقرار میکند (نام این جدول در پایگاه داده songs میباشد).
هر جدول در دیتابیس شما به یک مدل (Model) متصل است. تمام مدلها در مسیر App قرار میگیرند. به صورت پیشفرض مدل User.php در این پوشه موجود است. قبل از هر چیز به نحوهی ایجاد یک مدل میپردازیم. جهت ساخت یک مدل دستور زیر را در CMD اجرا میکنیم:
php artisan make:model Song
همچنین برای برقراری بین دیتابیس و مدل، لاراول امکاناتی در اختیار شما قرار داده است تا هنگام ساخت یک مدل، فایل migration آن نیز در پوشهی database/migrations ایجاد شود. برای انجام این کار از دستور زیر استفاده کنید:
php artisan make:model Song --migration or php artisan make:model Song -m
حال اگر دستور فوق را وارد کنید یک فایل تحت عنوان Song.php در مسیر App و یک فایل با نام create_songs_table.php در مسیر database/migrations ایجاد شده است.
محتویات فایل Song.php به صورت زیر است:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Song extends Model { // }
همچنین محتویات فایل create_songs_table.php به صورت زیر:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateMasoudsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('songs', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('songs'); } }
بنابراین علاوه بر ساخت مدل Song یک جدول با نام songs در اختیار شما قرار میگیرد.
فرض کنید یک مدل با نام Song میخواهیم تولید کنیم. بر اساس استانداردسازی یک جدول و مدل از قواعد نامگذاری آن تبعیت کرد. بنابراین در مدلهای لاراول نام مدل به صورت مفرد و نام جداول و کنترلرها و ویوها به صورت جمع خواهد بود. بنابراین برای مدل Song باید یک جدول با نام songs، یک کنترلر با نام SongsController و یک ویو تحت عنوان songs ایجاد کرد. حال برای عبارتهای دو یا سه سیلابی باید آخرین سیلاب آنها را به صورت جمع نوشت. به عنوان مثال برای مدل SecondaryContact باید جدول با نام secondary_contacts ایجاد کرد.
چنانچه بخواهید نام جدول یک مدل را به مقدار دلخواه خود تغییر دهید باید متغییر table$ را در فایل مدل و داخل کلاس class ModelName extend Model به صورت زیر تعریف کنید:
protected $table = 'contacts_secondary';
لاراول به صورت پیشفرض مقدار id هر ستون را به عنوان کلید اصلی مشخص میکند. حال اگر بخواهیم مقدار کلید اصلی پیشفرض را تغییر دهیم باید متغییر primaryKey$ را درون کلاس مدل به صورت زیر تغییر دهیم:
protected $primaryKey = 'contact_id';
همانطور که در جریان هستید لاراول به صورت پیشفرض مقادیر Primary Key ها را افزایشی تعریف میکند (یعنی به صورت خودکار مقادیر این ستونها به ازای هر رکورد جدید افزایش پیدا میکند) در صورتی که بخواهیم این پیش فرض را بر هم زده و اضافه شدن مقادیر عددی را از هر ستون بگیریم باید دستور زیر را در کلاس تعریف کنیم:
public $incrementing = false;
به ازای تعریف هر جدول دو ستون تحت عنوان created_at و updated_at ایجاد میشود. اگر نیازی به این دو ستون ندارید و میخواهد به صورت دلخواه تعریف کنید دستور زیر را به کدهای خود اضافه کنید:
public $timestamps = false;
در صورتیکه بخواهیم نامهای created_at و updated_at را تغییر دهیم باید ثابتهایی به صورت زیر تعریف کرده و به کلاس اضافه کنیم:
const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update';
هنگامیکه یک مدل را ایجاد میکنید به دلیل ارتباط آن مدل با جدول موردنظر میتوانید طی یک فرآیند، اطلاعات هر آنچه داده داخل جدول است را با استفاده از مدل ها بازیابی کرد. قبل از بکار بردن مدلها برای استخراج داده بهتر است شمارا با مفهوم جدیدی به نام کالکشنها آشنا کنیم:
بازیابی اطلاعات با استفاده از Helperهای Collection
برای بازیابی بهتر اطلاعات میتوان از یک سری متدها استفاده کرد تا با اعمال شروط و قید و بند خروجی فیلترشدهای را از دیتابیس دریافت کنیم. تمام هر آنچه که به صورت مجموعهای از نتایج توسط Eloquent بازگردانده میشوند نمونهای از شیء Illuminate\Database\Eloquent\Collection هستند. که این نتایج توسط متد get بازیابی میشوند. در این قصد لازم میدانیم اطلاعاتی راجعبه کالکشن ها در اختیار شما عزیزان قرار دهیم و سپس در ادامهی بحث به توضیح انواع متدهای collectionها برای خروجی گرفتن از دیتابیس اشاره کنیم.
collection ها در لاراول از کلاس Illuminate\Support\Collection استخراج شده و برای کارکردن با آرایهها مورد استفاده قرار میگیرند. به عنوان مثال در کد زیر مشاهده خواهید کرد که برای ساخت یک کالکشن جدید از آرایهها میتوان از هلپر (helper) به نام collect استفاده کنیم و یک مقدار را به خروجی بازگردانیم:
$collection = collect([1, 2, 3]);
درنظر داشته باشید که collectionها دقیقا مشابه آرایهها هستند ولی تغییر پذیر نیستند. یعنی اعضای یک کالشکن را نمیتوان تغییر داد و یا جایگزین کرد.
در این بخش قصد داریم تمام این متدها را شرح داده و نحوهی کارکرد آنها را توضیح دهیم.
all()
این دستور زمانی مورد استفاده قرار میگیرد که بخواهیم تمام اطلاعات موجود در یک جدول را بازیابی کنیم. به مثال زیر توجه کنید:
collect([1, 2, 3])->all(); // [1, 2, 3]
avg()
این متد میانگین تمام آیتمهایی که در یک کالشکن وجود دارند را باز میگرداند. به مثال زیر توجه کنید:
collect([1, 2, 3, 4, 5])->avg(); // 3
درصورتیکه کالکشن ما به صورت آرایهها یا اشیاء تو در تو بود باید همواره کلید آن را به عنوان آرگومان ارسال کنیم:
$collection = collect([ ['name' => 'JavaScript: The Good Parts', 'pages' => 176], ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096], ]); $collection->avg('pages'); // 636
همانطور که ملاحظه میکنید با ارسال کلید pages تنها دو مقدار ۱۷۶ و ۱۰۹۶ میانگینگیری شده و در خروجی نمایش داده خواهد شد.
chunk()
متد chunk جهت تبدیل کالکشنهای بزرگتر به کالکشنهای کوچکتر مورد استفاده قرار میگیرد. که به عنوان آرگومان ورودی یک سایز را دریافت میکند:
$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->toArray(); // [[1, 2, 3, 4], [5, 6, 7]]
collapse()
جهت ترکیب کردن چندین دسته آرایه از این دستور استفاده میشود. به مثال زیر توجه کنید:
$collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); $collapsed = $collection->collapse(); $collapsed->all(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
combine()
جهت ترکیب کردن یک کلید (key) و مقدارش (value) با یک کالکشن مورد استفاده قرار میگیرد. به مثال زیر توجه کنید:
$collection = collect(['name', 'age']); $combined = $collection->combine(['George', 29]); $combined->all(); // ['name' => 'George', 'age' => 29]
contains()
این دستور بررسی میکند که آیا یک آیتم درون کالکشن وجود دارد یا خیر؟ مثال زیر را بررسی کنید:
$collection = collect(['name' => 'Desk', 'price' => 100]); $collection->contains('Desk'); // true $collection->contains('New York'); // false
حال اگر از یک مجموعهی کلید و مقدار در کالکشن استفاده شود میتوان آرگومان دوم را برای ()contains
استفاده کرد:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ]); $collection->contains('product', 'Bookcase'); // false
علاوه بر موارد فوق میتوان یک تابع callback را به عنوان آرگومان به ورودی ()cotains
ارسال میکنیم:
$collection = collect([1, 2, 3, 4, 5]); $collection->contains(function ($value, $key) { return $value > 5; }); // false
count()
از این دستور برای شمارش تعداد آیتمهای موجود در یک کالکشن استفاده میکنند:
$collection = collect([1, 2, 3, 4]); $collection->count(); // 4
diff()
متد diff برای مقایسهی دو کالکشن یا آرایه از نظر مقادیر (values) مورد استفاده قرار میگیرد. این متد مقادیری که در کالکشن اصلی نباشد را نمایش میدهد:
$collection = collect([1, 2, 3, 4, 5]); $diff = $collection->diff([2, 4, 6, 8]); $diff->all(); // [1, 3, 5]
diffKeys()
این دستور دو کالشکن یا آرایه را بر اساس کلیدهایی (keys) که دارند، مقایسه میکند. این متد مقادیری که باز میگرداند یک جفت کلید/مقدار است که در کالکشن اصلی وجود ندارد:
$collection = collect([ 'one' => 10, 'two' => 20, 'three' => 30, 'four' => 40, 'five' => 50, ]); $diff = $collection->diffKeys([ 'two' => 2, 'four' => 4, 'six' => 6, 'eight' => 8, ]); $diff->all(); // ['one' => 10, 'three' => 30, 'five' => 50]
each()
متد each جهت انجام عملیات برای هر آیتم و کلید درون کالکشنها مورد استفاده قرار میگیرد و بهگونهای میتوان گفت که شبیه دستور foreach عمل میکند:
$collection = $collection->each(function ($item, $key) { // });
جهت خروج از تکرار هم میتوان از دستور return false استفاده کرد:
$collection = $collection->each(function ($item, $key) { if (/* some condition */) { return false; } });
every()
از این دستور میتوان به عنوان یک شرط استفاده کرد و برای همهی درایههای یک کالکشن مورد استفاده قرار میگیرد. در بیشتر مواقع برای تایید یک شرط در یک کالکشن استفاده میشود. مثلا در مثال زیر میخواهیم بگوییم که برای همهی آیتمهای یک کالکشن مقداری را بررسی کند:
collect([1, 2, 3, 4])->every(function ($value, $key) { return $value > 2; }); // false
except()
این متد تمام آیتمهای یک کالکشن را بجز آنهایی که keyهایشان مشخص شده است را باز میگرداند. except در لغت به معنی استثناء است. مثال زیر را مشاهده کنید:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]); $filtered = $collection->except(['price', 'discount']); $filtered->all(); // ['product_id' => 1]
only()
دقیقا عکس دستور except عمل میکند. بدین صورت که هر کلید (keys) یا کلیدهایی که درون آرگومان آن قرار بگیرد. در خروجی نمایش داده خواهد شد.
$collection = collect(['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]); $filtered = $collection->only(['product_id', 'name']); $filtered->all(); // ['product_id' => 1, 'name' => 'Desk']
filter()
این متد برای فیلتر کردن مقادیر و کلیدهای موجود در یک کالکشن مورد استفاده قرار میگیرد. به عنوان مثال در نمونهی زیر تمام مقادیر بیش از ۲ را در خروجی چاپ میکنیم:
$collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function ($value, $key) { return $value > 2; }); $filtered->all(); // [3, 4]
در صورتیکه متد فیلتر را بدون تابع Clouser مورد استفاده قرار دهیم، مقداری که به ما بر میگرداند برابر است با فیلتر کردن یک کالشکن در برابر هر آنچه که معادل false است، بنابراین عبارت null, false و یا فضای خالی ' '، عدد ۰ و آرایه خالی []، همگی جزو یک عبارت false هستند، به مثال زیر توجه کنید:
$collection = collect([1, 2, 3, null, false, '', 0, []]); $collection->filter()->all(); // [1, 2, 3]
reject()
این متد عکس متد filter عمل میکند. بدینگونه که به ازای هر آنچه که درست نباشد در خروجی نمایش میدهد. مثلا در نمونهی زیر اعداد بیشتر از ۲ برابر ۳ و ۴ هستند ولی مقادیر ۱ و ۲ درست نیستند! بنابراین آنچه با دستور reject چاپ میشود برابر است با [1,2]:
$collection = collect([1, 2, 3, 4]); $filtered = $collection->reject(function ($value, $key) { return $value > 2; }); $filtered->all(); // [1, 2]
first()
این متد اولین المان یک کالکشن را در اختیار شما قرار میدهد. به عنوان مثال در نمونهی زیر اعداد بیشتر از ۲ برابر ۳ و ۴ هستند اما تنها مقدار ۳ که اولین مقدار شناسایی شده است در خروجی چاپ میشود:
collect([1, 2, 3, 4])->first(function ($value, $key) { return $value > 2; }); // 3
اگر آرگومانی به تابع و متد first ارسال نشود بدیهیست که اولین مقدار یک کالکشن بازگردانده خواهد شد و در صورتیکه مقداری وجود نداشته باشد (یعنی کالکشن خالی-empty باشد) آنگاه مقدار null بازگردانده خواهد شد.
collect([1, 2, 3, 4])->first(); // 1
flatMap()
با استفاده از این متد میتوان یک تابع callback را برای تک تک آرایههای موجود در یک کالکشن تکرار کرد. حال با استفاده از این تابع callback میتوان مقادیر این آیتمها را ویرایش کرد و سپس بازگرداند. بنابراین یک کالکشن جدید تحویل داده خواهد شد. به مثال زیر توجه کنید که با استفاده از تابع callback مقادیر هر آرایهی موجود در کالکشن را ویرایش کردیم و یک کالکشن جدید تحویل دادیم:
$collection = collect([ ['name' => 'Sally'], ['school' => 'Arkansas'], ['age' => 28] ]); $flattened = $collection->flatMap(function ($values) { return array_map('strtoupper', $values); }); $flattened->all(); // ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
flatten()
از این متد برای تبدیل کردن کالکشنهای چندبعدی به یکبعدی استفاده میشود. به مثال زیر توجه کنید:
$collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]); $flattened = $collection->flatten(); $flattened->all(); // ['taylor', 'php', 'javascript'];
همچنین میتوان با دادن مقدار عمق یک آرایه یا کالکشن را مورد هدف قرار داد، در مثال زیر لایه اول آرایهها مدنظر میباشد:
$collection = collect([ 'Apple' => [ ['name' => 'iPhone 6S', 'brand' => 'Apple'], ], 'Samsung' => [ ['name' => 'Galaxy S7', 'brand' => 'Samsung'] ], ]); $products = $collection->flatten(1); $products->values()->all(); /* [ ['name' => 'iPhone 6S', 'brand' => 'Apple'], ['name' => 'Galaxy S7', 'brand' => 'Samsung'], ] */
در این مثال همانطور که در جریان هستید درصورتیکه آرگومانی به متد ارسال نکنیم خروجی ما به صورت زیر خواهد بود:
['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']
flip()
این متد برای جابهجا (عکس) کردن کلیدها و مقادیر بکار گرفته میشود. به مثال زیر توجه کنید:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $flipped = $collection->flip(); $flipped->all(); // ['taylor' => 'name', 'laravel' => 'framework']
forget()
از این متد برای حذف کردن یک آیتم از کالشکن توسط کلید آن، استفاده میشود:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $collection->forget('name'); $collection->all(); // ['framework' => 'laravel']
توجه: برخلاف بسیاری از متدهای کالکشنهای قبلی، متد forget مقداری را به عنوان کالکشن جدید باز نمیگرداند بلکه آن را ویرایش میکند.
forPage()
این متد یک کالکشن جدید شامل آیتمهایی که در یک صفحه مشخص به تعداد مشخص نمایش داده میشود. مثلا در مثال زیر اعلام کردیم که در صفحه ۲ تعداد ۳ آیتم نمایش داده میشود. آرگومان اول شمارهی صفحه و صفحه دوم تعداد آیتمهایی که نمایش داده میشود:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]); $chunk = $collection->forPage(2, 3); $chunk->all(); // [4, 5, 6]
توضیح مختصری درباره مثال بالا خدمت شما همراهان روکسو عرض کنیم: در مثال بالا به ازای هر صفحه ۳ آیتم نمایش داده خواهد شد. حالا مقادیر موجود در صفحه ۲ را با ارسال ارگومان اول بازگردانی کردهایم.
get()
یکی از پرکاربردترین متدهای کالکشنها دستور ()get است. این دستور مقدار یک آیتم را بر اساس کلیدی که به عنوان آرگومان به آن ارسال میکنیم باز میگرداند. درصورتیکه آن کلید وجود نداشته باشد مقدار null را باز میگرداند. به مثال زیر توجه کنید:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('name'); // taylor
همچنین میتوان به عنوان آرگومان دوم یک مقدار پیشفرض را ارسال کرد تا درصورتیکه آن کلید وجود نداشت مقدار پیشفرضی برایش درنظر بگیرد:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('foo', 'default-value'); // default-value
همچنین میتوان یک تابع callback به عنوان مقدار پیشفرض بهعنوان آرگومان دوم به این متد ارسال کرد. درصورتیکه کلید موردنظر وجود نداشته باشد این مقدار پیشفرض که از تابع callback باز گردانده شده است، جایگزین میشود:
$collection->get('email', function () { return 'default-value'; }); // default-value
groupBy()
از این متد برای گروهبندی آیتمهای یک کالشکن بر اساس کلید آن مورد استفاده قرار میگیرد:
$collection = collect([ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ['account_id' => 'account-x11', 'product' => 'Desk'], ]); $grouped = $collection->groupBy('account_id'); $grouped->toArray(); /* [ 'account-x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'account-x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ] */
همچنین میتوان یک تابع callback را به عنوان آرگومان به این متد ارسال کرد. تابع callback باید مقادیری یک کلید را ارسال کند:
$grouped = $collection->groupBy(function ($item, $key) { return substr($item['account_id'], -3); }); $grouped->toArray(); /* [ 'x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ] */
has()
این متد بررسی میکند که آیا کلید موردنظر در کالکشن موجود است یا خیر که پاسخ را به صورت TRUE و FALSE در اختیار کاربر قرار میدهد:
$collection = collect(['account_id' => 1, 'product' => 'Desk']); $collection->has('product'); // true
implode()
از این متد برای اتصال آیتمهای یک کالکشن بهره میبریم، آرگومانی که این متد دریافت میکند بر اساس نوع آیتمهایی که در کالکشن است، میباشد. اگر کالکشن شامل آرایهها و یا اشیاء باشد، شما باید کلید صفاتی که انتظار دارید به عنوان یک اتصال درنظر بگیرید را مشخص کنید و در آرگومان دوم باید رشته یا عبارتی که میخواهید برای جداکردن این آرایه ها قرار دهید را مشخص کنید. خروجی این متد باز میگرداند یک رشته است:
$collection = collect([ ['account_id' => 1, 'product' => 'Desk'], ['account_id' => 2, 'product' => 'Chair'], ]); $collection->implode('product', ', '); // Desk, Chair
و اگر یک کالکشن عبارت سادهتری داشت میتوان تنها یک آرگومان به این متد ارسال کرد که بیانگر عبارتیست که بین هر آیتم به هنگام نمایش دادن قرار داده میشود:
collect([1, 2, 3, 4, 5])->implode('-'); // '1-2-3-4-5'
intersect()
این متد زمانی مورد استفاده قرار میگیرد که بخواهیم تمام آیتمهای موجود در یک کالکشن یا آرایهی جدید را با قبلی مقایسه کرده و در صورت عدم وجود هر یک از آیتمهای کالکشن یا آرایهی جدید در کالکشن قبلی، آنها را حذف میکند. خروجی این متد بگونهایست که ایندکس یا کلید کالکشن قبلی را حفظ میکند. به مثال زیر توجه کنید:
$collection = collect(['Desk', 'Sofa', 'Chair']); $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); $intersect->all(); // [0 => 'Desk', 2 => 'Chair']
isEmpty()
این متد مقدار TRUE را برای زمانیکه یک کالکشن خالی empty باشد ارسال میکند و در غیر این صورت مقدار FALSE را برمیگرداند:
collect([])->isEmpty(); // true
keyBy()
این متد بر اساس کلیدی که دریافت میکند کالکشن را از نو کلیدگذاری کرده و آن را در خروجی نمایش میدهد. اگر تمام کلیدهای چندین آیتم یکسان باشند تنها آخرین مقدار را به نمایش میگذارد:
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'desk'], ['product_id' => 'prod-200', 'name' => 'chair'], ]); $keyed = $collection->keyBy('product_id'); $keyed->all(); /* [ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ] */
علاوه بر این میتوان یک تابع callback به عنوان آرگومان ورودی به متد ارسال کرد و نتیجه را در خروجی مشاهده نمود:
$keyed = $collection->keyBy(function ($item) { return strtoupper($item['product_id']); }); $keyed->all(); /* [ 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ] */
keys()
از این متد برای استخراج تمام کلیدهای موجود در یک کالکشن استفاده میشود:
$collection = collect([ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ]); $keys = $collection->keys(); $keys->all(); // ['prod-100', 'prod-200']
last()
این متد آخرین المان یک کالکشن را باز میگرداند. در مثال زیر یک آرگومان به عنوان تابع callback به متد ارسال کرده و نتیجه را مشاهده میکنید. مقادیر کمتر از 3 انتخاب شده اند که آخرین آن عدد 2 میباشد و در خروجی چاپ میشود:
collect([1, 2, 3, 4])->last(function ($value, $key) { return $value < 3; }); // 2
در صورتیکه آرگومانی به این متد ارسال نکنیم با آخرین مقدار یک کالکشن بازگردانده میشود و اگر این مقدار وجود نداشته باشد. عبارت null باز میگردد:
collect([1, 2, 3, 4])->last(); // 4
map()
از این دستور برای ویرایش و بروزرسانی مقادیر یک کالکشن استفاده میشود که معمولا آرگومانی به عنوان یک تابع callback به آن ارسال میشود. توجه داشته باشید ویرایشی که روی یک کالکشن انجام میشود سبب ایجاد یک کالکشن جدید است و کالکشن قبلی به قوت خود باقیست:
$collection = collect([1, 2, 3, 4, 5]); $multiplied = $collection->map(function ($item, $key) { return $item * 2; }); $multiplied->all(); // [2, 4, 6, 8, 10]
mapWithKeys()
این متد برای ویرایش کلیدهای یک کالکشن مورد استفاده قرار میگیرد. آرگومان ورودی آن یک تابع callback است که با انجام عملیات و محاسبات خروجی را مرتبط با یک آرایه یا کلید و مقدار در اختیار قرار میدهد:
$collection = collect([ [ 'name' => 'John', 'department' => 'Sales', 'email' => 'john@example.com' ], [ 'name' => 'Jane', 'department' => 'Marketing', 'email' => 'jane@example.com' ] ]); $keyed = $collection->mapWithKeys(function ($item) { return [$item['email'] => $item['name']]; }); $keyed->all(); /* [ 'john@example.com' => 'John', 'jane@example.com' => 'Jane', ] */
max()
این متد ماکزیمم مقدار یک کالکشن را نمایش میدهد. اگر یک کالکشن کلید داشته باشد به عنوان ورودی به متد max ارسال میگردد:
$max = collect([['foo' => 10], ['foo' => 20]])->max('foo'); // 20 $max = collect([1, 2, 3, 4, 5])->max(); // 5
merge()
از این متد برای ادغام کردن دو کالکشن و یا آرایه استفاده میشود. در صورتیکه یک کالکشن کلیدی داشته باشد که در کالکشن دوم تکرار شده باشد مقدار کالکشن دوم در کالشن اول جایگزین میشود. به مثال زیر توجه کنید:
$collection = collect(['product_id' => 1, 'price' => 100]); $merged = $collection->merge(['price' => 200, 'discount' => false]); $merged->all(); // ['product_id' => 1, 'price' => 200, 'discount' => false]
اگر کلید آرایهها عدد باشد، مقادیر ادغام شده به انتهای کالکشن اول اضافه میشود:
collection = collect(['Desk', 'Chair']); $merged = $collection->merge(['Bookcase', 'Door']); $merged->all(); // ['Desk', 'Chair', 'Bookcase', 'Door']
min()
این متد کمترین مقدار یک آرایه و یا کالکشن را باز میگرداند:
The min method returns the minimum value of a given key: $min = collect([['foo' => 10], ['foo' => 20]])->min('foo'); // 10 $min = collect([1, 2, 3, 4, 5])->min(); // 1
nth()
از این دستور برای ساخت یک کالکشن جدید شامل المانهای n است:
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']); $collection->nth(4); // ['a', 'e']
همانطور که در این مثال مشاهده میکنید مقادیر ایندکس ۰ و ۴ به عنوان یک کالکشن جدید ایجاد میشوند. همچنین میتوان یک آرگومان دوم به این متد داد تا نقطهی شروع یک ایندکس (یا آفست از ایندکس ۰) را مشخص کرد:
$collection->nth(4, 1); // ['b', 'f']
partition()
این متد در بیشتر اوقات با تابع list در PHP برای جداسازی المانهایی که به عنوان یک تابع callback از آرگومان partition خارج میشود، مورد استفاده قرار میگیرد:
$collection = collect([1, 2, 3, 4, 5, 6]); list($underThree, $aboveThree) = $collection->partition(function ($i) { return $i < 3; });
pipe()
از این متد جهت ارسال یک کالکشن به عنوان آرگومان تابع callback و انجام محاسبات و سایر متدهای روی آن کالکشن استفاده میشود:
collection = collect([1, 2, 3]); $piped = $collection->pipe(function ($collection) { return $collection->sum(); }); // 6
pluck()
این متد تمام مقادیر یک موجود در یک کلید را باز میگرداند:
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk'], ['product_id' => 'prod-200', 'name' => 'Chair'], ]); $plucked = $collection->pluck('name'); $plucked->all(); // ['Desk', 'Chair']
همچنین میتوان کلیدسازی جدیدی را بر اساس آرگومان دوم (keys) ایجاد کرد:
$plucked = $collection->pluck('name', 'product_id'); $plucked->all(); // ['prod-100' => 'Desk', 'prod-200' => 'Chair']
pop()
از این متد برای حذف آخرین المان یک کالکشن مورد استفاده قرار میگیرد:
$collection = collect([1, 2, 3, 4, 5]); $collection->pop(); // 5 $collection->all(); // [1, 2, 3, 4]
prepend()
از این متد برای اضافه کردن یک آیتم به ابتدای یک کالکشن استفاده میشود:
$collection = collect([1, 2, 3, 4, 5]); $collection->prepend(0); $collection->all(); // [0, 1, 2, 3, 4, 5]
همچنین میتوان به عنوان آرگومان دوم یک کلید را مشخص کرد و ابتدای کالکشن قرار داد:
$collection = collect(['one' => 1, 'two' => 2]); $collection->prepend(0, 'zero'); $collection->all(); // ['zero' => 0, 'one' => 1, 'two' => 2]
pull()
این دستور برای حذف کردن یک آیتم از کالکشنی با استفاده از کلید آن بهره میبریم:
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']); $collection->pull('name'); // 'Desk' $collection->all(); // ['product_id' => 'prod-100']
push()
برای اضافه کردن یک آیتم به انتهای یک کالکشن مورد استفاده قرار میگیرد:
$collection = collect([1, 2, 3, 4]); $collection->push(5); $collection->all(); // [1, 2, 3, 4, 5]
put()
از متد put برای قرار دادن یک کلید و مقدار به انتهای یک کالکشن مورد استفاده قرار میگیرد:
$collection = collect(['product_id' => 1, 'name' => 'Desk']); $collection->put('price', 100); $collection->all(); // ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random()
این متد یک آیتم رندوم را از یک کالکشن به نمایش میگذارد:
$collection = collect([1, 2, 3, 4, 5]); $collection->random(); // 4 - (retrieved randomly)
همچنین میتوان یک عدد به آرگومان متد random اضافه کرد که نمایانگر تعداد آیتمهاییست که میخواهیم این متد برایمان بازگرداند. به عنوان مثال:
$random = $collection->random(3); $random->all(); // [2, 4, 5] - (retrieved randomly)
reduce()
از این متد برای کاهش یک مجموعه کالکشن به یک مقدار استفاده میشود. این متد دارای یک تابع callback است که دو ورودی میگیرد. ورودی اول carry به عنوان یک متغییر مجازی میباشد که مقدار قبلی متغییر item در آن ذخیره میشود:
$collection = collect([1, 2, 3]); $total = $collection->reduce(function ($carry, $item) { return $carry + $item; }); // 6
اولین مقدار carry همواره null است بنابراین برای مقداردهی اولیه به این متد باید از یک آرگومان دوم به متد reduce اعمال کنیم:
collection->reduce(function ($carry, $item) { return $carry + $item; }, 4); // 10
reverse()
از این متد برای معکوس کردن آیتمهای یک کالکشن استفاده میشود:
$collection = collect([1, 2, 3, 4, 5]); $reversed = $collection->reverse(); $reversed->all(); // [5, 4, 3, 2, 1]
search()
از این متد برای جستجوی درون کالکشنها بر اساس پارامتر ورودیای که دریافت میکند، استفاده میشود و پس از پیدا کردن آن مقدار، کلیدش را باز میگرداند. اگر item پیدا نشد عبارت false چاپ میشود:
$collection = collect([2, 4, 6, 8]); $collection->search(4); // 1
این جستجو گاها ضعیف میباشد، زیرا اگر بخواهیم یک رشته که با عدد ترکیبشده است را درون یکی از آیتمها قرار دهیم، ممکن است مقدار ۴ درون یک رشته با مقدار عدد صحیح ۴ یکسان درنظر گرفته شود. در نتیجه برای محاسبه و جستجوی دقیق تر، عبارت true را به عنوان آرگومان دوم به متد ارسال میکنیم:
$collection->search('4', true); // false
علاوه بر این میتوان یک تابع callback را به عنوان آرگومان ورودی به متد ارسال کرد که خروجی آن اولین مقداریست که شناسایی میکند:
$collection->search(function ($item, $key) { return $item > 5; }); // 2
shift()
از این متد برای حذف کردن اولین آیتم یک کالکشن استفاده میشود:
$collection = collect([1, 2, 3, 4, 5]); $collection->shift(); // 1 $collection->all(); // [2, 3, 4, 5]
shuffle()
از این متد برای چینش رندوم یک کالکشن استفاده میشود:
$collection = collect([1, 2, 3, 4, 5]); $shuffled = $collection->shuffle(); $shuffled->all(); // [3, 2, 5, 1, 4] // (generated randomly)
slice()
از این متد برای ایجاد کردن یک کالکشن جدید از کالکشن جدید با تعداد المانهای مشخص که توسط ایندکس مشخص میشود، استفاده میشود. مثلا در نمونهی زیر از ایندکس ۴ به بعد را درون یک کالکشن جدید قرار خواهیم داد:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $slice = $collection->slice(4); $slice->all(); // [5, 6, 7, 8, 9, 10]
علاوه بر این میتوان سایز یک slice را مشخص کرد تا تعداد مشخصی از المانها و آیتمها را در اختیار داشته باشیم. برای اینکار باید به عنوان آرگومان دوم مقداری را به تابع ارسال کرد:
$slice = $collection->slice(4, 2); $slice->all(); // [5, 6]
توجه داشته باشید که با اعمال این متد کلیدها (یا ایندکسها) حفظ خواهند شد درصورتیکه بخواهیم ایندکس ها یا کلیدها بروزرسانی شوند باید از متد values
استفاده کرد.
sort()
این متد برای مرتب کردن یک کالکشن مورد استفاده قرار میگیرد. پس از اعمال یک sort، همواره کلیدهای اصلی یک کالکشن باقی میماند. در مثال زیر از متد values برای بروزرسانی از ۰ ایندکسها و کلیدها استفاده شده است:
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sort(); $sorted->values()->all(); // [1, 2, 3, 4, 5]
sortBy()
از این متد برای مرتب کردن یک کالکشن و یا آرایهی تو در تو بر اساس کلیدهای آنها استفاده میشود. این روش نیز کلیدهای اصلی آرایهها یا کالکشنها را نگه میدارد. در مثال زیر برای بروزرسانی این کلیدها از متد values نیز استفاده کردهایم:
$collection = collect([ ['name' => 'Desk', 'price' => 200], ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ]); $sorted = $collection->sortBy('price'); $sorted->values()->all(); /* [ ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ['name' => 'Desk', 'price' => 200], ] */
همچنین میتوان یک تابع callback به عنوان ورودی به متد sortBy ارسال کرد تا محاسباتی را انجام داده و به متد sortBy باز گرداند:
$collection = collect([ ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], ]); $sorted = $collection->sortBy(function ($product, $key) { return count($product['colors']); }); $sorted->values()->all(); /* [ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], ] */
sortByDesc()
این متد دقیقا مشابه متد sortBy است با این تفاوت که به صورت نزولی خروجی را نمایش میدهد.
splice()
از این متد برای حذف یک بخش از آیتمها در یک ایندکس مشخص استفاده میشود:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2); $chunk->all(); // [3, 4, 5] $collection->all(); // [1, 2]
برای قرار دادن یک سایز مشخص باید از آرگومان دوم استفاده کرد:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1); $chunk->all(); // [3] $collection->all(); // [1, 2, 4, 5]
همچنین میتوان یک آرگومان سوم شامل آیتمهای جدید به مجموعهی کالکشن قبلی اضافه کرد که با مقدار حذفشده، جایگزین میشود:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1, [10, 11]); $chunk->all(); // [3] $collection->all(); // [1, 2, 10, 11, 4, 5]
split()
برای تقسیم کردن یک مجموعه به اجزای کوچکتر مورد استفاده قرار میگیرد. در مثال زیر یک کالکشن به ۳ کالکشن کوچکتر تبدیل شده است:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1, [10, 11]); $chunk->all(); // [3] $collection->all(); // [1, 2, 10, 11, 4, 5]
sum()
از این دستور برای مجموع تمام المانهای یک کالکشن استفاده میشود:
collect([1, 2, 3, 4, 5])->sum(); // 15
اگر یک کالکشن شامل آرایهها یا اشیاء تودرتو بود میتوان با ارسال کلید مشخصی، دستور sum را برای مجموع مقادیر آن بکار برد:
$collection = collect([ ['name' => 'JavaScript: The Good Parts', 'pages' => 176], ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096], ]); $collection->sum('pages'); // 1272
همچنین میتوان یک تابع callback به عنوان ورودی به این متد ارسال کرد:
$collection = collect([ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], ]); $collection->sum(function ($product) { return count($product['colors']); }); // 6
take()
از این متد برای بازگرداندن یک کالکشن جدید همراه با تعداد مشخصی آیتم استفاده میشود:
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(3); $chunk->all(); // [0, 1, 2]
همانطور که ملاحظه میکنید المانهای قبل از ایندکس سوم یعنی ۰ و ۱ و ۲ بازگردانده شده است. علاوه بر این میتوان یک عدد منفی به آرگومان ارسال کرد تا آیتمهای باقی مانده به آخر را به شما باز گرداند. مثلا در نمونهی زیر المانهای ۴ و ۵ با ارسال آرگومان ۲- بازگردانده خواهد شد.
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(-2); $chunk->all(); // [4, 5]
toArray()
با استفاده از متد toArray یک کالکشن به آرایههای خام PHP تبدیل میشود. اگر مقادیر کالکشن موردنظر از مدل Eloquent استخراج شده بود، این مدل همیشه به صورت خودکار به آرایه تبدیل میشود:
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toArray(); /* [ ['name' => 'Desk', 'price' => 200], ] */
toJson()
از این متد برای تبدیل کالکشنها به دادهی JSON استفاده میشود:
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toJson(); // '{"name":"Desk", "price":200}'
transform()
این متد روی هر المان یک کالکشن و فراخوانی یک تابع callback برای هر المان، تکرار میشود. با اعمال این دستور یک کالکشن جدید ایجاد نمیشود بلکه کالکشن قبلی ویرایش خواهد شد. به مثال زیر توجه کنید:
$collection = collect([1, 2, 3, 4, 5]); $collection->transform(function ($item, $key) { return $item * 2; }); $collection->all(); // [2, 4, 6, 8, 10]
توجه: از این متد برای ویرایش یک کالکشن استفاده میشود و مقادیر آن دقیقا روی کالکشن جدید اعمال خواهد شد، درصورتیکه میخواهید تغییرات روی کالکشن در یک کالکشن جدید ذخیره شود از دستور map استفاده کنید که در فوق به آن اشاره کردیم.
union()
متد union یک آرایه را به یک کالکشن اضافه میکند. اگر آرایه موردنظر شامل کلیدهایی باشد که درون کالکشن اصلی موجود باشد آنگاه کلیدهای موجود در کالکشن اصلی مقدم تر هستند!
$collection = collect([1 => ['a'], 2 => ['b']]); $union = $collection->union([3 => ['c'], 1 => ['b']]); $union->all(); // [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique()
این متد تمام مقادیر یکتای یک کالکشن را ارسال میکند. کلیدهای کالکشن جدید برابر کلید کالکشن اصلی است. در مثال زیر از متد values برای بروزرسانی کلید استفاده میشود:
$collection = collect([1, 1, 2, 2, 3, 4, 2]); $unique = $collection->unique(); $unique->values()->all(); // [1, 2, 3, 4]
در صورتیکه آرایهها یا اشیاء تودرتو وجود داشت میتوان یک کلید مشخص را انتخاب کرده و مقادیر یکتای آنها را چاپ کرد:
$collection = collect([ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], ]); $unique = $collection->unique('brand'); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ] */
همچنین میتوان یک تابع callback را به ورودی متد ارسال کرد:
$unique = $collection->unique(function ($item) { return $item['brand'].$item['type']; }); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], ] */
values()
این متد کلیدهای موجود در یک کالکشن جدید را reset میکند یا از ابتدا شمارهگذاری خواهد کرد:
$collection = collect([ 10 => ['product' => 'Desk', 'price' => 200], 11 => ['product' => 'Desk', 'price' => 200] ]); $values = $collection->values(); $values->all(); /* [ 0 => ['product' => 'Desk', 'price' => 200], 1 => ['product' => 'Desk', 'price' => 200], ] */
when()
این متد همواره یک callback دارد که در صورت true بودن آرگومان اول تابع callback محاسبه میشود:
$collection = collect([1, 2, 3]); $collection->when(true, function ($collection) { return $collection->push(4); }); $collection->all(); // [1, 2, 3, 4]
where()
از این متد برای فیلتر کردن کالکشنها بر اساس کلید/ مقدار دریافتی استفاده میشود:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]); $filtered = $collection->where('price', 100); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ] */
متد where در مقایسه مقادیر خیلی قوی عمل نمیکند بنابراین در صورتیکه میخواهید مقادیر یک کالکشن را مقایسه و فیلتر کنید بهتر است از whereStrict استفاده کنید که در ادامه به توضیح آن میپردازیم:
whereStrict()
این متد مشابه متد where است با این تفاوت که مقایسهی قدرتمندتری را بین مقادیر انجام میدهد. یعنی ابتدا نوع متغییر را در نظر میگیرد و سپس آنها را با هم مقایسه میکند به عبارتی where شبیه اپراتور == عمل میکند و whereStrict شبیه اپراتور ===.
whereIn()
این متد بر اساس کلید/مقدار آرایهای دریافتی یک کالکشن را فیلتر میکند:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]); $filtered = $collection->whereIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Bookcase', 'price' => 150], ['product' => 'Desk', 'price' => 200], ] */
برای دقت بیشتر در مقایسه و فیلتر کردن بهتر است از دستور whereInStrict استفاده شود.
whereInStrict()
این متد مشابه متد whereIn میباشد با این تفاوت که مقایسهی قویتری را انجام میدهد.
whereNotIn()
این متد مقادیری را که برابر با کلید و مقدار مشخص شده نیستند، باز میگرداند:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]); $filtered = $collection->whereNotIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ] */
برای دقت بیشتر و قدرت فیلترینگ بالاتر میتوان از دستور whereNotInStrict استفاده کرد:
whereNotInStrict()
از این دستور برای فیلترینگ قدرتمندتر استفاده میشود.
zip()
این متد مقادیر موجود در ورودی تابع zip را با مقادیر کالکشن بر اساس ایندکس آنها ادغام میکند:
$collection = collect(['Chair', 'Desk']); $zipped = $collection->zip([100, 200]); $zipped->all(); // [['Chair', 100], ['Desk', 200]]
بسیار عالی! با مطالعهی این فصل طولانی با تمام متدهای موجود در لاراول برای استفاده در مدلها آشنا شدید. این متدها به شما کمک میکنند تا در دستیابی به اطلاعات دیتابیس سریعتر عمل کنید. در فصل آینده به توضیح دقیق modelها پرداخته و مباحث آن را به پایان میرسانیم. با ما همراه باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.