محمدسجاد دباغ
3 سال پیش توسط محمدسجاد دباغ مطرح شد
20 پاسخ

استفاده از عملگر در php

سلام وقت بخیر
در یکی از مدل ها تابع زیر را دارم و نیاز هست که مجموع duration ویدئوها کحاسبه بشه.
اما خط ششم درست نیست.
چه کاری باید انجام داد؟

public function topic_duration()
    {
        $allTopic = $this->hasMany(Topic::class , "workshop_id" , "id");
        foreach ($allTopic as $topic) {
            $file = File::find($topic->file_id)->first();
            $duration += $file->video_duration;
        }
        return $duration;
    }

ثبت پرسش جدید
Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش آپدیت شد
0

و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.

چالش تمومی نداره. خود پی‌اچ‌پی رو درست و حسابی یاد بگیرین. مثلاً اینو ببینین:
https://phptherightway.com/
بعدش لاراول رو درست و حسابی یاد بگیرین و داکیومنتیشنش رو بخونین. آموزش‌های آقای ایمان غفوری کم‌نظیره. اگه انگلیسی بلدین که جفری‌وی ترکونده. بعدش یه دیتابیس رابطه‌ای (MySQL یا PostgreSQL) یاد بگیرین. این رودمپ خیلی خوبه:
https://roadmap.sh/

این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.

شما یه متد می‌سازین که قراره یه Relation برگردونه، مثل topic (درستش اینه که بنویسین topics چون one to many هست)، بعضی متدها هم قراره یه مقدار خاصی رو برگردونن و قرار نیست توی این متدهاتون با با مدل‌های دیگه ارتباط درست کنین. شما topics رو داشته باشین و داخلش همون Relation رو برگردونین، بعد توی متد getTopicsDuration که درست می‌کنین...

بیشتر راهنمایی میکنید؟

