احمد
4 سال پیش توسط احمد مطرح شد
12 پاسخ

آپلود چند تصویر در دیتابیس

سلام چگونه چند تصویر به صورت همزمان به دیتا بیس ارسال کنیم؟


ثبت پرسش جدید
سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 4 سال پیش مطرح شد
0

@ahmad316948 سلام .
ارور اول بخاطر این هست که هیچ جایی inligting رو سیو نکردید که ایجاد بشه و آیدی اون سطر در اختیارتون باشه . مورد دوم هم به این دلیل هست که احتمالا روابطتون رو در مدل مربوطه تعریف نکردید یا تعریف شده اما به غلط .

راه حل مشکل اول : بعد از اینکه موارد رو مقدار دهی کردین باید در آخر دستور زیر رو رو فراخوانی کنید تا سطر مربوطه در دیتابیس درج بشه سپس به آیدی دسترسی داشته باشید.

$inligting->save();

راجب مشکل دوم : باید اطلاعات دقیق نسبت به تعریف رابطه های eloquent در لاراول پیدا کنید و روابطتون رو ایجاد کنید چون هیچکس از ساختار دیتابیس شما و نحوه تحلیلتون خبر نداره .

و در آخر نکته ای که خیلی مهمه این هست که موارد ریز به ریز رو نمیشه در پرسش و پاسخ پله پله برطرف کرد و قطعا با مشکل مواجه میشید . من هم پیشنهاد مهندس یگانه رو دارم خدمتتون که حتما حتما موارد پایه ای رو درک کنید چون الان اگر نصف راه رو رفتید و ده تا سوال و مشکل ایجاد شده هرچقدر جلوتر برید این موارد چندین برابر میشه و به حدی میرسه که کاملا کلافه میشید چون کلی ارور هست و دلیل هیچکدومش رو نمیدونید!!

در هر صورت آرزوی موفقیت دارم . 🌹


woz
تخصص : fan of open source world
@wozniak 4 سال پیش آپدیت شد
0

@ahmad316948
در دیتابیس تصاویر به صورت آدرس ذخیره میشوند. یعنی شما آدرس local یا آدرس absolute رو ذخیره می کنید. (بسته به شماست)
پس برای ذخیره تعداد بیشتر تصویر کافیه یک text یا varchar (در لاراول string) با مقدار دلخواه در نظر بگیرید ، و بعدا اون رو از نوع array داخل مدل cast کنید و ارایه ای از آدرس تصاویر برای هر رکوردتون ذخیره کنید


محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 4 سال پیش مطرح شد
4

برای این کار باید برای المنت input مورد نظر attribute با مقدار multiple قرار بدید تا امکان انتخاب چندین عکس وجود داشته باشه. اینجوری:

      <input type="file" name="photos[]" multiple="multiple">

و بعد از submit و در سمت سرور میتونید به هر یک از این تصاویر که به صورت آرایه ارسال شده اند و با حلقه foreach دسترسی داشته باشید.

یکی از رایج ترین روش های پیاده سازی این قضیه هم استفاده از رابطه One-To_Many هست. بعنوان مثال یک محصول ممکن است یک یا چند تصویر براش وجود داشته باشه...

همون طوری که اشاره شد تصاویر هم معمولا فایلشون داخل سرور آپلود میشه و اسم و آدرسشون در داخل دیتابیس قرار میگیره.

با این توضیحات کافیه ابتدا تصاویر رو در پوشه مورد نظر آپلود کنید و بعد به ازای هر تصویر یک سطر رکورد در جدول مربوط به تصاویرتون ایجاد نمایید.


احمد
@ahmad316948 4 سال پیش مطرح شد
0

@mhyeganeh
سلام من از طریق input تصاویر رو بصورت array فرستادم به کنترلر و متد store الان نمیدونم چجوری اون فایل هارو بگیرم و به متد file() اضافه کنم .

 public function store(Request $request, Product $product)
    {
       // return $request->all();
       $validData = $request->validate([
          'images.*.image'=> 'required',
          'images.*.alt'=> 'required|min:3'
      ]);
       $file = $request->file('image');
       $destinationPath = '/images/' . now()->year . '/' . now()->month . '/' . now()->day. '/';

     }

پدرام رحیمی
تخصص : برنامه نویس
@pedramrahimi 4 سال پیش مطرح شد
0

از نظر تحلیلی همون که محمدحسن گفت روش درستیه: قدیم (من یه دایناسور هستم که از 1369 شمسی کد میزنم!) بهش می گفتیم مستردیتیل. یعنی یه جدول داریم مستر که شماره ی فاکتور توش میاد و یه جدول دیگه که لیست کالاهای داخل اون فاکتور. حالا تو به جاش بگو مثلاً مطلب و تصاویر مربوط به مطلب. بعد این دو تا جدول باید با یک کد به اسم کدمطلب ارتباط بگیرن. موقع لود کردن دیتا هم میگی برو از جدول اول فلان کدو بیار و از جدول دوم تمام اونایی رو که این فلان کد در فیلد کد مطلبشون درج شده.


محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 4 سال پیش آپدیت شد
0

@ahmad316948
عرض کردم که... چون آرایه هست نیاز به یک حلقه foreach دارید و تک به تک عکس ها رو دریافت کنید و به ازای هر یک عملیاتی که لازم هست رو اعمال کنید. (ذخیره عکس در مسیر مورد نظر و اضافه کردن رکورد مربوطه)

یک مثال ساده از این قضیه:

if($request->hasfile('images')) {
            foreach($request->file('images') as $image) {

                //1. ایجاد یک نام یکتابرای فایل

                //2. ذخیره فایل در مسیر مورد نظر
                //  e g: Storage::putFileAs(...)

                //3. اضافه کردن رکورد عکس مربوطه به دیتابیس

            }
}   

اگر باز هم متوجه نشدید سری به لینک های زیر بزنید:
https://www.codechief.org/article/multiple-image-upload-upload-multiple-image-in-laravel-7
https://stackoverflow.com/questions/47708753/saving-multiple-images-in-laravel
https://laravel.com/docs/8.x/filesystem#storing-files


احمد
@ahmad316948 4 سال پیش مطرح شد
0

@mhyeganeh
سلام من طبق راهنمایی شما پیش رفتم ولی در آخر ارور Undefined variable: data رو میده.
کد های controller:

$validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'attributes' => 'array',
            'address' => 'required',

        ]); 

        if($request->hasfile('images')) {

            foreach($request->file('images') as $image) {
                $name = time().'.'.$image->extension();
                $image->move(public_path().'/files/', $name); 
                $data[] = $name;

            }

    }

        $image= new Product();
         $image->images=json_encode($data);
         $image->save();

  //  Product::create($validData);
    //alert()->success('آگهی شما با موفقیت ثبت شد و پس از تأیید مدریر در سایت قرار می گیرد','بسیار');
    //return redirect(route('products'));

کد view:

 <script>
           let createNewPic = ({ id }) => {
                return `
                    <div class="row image-field" id="image-${id}">
                        <div class="col-5">
                            <div class="form-group">
                                 <label>تصویر</label>
                                 <div class="input-group">
                                    <input type="file" class="form-control image_label" name="images[]"
                                           aria-label="Image" aria-describedby="button-image">
                                </div>
                            </div>
                        </div>

                         <div class="col-2">
                            <label >اقدامات</label>
                            <div>
                                <button type="button" class="btn btn-sm btn-warning" onclick="document.getElementById('image-${id}').remove()">حذف</button>
                            </div>
                        </div>
                    </div>
                `
            }

            $('#add_product_image').click(function() {
                let imagesSection = $('#images_section');
                let id = imagesSection.children().length;

                imagesSection.append(
                    createNewPic({
                        id
                    })
                );

            });
            $('#add_product_image').click();

            // set file link
            function fmSetLink($url) {
                image.find('.image_label').first().val($url);
            }
        </script>

محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 4 سال پیش مطرح شد
0

@ahmad316948
خوب متن ارورش کاملا گویای مشکل هست دیگه... قبلش متغیر data رو باید بسازید تا بتونید از $data[] = $name استفاده کنید:

$data = [];

احمد
@ahmad316948 4 سال پیش مطرح شد
0

@mhyeganeh
سلام من الان یه مدل دیگه به نام ProductGallery دارم که با استفاده از روابط لاراول به مدل Product متصل کردم و هنگام اضافه کردن محصول تصاویر رو در مدل ProductGallery ذخیره میکنه. الان نمیدونم چجوری فیلد product_id در جدول ProductGallery مقدار دهی کنم.
متن ارور

Illuminate\Database\QueryException
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'product_id' cannot be null (SQL: insert into `product_galleries` (`image`, `product_id`, `updated_at`, `created_at`) values (/images/2020/10/12/account.jpg, ?, 2020-10-12 13:55:10, 2020-10-12 13:55:10))
http://localhost:8000/advert/create

کد های کنترلر

public function create(Request $request, Product $product)
    {
        $validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'attributes' => 'array',
            'address' => 'required',

        ]); 
        $inligting = new Product;
        $inligting->title= $validData['title'];
         $inligting->description= $validData['description'];
         $inligting->address= $validData['address'];

        if($request->hasFile('image')) {
            $data= [];
            foreach($request->file('image') as $image) {
                $photo = new ProductGallery;

                $destinationPath = '/images/' . now()->year . '/' . now()->month . '/' . now()->day. '/';
                $image->move(public_path($destinationPath),  $image->getClientOriginalName()); 
                $photo->image = $destinationPath . $image->getClientOriginalName();
                $photo->product_id = $request->id;
                array_push($data, $photo);

                $inligting->gallery()->save($photo);

            }
        }else{
            return 'error';
        }
       // Product::create($validData);

         $product = Product::create($validData);

        $attributes = collect($validData['attributes']);
        $attributes->each(function($item) use($product) {
            if(is_null($item['name']) || is_null($item['value'])) return;

            $attr = Attribute::firstOrCreate(
                ['name'=> $item['name']]
            );

            $attr_value = $attr->values()->firstOrCreate(
                ['value' => $item['value'] ]
            );

            $product->attributes()->attach($attr->id, ['value_id'=> $attr_value->id]);
        });

    alert()->success('آگهی شما با موفقیت ثبت شد و پس از تأیید مدریر در سایت قرار می گیرد','بسیار');
return redirect(route('products')); 
        }
}

محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 4 سال پیش آپدیت شد
1

@ahmad316948

پیشنهاد میکنم قبل از ادامه دادن بیشتر از این یکبار وقت بذارید و بروی مباحث پایه ای PHP و لاراول مسلط بشید. بیشتر از یک هفته زمان نمی‌بره واقعا ولی در ادامه کارتون خیلی حرفه ای تر و راحت تر میشه. ولی اگر در هر صورت شرایطش رو الان ندارید:

به دو شکل میتونید این کار رو انجام بدید:

اول اینکه از آیدی همون instance که بالاتر ساختید استفاده کنید. یعنی تو مثال شما میشه اینجوری:

$photo->product_id = $inligting->id;

و راه دوم هم استفاده از روابط Eloquent هست که اگر به درستی انجام داده باشید خیلی راحت میتونید بگید:

$inligting->gallery()->create([
    'image' => $destinationPath . $image->getClientOriginalName(),
]);

و اینجوری خودش اتومات آیدی مرتبط رو قرار میده و نیازی نیست قید بشه.


احمد
@ahmad316948 4 سال پیش مطرح شد
0

@mhyeganeh سلام. ممنون از راهنماییتون. چون عجله دارم فرصت مرور دوباره مباحث لاراول رو ندارم. ولی در اولین فرصت حتما این کارو انجام میدم. روش اول دوباره خطای خالی بودن product_id رو داد و روش دوم هم یه خطای مربوط به hasMany داد


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 4 سال پیش مطرح شد
0

@ahmad316948 سلام .
ارور اول بخاطر این هست که هیچ جایی inligting رو سیو نکردید که ایجاد بشه و آیدی اون سطر در اختیارتون باشه . مورد دوم هم به این دلیل هست که احتمالا روابطتون رو در مدل مربوطه تعریف نکردید یا تعریف شده اما به غلط .

راه حل مشکل اول : بعد از اینکه موارد رو مقدار دهی کردین باید در آخر دستور زیر رو رو فراخوانی کنید تا سطر مربوطه در دیتابیس درج بشه سپس به آیدی دسترسی داشته باشید.

$inligting->save();

راجب مشکل دوم : باید اطلاعات دقیق نسبت به تعریف رابطه های eloquent در لاراول پیدا کنید و روابطتون رو ایجاد کنید چون هیچکس از ساختار دیتابیس شما و نحوه تحلیلتون خبر نداره .

و در آخر نکته ای که خیلی مهمه این هست که موارد ریز به ریز رو نمیشه در پرسش و پاسخ پله پله برطرف کرد و قطعا با مشکل مواجه میشید . من هم پیشنهاد مهندس یگانه رو دارم خدمتتون که حتما حتما موارد پایه ای رو درک کنید چون الان اگر نصف راه رو رفتید و ده تا سوال و مشکل ایجاد شده هرچقدر جلوتر برید این موارد چندین برابر میشه و به حدی میرسه که کاملا کلافه میشید چون کلی ارور هست و دلیل هیچکدومش رو نمیدونید!!

در هر صورت آرزوی موفقیت دارم . 🌹


حسین شیخ بارانی
تخصص : طراحی سایت
@abdgod 3 سال پیش مطرح شد
0

فرض این هست شما دارید یک پست می سازید و می خواهید یک گالری از عکس هم برای هر پست داشته باشید

خب تصویر رو با ajax ارسال کنید و مقدار برگشتی رو نام اون عکس بذارید بعد با جاوا اسکریپت خروجی ها رو توی یک آرایه پوش کنید

این جوری می تونید عکس های که نمی خواهدید قرار بدید فقط از آرایه حذف کنید

بعد مقدار ارایه رو تبدیل به جیسون کنید و ارسال کنید

برای نمایش هم براحتی از همین جیسون استفاده کنید


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

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