🚀 جلوگیری از مشکل 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($noscript));
یا از متغیرهای موقتی استفاده میشد:
$trim = trim($noscript);
$result = strtolower($trim);
اما با استفاده از پایپ می توان ساختار تمیزتر و قابل فهمتری را داشته باشیم:
$result = $noscript
|> trim(...)
|> strtolower(...);
ترتیب اجرای عملیات کاملا روشن و خوانا است:
ابتدا
trim، سپس strtolower.ترکیب توابع استاندارد با Closure
$slug = $noscript
|> 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
👍3
پکیج امروز: 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
🔥2
برای مدیریت نقشها و دسترسیها در اپهای متوسط و بزرگ لاراول، پکیج spatie/laravel-permission تقریبا استاندارد صنعت شده. بهجای ifهای تو در تو و چککردن role در هر کنترلر، یک سیستم تمیز و قابلگسترش میدهد. 🔐
چند مزیت مهم:
• تعریف role و permission در دیتابیس، نه هاردکد 🧱
• متدهای آماده روی مدل User مثل:
• Middleware برای محدود کردن routeها
• هماهنگ با Gate/Policy خود لاراول
نصب و راهاندازی سریع:
در پروژههای تیمی، این پکیج جلوی کلی if بیمنطق و duplication را میگیرد و مدیریت پنل ادمین، سطح دسترسی API و نقشهای مختلف (admin, editor, support) را تمیز میکند. ✨
مستندات رسمی:
Docs
GitHub
امتحانش در یک پروژه واقعی حس خوبی از نظم و کنترل روی Authorization میدهد. 😉
🔖 #Laravel #PHP #لاراول #Laravel #spatie #laravel_permission #PHP #Authorization #Role #Permission
👤 Developix
💎 Channel: @DevelopixLaravel
چند مزیت مهم:
• تعریف role و permission در دیتابیس، نه هاردکد 🧱
• متدهای آماده روی مدل User مثل:
hasRole ،can• Middleware برای محدود کردن routeها
• هماهنگ با Gate/Policy خود لاراول
نصب و راهاندازی سریع:
composer require spatie/laravel-permission
php artisan vendor:publish \
--provider\=\"Spatie\\Permission\\PermissionServiceProvider\"
php artisan migrate
// در مدل User:
use Spatie\\Permission\\Traits\\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}
// استفاده در کد:
$user->assignRole('admin');
if ($user->can('edit articles')) {
// ...
}
در پروژههای تیمی، این پکیج جلوی کلی if بیمنطق و duplication را میگیرد و مدیریت پنل ادمین، سطح دسترسی API و نقشهای مختلف (admin, editor, support) را تمیز میکند. ✨
مستندات رسمی:
Docs
GitHub
امتحانش در یک پروژه واقعی حس خوبی از نظم و کنترل روی Authorization میدهد. 😉
🔖 #Laravel #PHP #لاراول #Laravel #spatie #laravel_permission #PHP #Authorization #Role #Permission
👤 Developix
💎 Channel: @DevelopixLaravel
👍4
🔎 در قطعهکد بالا، در روش اول برای محاسبه آمار سفارشها، هر بار که روی یک
🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
user لوپ میزنیم، چندین کوئری جدید به دیتابیس اجرا میشود (مشکل N+1 Query) و همچنین محاسباتی مثل مجموع مبالغ سفارشهای تکمیلشده را داخل PHP انجام میدهیم. در روش دوم با استفاده از Aggregation Query در خود دیتابیس و بهکارگیری Eager Loading و توابعی مثل withSum و withCount، هم تعداد کوئریها کاهش پیدا میکند، هم فشار زیادی از روی PHP برداشته میشود و کارایی سیستم در سناریوهایی مثل گزارشگیری روی تعداد زیاد کاربر و سفارش، بهطور محسوسی بهتر میشود. بهنظر شما در پروژههای واقعی لاراول، چه زمانی بهتر است این نوع محاسبات را از سطح PHP به سطح دیتابیس منتقل کنیم تا هم پیچیدگی کد کم شود و هم Performance بالاتر برود؟🔖 #Laravel #PHP #لاراول
👤 Developix
💎 Channel: @DevelopixLaravel
👍11❤4
خیلی وقتها توی پروژههای Laravel بیدلیل همهٔ ستونهای جدول رو لود میکنیم، درحالیکه فقط ۲–۳ تا فیلد لازم داریم. همین کار ساده میتونه رم، زمان اجرا و حجم پاسخ API رو بیخودی سنگین کنه. 🚀
بهجای این:
فقط همون فیلدهایی که لازم هست رو بگیر:
حالا اگه رابطه هم داری (مثلاً posts)، باز هم میشه کمحجم نگهش داشت:
✅ نکتهها:
- ستون کلید خارجی (مثلاً
- برای APIها و لیستهای بزرگ (لیست کاربران، محصولات، گزارشها) این کار واقعاً روی Performance تاثیر محسوس داره.
- موقع debug میشه موقتاً select رو برداشت تا مطمئن شد چیزی جا نمونده، بعد دوباره بهینهاش کرد. 😉
این عادت کوچیک که همیشه توی Queryها به
برای جزئیات بیشتر مستند رسمی Laravel در مورد Eloquent & Query Builder:
https://laravel.com/docs/11.x/queries#select-statements
🔖 #Laravel #PHP #لاراول #Laravel #Eloquent #Performance #Query #select
👤 Developix
💎 Channel: @DevelopixLaravel
بهجای این:
$users = User::where('is_active', true)->get();
فقط همون فیلدهایی که لازم هست رو بگیر:
$users = User::where('is_active', true)
->select(['id', 'name', 'email'])
->get();
حالا اگه رابطه هم داری (مثلاً posts)، باز هم میشه کمحجم نگهش داشت:
$users = User::with(['posts:id,user_id,noscript'])
->select(['id', 'name'])
->get();
✅ نکتهها:
- ستون کلید خارجی (مثلاً
user_id) حتماً توی select رابطه بیاد، وگرنه Eloquent نمیتونه رابطه رو درست مپ کنه.- برای APIها و لیستهای بزرگ (لیست کاربران، محصولات، گزارشها) این کار واقعاً روی Performance تاثیر محسوس داره.
- موقع debug میشه موقتاً select رو برداشت تا مطمئن شد چیزی جا نمونده، بعد دوباره بهینهاش کرد. 😉
این عادت کوچیک که همیشه توی Queryها به
select فکر کنی، جلوی کلی Memory Leak ریز و Query سنگین توی پروژههای بزرگ رو میگیره و API تمیزتر و سریعتری تحویل میده. 💡برای جزئیات بیشتر مستند رسمی Laravel در مورد Eloquent & Query Builder:
https://laravel.com/docs/11.x/queries#select-statements
🔖 #Laravel #PHP #لاراول #Laravel #Eloquent #Performance #Query #select
👤 Developix
💎 Channel: @DevelopixLaravel
👍16🔥1
Forwarded from ابر ویراک
زیرساختی مطمئن برای کسب و کارهای آنلاین
📞 همین حالا با ما تماس بگیرید و این فرصت فوقالعاده رو از دست ندید!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1