چرا که نه؟ شما با متد topics یه Relation برمی‌گردونین و Relation با Collection فرق داره. شما می‌خوایین به رکوردهای اون یکی جدول دسترسی پیدا کنین، پس کدتون اینطوری میشه:

 foreach ($this->topics as $topic) {
 .
 .
 .

وقتی بنویسیم this->topics$ ، یه کالکشن داریم که میشه داخل foreach گذاشت و یکی یکی تاپیک‌هارو گرفت. البته میشه این جمع رو از طریق دیتابیس انجام داد و دیگه نیازی نیست حلقه نوشت و یکی یکی اضافه کرد.


moha li
تخصص : توسعه دهنده لاراول و Vue
@mohaligateway 3 سال پیش مطرح شد
0

سلام
مگه جاوا اسکریپت هستش ؟؟؟؟
باید به جای + از . استفاده کنید.
@msdabbagh


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@mohaligateway
من جاوا اسکریپت زیاد خوندم 😀
بجای + نقطه بزارم یعنی این؟

$duration .= $file->video_duration;

moha li
تخصص : توسعه دهنده لاراول و Vue
@mohaligateway 3 سال پیش مطرح شد
-1

بله باید به جای مثبت از نقطه استفاده کنید. 😏
@msdabbagh


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@mohaligateway
مطمعن هستید؟ چون عمل نمیکنه.
در روش خودم و روش شما، زیر $duration خط قرمز کشیده میشود.


رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
-1

@mohaligateway درست میگه اگر اونجا رو خط کشی کرده باید یه نمونه از $filet رو ارسال کنی


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@Rp76 یک نمونه از file کجا ارسال کنم؟ متوجه نشدم.


moha li
تخصص : توسعه دهنده لاراول و Vue
@mohaligateway 3 سال پیش مطرح شد
0

شما به خط قرمز IDE کاری نداشته باشید بعضی وقت ها نمی تونه بخونه الان ارور دارید هنگام اجرا کردن کد بالا ؟ ارورش چیه ؟
@msdabbagh


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@mohaligateway
@Rp76

Undefined variable: duration

محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش آپدیت شد
0

@mohaligateway
@Rp76
کد رو به شکل زیر تغییر دادم و مشکل Undefined variable حل شد.

public function topic_duration()
    {
        $allTopic = $this->hasMany(Topic::class , "workshop_id" , "id");
        $duration = 0;
        foreach ($allTopic as $topic) {
            $file = File::find($topic->file_id)->first();
            $duration .= $file->video_duration;
        }
        return $duration;
    }

اما عدد صفر برمیگرده.


رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

من میگم نتیجه خط ۶ رو برامون بفرست ببینیم

نمیخوام فایل رو اپلود کنی که!


moha li
تخصص : توسعه دهنده لاراول و Vue
@mohaligateway 3 سال پیش مطرح شد
0

خوب باید جمع بزنید. حالا اون قسمت اول رو که با . نوشتید باید به + تبدیل کنید.

$duration+= $file->video_duration

@msdabbagh


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش آپدیت شد
0

@Rp76

من میگم نتیجه خط ۶ رو برامون بفرست ببینیم

نتیجه خط ششم هیچی نیست، حتی $topic هم خالیه 🤔

روش دیگه ای برای این کار هست؟ مجموع یک فیلد در رکوردهای file به شرط اینکه اون فایل در topic آمده باشه و اون topic هم زیرمجموعه workshop باشه.

workshop -> topics -> files -> sum filds videoduration

رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

والا من که نمیدونم پروژه چیه
پس نمیتونم متوجه بشم چی میگی!


Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش آپدیت شد
1

@mohaligateway
چه ربطی به جاواسکریپت داره؟ توی PHP از . برای جوین استفاده میشه ولی + برای جمعه و کار این دوتا فرق داره.

<?php
$num = 12;
$num += 10;
echo $num; // 22

moha li
تخصص : توسعه دهنده لاراول و Vue
@mohaligateway 3 سال پیش مطرح شد
0

بله شما درست می فرمائید @muhammad . دقت نکردم اول کار کد ها یه کم نامفهوم بود داخل چرخه و نمی دونستم می خوان summation کنن.


Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش آپدیت شد
2

اشتباه شما از اول این بود که =+ رو استفاده کردین. این شکل کوتاه‌شده x=x+y هست و کلا برای جمع باید قبلش duration تعریف شده باشه و بعد چیزی باهاش جمع بسته بشه، ولی وقتی هنوز تعریف نشده، مقداری نداره تا یه مقدار دیگه باهاش جمع بشه. اشتباه دوم ریختن قیمه (Relation) توی ماست (متد معمولی که انتظار نمیره رلیشن ایجاد کنه) بوده. اشتباه سوم استفاده مستقیم از Relation بوده، شما نمی‌تونین Relation رو داخل foreach بذارین، باید با get نتیجه رو به صورت Collection بگیرین.

حدس می‌زنم دارین از یه سری آموزش ویدئویی استفاده می‌کنین ولی نمی‌دونین چرا مدرس فلان کار رو کرده فقط تکرارش می‌کنین. مفاهیم رو یاد بگیرین و زیاد دنبال آموزش پروژه محور نباشین. باید بدونین رلیشن رو کجا می‌زنین، چه خروجی داره، چند نوع داره، چرا استفاده میشه، چه‌طور لاراول هندلش می‌کنه و الی آخر. اینارو بدونین، می‌تونین خودتون دوره ضبط کنین و بفرستین ما استفاده کنیم.
@msdabbagh


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@muhammad
سلام وقت بخیر
من تنها دوره ای که در مورد لاراول دیدم دوره لاراول راکت هست که در حد احرازهویت و انتشار و مدیریت پست بود.
و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.


حالا طبق گفته های شما یک مقدار راهنمایی بیشتر نیاز دارم.

متد معمولی که انتظار نمیره رلیشن ایجاد کنه

این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.


استفاده مستقیم از Relation بوده، شما نمی‌تونین Relation رو داخل foreach بذارین، باید با get نتیجه رو به صورت Collection بگیرین.

ما توی همون مدل متد زیر رو به صورت مستقیم ایجاد کردیم و به درستی قابل اجراست.

public function topic()
    {
        return $this->hasMany(Topic::class , "workshop_id" , "id");
    }

و دلیل اینکه در اون قسمت Relation رو داخل foreach گذاشتم این بود که به ازای هر topic فایل متصل به اون رو به دست بیارم.


باید با get نتیجه رو به صورت Collection بگیرین.

بیشتر راهنمایی میکنید؟


Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش آپدیت شد
0

و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.

چالش تمومی نداره. خود پی‌اچ‌پی رو درست و حسابی یاد بگیرین. مثلاً اینو ببینین:
https://phptherightway.com/
بعدش لاراول رو درست و حسابی یاد بگیرین و داکیومنتیشنش رو بخونین. آموزش‌های آقای ایمان غفوری کم‌نظیره. اگه انگلیسی بلدین که جفری‌وی ترکونده. بعدش یه دیتابیس رابطه‌ای (MySQL یا PostgreSQL) یاد بگیرین. این رودمپ خیلی خوبه:
https://roadmap.sh/

این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.

شما یه متد می‌سازین که قراره یه Relation برگردونه، مثل topic (درستش اینه که بنویسین topics چون one to many هست)، بعضی متدها هم قراره یه مقدار خاصی رو برگردونن و قرار نیست توی این متدهاتون با با مدل‌های دیگه ارتباط درست کنین. شما topics رو داشته باشین و داخلش همون Relation رو برگردونین، بعد توی متد getTopicsDuration که درست می‌کنین...

بیشتر راهنمایی میکنید؟

چرا که نه؟ شما با متد topics یه Relation برمی‌گردونین و Relation با Collection فرق داره. شما می‌خوایین به رکوردهای اون یکی جدول دسترسی پیدا کنین، پس کدتون اینطوری میشه:

 foreach ($this->topics as $topic) {
 .
 .
 .

وقتی بنویسیم this->topics$ ، یه کالکشن داریم که میشه داخل foreach گذاشت و یکی یکی تاپیک‌هارو گرفت. البته میشه این جمع رو از طریق دیتابیس انجام داد و دیگه نیازی نیست حلقه نوشت و یکی یکی اضافه کرد.


محمدسجاد دباغ
تخصص : برنامه نویس لاراول
@mdabbagh 3 سال پیش مطرح شد
0

@muhammad
ممنونم از معرفی منابع حتما مطالعه میکنم.
طبق روش شما رفتم و فکر میکنم حل شده فقط دیتایی که میگیره رو به عنوان عدد تشخیص نمیده که جمع کنه.

Object of class App\models\File could not be converted to number
or
Object of class App\models\File could not be converted to int

کد من هم به شکل زیر هست

public function topic_duration()
    {
        $duration = 0;
        foreach ($this->topics as $topic) {
            $file_duration = File::where('id', $topic->file_id)->get('video_duration')->first();
            (int)$duration += (int)$file_duration;
        }
        return $duration;
    }

@mohaligateway
@Rp76


Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش آپدیت شد
0

علتش خیلی واضحه: شما دارین مدل رو جمع می‌بندین یا کست می‌کنین به int!

$file_duration = File::where('id', $topic->file_id)->sum('video_duration')
$duration += $file_duration;

البته چنین کدی افتضاح در افتضاحه، چون هر بار یه کوئری به دیتابیس می‌زنه و یه مدل براش می‌سازه و مثلا وقتی 50 تا تاپیک داشته باشین، با هر بار استفاده از این متد، 50 تا کوئری می‌زنه تا یاری که توی خونه هست رو گرد جهان پیدا کنه. راه حلش چیه؟ استفاده از Eager loading، استفاده از دو کوئری یکی برای گرفتن لیستی از آیدی تاپیک‌ها و یکی جمع طول فایل‌ها با WHERE IN، یا استفاده از کوئری SQL خام. بهتر از همه‌ی این راه‌حل‌ها هم اینه که طول فایل‌ها یه بار برای همیشه محاسبه بشه، چون وقتی قرار نیست طولش تغییر کنه، جالب نیست که هر بار سرور رو اذیت کنیم که یه عدد بهمون بده.


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام