🚀 جلوگیری از مشکل N+1 در Eloquent با eager loading و withCount
خیلی از باگها و افت کارایی در اپهای لاراول از درخواستهای اضافی دیتابیس (مشکل N+1) ناشی میشه. با استفاده از eager loading و withCount میتونید هم تعداد کوئریها رو کم کنید و هم اطلاعاتی مثل تعداد ارتباطها رو بدون کوئریهای اضافی بگیرید. 💡
مثال عملی: فرض کنید مدل Post و رابطه comments دارید. اگر بدون eager loading لیست پستها رو رندر کنید، هر بار که به comments دسترسی پیدا میکنید یک کوئری جدید اجرا میشه — N+1.
راه ساده و بهینه:
نکات عملی و بهترین روشها:
- وقتی فقط تعداد رابطه لازم دارید از withCount استفاده کنید تا دادههای اضافی لود نشه. 🔍
- برای بارگذاری شرطی (مثلاً فقط کامنتهای تاییدشده) از closure در with استفاده کنید:
- برای دیتاستهای بزرگ از chunk یا cursor استفاده کنید تا حافظه پر نشه. ⚠️
اشتباه رایج: افزودن eager loading برای روابطی که هرگز استفاده نمیشن — فقط روابط لازم را بارگذاری کنید تا از overhead جلوگیری کنید.
با این روش ساده، کوئریها بهمراتب کمتر و صفحهها سریعتر بارگذاری میشن. امتحان کنید و بازخورد یا تجربهتون رو به اشتراک بذارید. 🙌
Laravel Docs — Eloquent Relationships
🔖 #Laravel #PHP #لاراول #Laravel #Eloquent #Performance #EagerLoading
👤 Developix
💎 Channel: @DevelopixLaravel
خیلی از باگها و افت کارایی در اپهای لاراول از درخواستهای اضافی دیتابیس (مشکل N+1) ناشی میشه. با استفاده از eager loading و withCount میتونید هم تعداد کوئریها رو کم کنید و هم اطلاعاتی مثل تعداد ارتباطها رو بدون کوئریهای اضافی بگیرید. 💡
مثال عملی: فرض کنید مدل Post و رابطه comments دارید. اگر بدون eager loading لیست پستها رو رندر کنید، هر بار که به comments دسترسی پیدا میکنید یک کوئری جدید اجرا میشه — N+1.
راه ساده و بهینه:
$posts = Post::with('comments')->get();
foreach ($posts as $post) {
// دسترسی به رابطه بدون کوئری اضافی
echo $post->comments->count();
}
// اگر فقط تعداد نیاز دارید، از withCount استفاده کنید:
$posts = Post::withCount('comments')->get();
foreach ($posts as $post) {
echo $post->comments_count; // مقدار از همان کوئری اصلی
}
نکات عملی و بهترین روشها:
- وقتی فقط تعداد رابطه لازم دارید از withCount استفاده کنید تا دادههای اضافی لود نشه. 🔍
- برای بارگذاری شرطی (مثلاً فقط کامنتهای تاییدشده) از closure در with استفاده کنید:
with(['comments' => fn($q) => $q->where('approved', 1)]).- برای دیتاستهای بزرگ از chunk یا cursor استفاده کنید تا حافظه پر نشه. ⚠️
اشتباه رایج: افزودن eager loading برای روابطی که هرگز استفاده نمیشن — فقط روابط لازم را بارگذاری کنید تا از overhead جلوگیری کنید.
با این روش ساده، کوئریها بهمراتب کمتر و صفحهها سریعتر بارگذاری میشن. امتحان کنید و بازخورد یا تجربهتون رو به اشتراک بذارید. 🙌
Laravel Docs — Eloquent Relationships
🔖 #Laravel #PHP #لاراول #Laravel #Eloquent #Performance #EagerLoading
👤 Developix
💎 Channel: @DevelopixLaravel
❤9👍1
در کد بالا در متد index برای صفحهبندی لیست پستها از load کردن تمام رکوردها در Memory و سپس جمعآوری آنها با
🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
collect() و forPage() استفاده شده که هم مصرف مموری را بالا میبرد و هم در صورت زیاد بودن تعداد رکوردها باعث افت کارایی میشود. در عوض میتوانید مستقیماً روی QueryBuilder از paginate() استفاده کنید تا صفحهبندی در سطح دیتابیس انجام شود و فقط رکوردهای همان صفحه Query شوند. بهنظر شما در پروژههای واقعی با دیتاست بزرگ، استفاده از کدام روش منطقیتر و مقیاسپذیرتر است؟🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
👍10❤1
Forwarded from | کانال توسعهدهندگان PHP |
عملگر پایپ (Pipe Operator) در PHP
عملگر پایپ (
ساختار کلی عملگر پایپ:
در این ساختار:
- مقدار سمت چپ (value) محاسبه شده و سپس به تابع سمت راست (callable) ارسال میشود، و نتیجهٔ آن تابع، خروجی نهایی عبارت خواهد بود.
- تابع سمت راست باید فقط یک پارامتر لازم داشته باشد؛ زیرا همان یک پارامتر از پایپ دریافت میشود.
- نماد (
چند مثال:
پیش از اضافه شدن پایپ تواع پشت سر هم نوشته میشد:
یا از متغیرهای موقتی استفاده میشد:
اما با استفاده از پایپ می توان ساختار تمیزتر و قابل فهمتری را داشته باشیم:
ترتیب اجرای عملیات کاملا روشن و خوانا است:
ابتدا
ترکیب توابع استاندارد با Closure
از آنجایی که گفته شد توابع تنها یک متد داشته باشند، برای توابع با چند متد میتوان از کلوژرها استفاده کرد.
در این مثال
عملیات روی آرایه
چنین زنجیرهای بدون استفاده از پایپ، بهطور معمول شامل متغیرهای واسطه یا تو در تویی توابع خواهد بود؛ اما با استفاده از پایپ، تمامی مراحل به صورت خوانا پشت سر هم نوشته شدهاند.
مزایای استفاده از عملگر پایپ:
- جریان داده از بالا به پایین قابل مشاهده است و عملیات به شکلی خطی بیان میشوند.
- بهجای اینکه توابع داخل یکدیگر قرار بگیرند، هر تابع بهطور مستقل در یک مرحله اجرا میشود.
- نیازی به ایجاد متغیر برای ذخیرهٔ نتیجهٔ هر مرحله نیست.
محدودیتها و نکات مهم:
- توابعی که بیش از یک پارامتر ضروری دارند، مستقیماً با پایپ قابل استفاده نیستند.
- توابعی که پارامترشان با ارجاع (By Reference) دریافت میشود قابل استفاده نیستند (مانند
- اگر تابعی مقدار بازگشتی نداشته باشد (void)، نتیجهٔ عملیات null خواهد بود و استفادهٔ آن در میانهٔ زنجیره صحیح نیست.
به طور کلی عملگر پایپ در PHP 8.5 امکان نگارش کدی خواناتر، مرحلهای و ساختیافته را فراهم میکند.
این عملگر با ارسال خروجی هر مرحله به مرحلهٔ بعد، جریان داده را سادهسازی میکند و برای پردازش رشتهها، آرایهها و دادههای میانمرحلهای بسیار مناسب است.
در مقابل، محدودیتهایی نظیر نیاز به تکپارامتری بودن تابع یا عدم پشتیبانی از توابع دارای ارجاع وجود دارد که باید در استفادهٔ روزمره مورد توجه قرار گیرد.
🔖 #PHP #پی_اچ_پی
👤 AmirHossein
💎 Channel: @DevelopixPHP
عملگر پایپ (
|> ) از PHP 8.5 با هدف سادهسازی جریان داده و افزایش خوانایی کد اضافه شده است. این عملگر امکان میدهد خروجی یک عبارت بهعنوان ورودی تابع بعدی استفاده شود؛ بدون آنکه نیاز به تو در تو کردن فراخوانیها یا استفاده از متغیرهای موقتی باشد.ساختار کلی عملگر پایپ:
$value |> callable;
در این ساختار:
- مقدار سمت چپ (value) محاسبه شده و سپس به تابع سمت راست (callable) ارسال میشود، و نتیجهٔ آن تابع، خروجی نهایی عبارت خواهد بود.
- تابع سمت راست باید فقط یک پارامتر لازم داشته باشد؛ زیرا همان یک پارامتر از پایپ دریافت میشود.
- نماد (
... ) پس از نام تابع، بیانگر این است که پارامتر آن تابع از طریق عملگر پایپ وارد میشود.چند مثال:
پیش از اضافه شدن پایپ تواع پشت سر هم نوشته میشد:
$result = strtolower(trim($title));
یا از متغیرهای موقتی استفاده میشد:
$trim = trim($title);
$result = strtolower($trim);
اما با استفاده از پایپ می توان ساختار تمیزتر و قابل فهمتری را داشته باشیم:
$result = $title
|> trim(...)
|> strtolower(...);
ترتیب اجرای عملیات کاملا روشن و خوانا است:
ابتدا
trim، سپس strtolower.ترکیب توابع استاندارد با Closure
$slug = $title
|> trim(...)
|> (fn($s) => str_replace(' ', '-', $s))
|> strtolower(...);
از آنجایی که گفته شد توابع تنها یک متد داشته باشند، برای توابع با چند متد میتوان از کلوژرها استفاده کرد.
در این مثال
str_replace نیاز به پارامترهای بیشتری است به همین دلیل از arrow-function استفاده شده.عملیات روی آرایه
$clean = $items
|> array_map(fn($x) => trim($x), ...)
|> array_filter(fn($x) => $x !== '', ...)
|> array_values(...);
چنین زنجیرهای بدون استفاده از پایپ، بهطور معمول شامل متغیرهای واسطه یا تو در تویی توابع خواهد بود؛ اما با استفاده از پایپ، تمامی مراحل به صورت خوانا پشت سر هم نوشته شدهاند.
مزایای استفاده از عملگر پایپ:
- جریان داده از بالا به پایین قابل مشاهده است و عملیات به شکلی خطی بیان میشوند.
- بهجای اینکه توابع داخل یکدیگر قرار بگیرند، هر تابع بهطور مستقل در یک مرحله اجرا میشود.
- نیازی به ایجاد متغیر برای ذخیرهٔ نتیجهٔ هر مرحله نیست.
محدودیتها و نکات مهم:
- توابعی که بیش از یک پارامتر ضروری دارند، مستقیماً با پایپ قابل استفاده نیستند.
"hello world" |> explode(' ', ...); // ERROR
"hello world" |> (fn($v) => explode(' ', $v)); // correct- توابعی که پارامترشان با ارجاع (By Reference) دریافت میشود قابل استفاده نیستند (مانند
array_pop یا sort)- اگر تابعی مقدار بازگشتی نداشته باشد (void)، نتیجهٔ عملیات null خواهد بود و استفادهٔ آن در میانهٔ زنجیره صحیح نیست.
به طور کلی عملگر پایپ در PHP 8.5 امکان نگارش کدی خواناتر، مرحلهای و ساختیافته را فراهم میکند.
این عملگر با ارسال خروجی هر مرحله به مرحلهٔ بعد، جریان داده را سادهسازی میکند و برای پردازش رشتهها، آرایهها و دادههای میانمرحلهای بسیار مناسب است.
در مقابل، محدودیتهایی نظیر نیاز به تکپارامتری بودن تابع یا عدم پشتیبانی از توابع دارای ارجاع وجود دارد که باید در استفادهٔ روزمره مورد توجه قرار گیرد.
🔖 #PHP #پی_اچ_پی
👤 AmirHossein
💎 Channel: @DevelopixPHP
❤11👍1👎1
🔎 سوال برای توسعهدهندگان Laravel / PHP
خروجی اجرای این کد PHP چیست؟
به تفاوت بین type casting و type juggling در PHP و تاثیر آن روی کلیدهای آرایه دقت کنید.
خروجی کامل تابع
🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
خروجی اجرای این کد PHP چیست؟
به تفاوت بین type casting و type juggling در PHP و تاثیر آن روی کلیدهای آرایه دقت کنید.
$data = [
"01" => "first",
1 => "second",
true => "third",
"1" => "fourth",
];
var_dump($data);
خروجی کامل تابع
var_dump را بنویسید (ساختار آرایه و مقادیر آن).🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
👍2
پکیج امروز: Spatie Laravel Ray 🔍
یک دیباگر زنده که لاگها و query و jobها را به اپ دسکتاپ Ray میفرستد؛ مخصوص وقتی که var_dump و dd کل صفحه را منفجر میکنند 🙂
به چه درد میخورد؟
• دیدن لاگها، queryها، exceptionها بهصورت لحظهای
• گروهبندی، فیلتر و استایلدهی به لاگها
• دیباگ queue job، event، mail و حتی cache
نصب
نمونه استفاده در کنترلر
برای پروژههای بزرگ لاراول که لاگخوانی در فایل سخت میشود، Ray جریان دیباگ را خیلی تمیز و قابلردیابی میکند. ارزش دارد یکبار روی یک feature واقعی تست شود و تنظیماتش را مطابق نیاز تیمتان شخصیسازی کنید 🚀
لینکها:
GitHub
Docs
🔖 #Laravel #PHP #لاراول #Laravel #PHP #Spatie #Debugging #Laravel_Ray
👤 Developix
💎 Channel: @DevelopixLaravel
یک دیباگر زنده که لاگها و query و jobها را به اپ دسکتاپ Ray میفرستد؛ مخصوص وقتی که var_dump و dd کل صفحه را منفجر میکنند 🙂
به چه درد میخورد؟
• دیدن لاگها، queryها، exceptionها بهصورت لحظهای
• گروهبندی، فیلتر و استایلدهی به لاگها
• دیباگ queue job، event، mail و حتی cache
نصب
composer require spatie/laravel-ray --dev
php artisan vendor:publish \
--provider\="Spatie\LaravelRay\RayServiceProvider"
نمونه استفاده در کنترلر
use Spatie\LaravelRay\Ray;
public function index()
{
ray('Load products');
$products = Product::with('category')
->where('active', true)
->get();
ray($products)->blue();
return view('products.index', compact('products'));
}
برای پروژههای بزرگ لاراول که لاگخوانی در فایل سخت میشود، Ray جریان دیباگ را خیلی تمیز و قابلردیابی میکند. ارزش دارد یکبار روی یک feature واقعی تست شود و تنظیماتش را مطابق نیاز تیمتان شخصیسازی کنید 🚀
لینکها:
GitHub
Docs
🔖 #Laravel #PHP #لاراول #Laravel #PHP #Spatie #Debugging #Laravel_Ray
👤 Developix
💎 Channel: @DevelopixLaravel