نمایش تصویر از داخل storage public

6 روز پیش
توسط محمدحسن یگانه آپدیت شد
JBolouri ( 5058 تجربه )
1 ماه پیش

سلام دوستان..
تصویر داخل پوشه public مربوط به storage آپلود میشه..

توی ویو، توی تگ ایمیج آدرسشو که میدم لود نمیشه..

src="{{ asset('storage/'. $admin->image_addr) }}"

دقیقا از همین dd هم که گرفتم دیدم آدرسش درسته فقط نشون نمیده..

"http://localhost:۸۰۰۰/storage/Data/Admins/۹LIXJfoUpdIgqJDEszZZBwCT۸jopn۸IA/۹LIXJfoUpdIgqJDEszZZBwCT۸jopn۸IA.jpg"

php artisan storage:link
رو هم اجرا کردم و پوشه لینک شده

ممنون میشم راهنماییم کنید

بهترین پاسخ انتخاب شده توسط JBolouri
محمدحسن یگانه
1 هفته پیش

پیام های بالا رو خوندم احساس میکنم آخرش جواب صحیحی داده نشد. فلذا میخوام چیزی که خودم فهمدیم رو در حد توان باهاتون به اشتراک بذارم:

اول اینکه توجه داشته باشید هر گونه asset شامل فایل css و js و تصویر و فونت و ... که سایت میخواد لود بکنه الا و لابد باید داخل پوشه public پروژتون قرار داشته باشه. فعلا منظورم از پوشه public فولدری هست که داخل روت پروژه هست و نه اونی که داخل storage هست. (به اون میرسیم) پس تا جایی که میدونم هیچ جوره نمیشه عکسی رو که داخل مسیری غیر از پوشه public هست رو داخل سایت لود کرد.

یعنی به عبارت دیگه برای این asset ها بایستی لینک دانلود مستقیم فایل براشون وجود داشته باشه. و با توجه به ساختار پوشه بندی فریم ورک لاراول، کاربران وبسایت فقط میتونند به محتوای داخل فولدر public دسترسی داشته باشند. اگر دقت کنید بعد از آدرس URL سایتتون و علامت / هر چیزی که وارد کنید مربوط به پوشه ها و فایل های داخل public تون هست و شما هیچ وقت نمیتونید به محتوای بیرون این پوشه مثلا config یا .env دسترسی پیدا کنید.

از طرف دیگه باید دقت کنیم که هر گونه فایلی که داخل پوشه public قرار بگیره در دسترس عموم قرار میگیره. حتی اگر جایی در سایت بهشون لینک نداده باشیم، فقط کافیه اسم فایل و مسیرش رو بدونیم. پس فایل هایی که بعنوان مثال فقط باید بعد از ثبت نام یا پرداخت و ... در دسترس قرار بگیرند نباید داخل این فولدر قرار بگیرند. پس چاره چیه؟

یک فولدری داریم بنام storage/app که میاد همون نقشی که میخوایم رو بازی میکنه. یعنی یک انبار محتوایی هست که قابلیت دسترسی عمومی و دانلود با لینک مستقیم ندارند. بلکه باید هر زمان که خواستیم براشون یک URL موقتی ایجادکنیم و یا response با نوع download برگردونیم. یعنی اینجوری:

return response()->download('path/to/file');

حالا یک فایل هایی هم داریم که میخوایم داخل storage باشند و از متدهای اون بتونیم استفاده کنیم. از طرفی هم باید قابلیت دسترسی عمومی داشته باشند. مثلا تصویر آواتار کاربران و ... برای این جور موارد اومدن یک پوشه بنام public قرار دادند تو مسیر storage/app و گفتند این جور فایل هاتون رو بریزید داخل این پوشه. تا اینجای کار که همه چیز خوبه. ولی اگر یادتون باشه بالاتر اشاره کردم که شما بعنوان کاربر فقط میتونید تصاویر و کلا asset های فقط پوشه public قرار گرفته در روت پروژه رو ببینید و شامل این پوشه نمیشه.

به همین خاطر یک راه حل خیلی تمیز گذاشتند و اون هم ایجاد یک symbolic link هست از پوشه sotorage/app/public در پوشه public روت پروژه با نام storage و با دستور storage:link ایجاد میشه. اینجوری شما به هر یک از فایل های داخل storage و پوشه public که خواستید آدرس دهی کنید کافیه بگید:

<img href="/storage/ali.jpg">

و این یعنی فایل ali.jpg که در اصل داخل مسیر storage/app/public/ali.jpg قرار داره. دقت کنید فایل ها همچنان جاشون تغییر نکرده بلکه این symbolic link ساده هست که میاد اون ها در دسترس عمومی قرار میده.

یک قاعده کلی و رایج هم اینکه معمولا فایل های css و js و فونتها و اون دسته از تصاویری که در قالب وبسایت بکار رفتند رو داخل پوشه public روت پروژه قرار میدن و مواردی که به مرور زمان توسط ادمین ها و یا کاربران آپلود و ویرایش یا حذف میشن همگی میرن داخل storage/app. اگر میخواستیم دسترسی عمومی پیدا کنه هم که میرن داخل پوشه storage/app/public

حسین شیری نژاد ( 24940 تجربه )
1 ماه پیش
تخصص : برنامه نویس

بهترین جا برای اپلود تصویر اینه که داخل پوشه public یه پوشه به نام upload درست کنی و تصاویرتو اونجاد ذخیره کنی اصلا فایل اپلودو درstorage/upload ذخیره نکن.

محسن بستان ( 97480 تجربه )
1 ماه پیش
تخصص : توسعه دهنده ارشد وب

@javadbolouri72
سلام.
برید داخل پوشه و ببینید آیا اون فایل در اون قسمت وجود داره یا نه.
روشی هم که آقای حسین گفتند، کار اشتباهیه چون لاراول دایرکتوری storage رو دقیقا برای همین کار ساخته و ساختار اصلی و پیشنهاد شده لاراول هستش.

JBolouri ( 5058 تجربه )
1 ماه پیش

@javadbolouri72

بله فایلا قشنگ سر جاشون با اسمی که توی دیتابیس ذخیره شده، قرار گرفتن...
هم فایلا سرجاشونن هم dd که گرفتم آدرس درسته

JBolouri ( 5058 تجربه )
1 ماه پیش

@hosseinshirinegad98

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

راستی با چه دستوری میشه یه پوشه رو با فایلای داخلش پاک کرد؟

دستور rmdir که میزنم ارور میده که تو پوشه فایل هست و پاک نمیکنه..

حسین شیری نژاد ( 24940 تجربه )
1 ماه پیش
تخصص : برنامه نویس

ابتدا تموم فایل های دورن پوشه رو می بایست حذف کنید بعد اقدام به پاک کردن فولدر نمایید. فولدر موقع حذف باید خالی باشد.
من تابحال هر آموزشی که دیدم همه فایل های آپلود شده در داخل فولدر public ذخیره می شن برنامه نویسان بزرگی هم این کارو کرده حتی آقا حسام هم در این سایت از فولدر public برای ذخیره فایل های آپلود شده استفاده کرده.
روش استوریجو من کار نکردم و تجربه ندارم.
@javadbolouri72

حسین شیری نژاد ( 24940 تجربه )
1 ماه پیش
تخصص : برنامه نویس

برای حذف فایل هم از متد خود php به نامunlink() استفاده کنید.
روش استوریجو خودتون می تونید بررسی کنید شاید همون روش پیشنهاد لاراول باشه . ولی تابحال من اطلاعی در این زمینه ندارم @javadbolouri72

JBolouri ( 5058 تجربه )
1 ماه پیش

@hosseinshirinegad98

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

حسین شیری نژاد ( 24940 تجربه )
1 ماه پیش
تخصص : برنامه نویس

درود زنده باشید . @javadbolouri72

kabiri ( 2854 تجربه )
1 هفته پیش

سلام وقت به خیر . میشه بگین این مشکل چه جوری حل شد. من چندوقته سر این موضوع مشکل دارم. ممنون میشم کمکم کنید.
@javadbolouri72

محمدحسن یگانه ( 18549 تجربه )
1 هفته پیش
تخصص : Full-Stack Web Developer

پیام های بالا رو خوندم احساس میکنم آخرش جواب صحیحی داده نشد. فلذا میخوام چیزی که خودم فهمدیم رو در حد توان باهاتون به اشتراک بذارم:

اول اینکه توجه داشته باشید هر گونه asset شامل فایل css و js و تصویر و فونت و ... که سایت میخواد لود بکنه الا و لابد باید داخل پوشه public پروژتون قرار داشته باشه. فعلا منظورم از پوشه public فولدری هست که داخل روت پروژه هست و نه اونی که داخل storage هست. (به اون میرسیم) پس تا جایی که میدونم هیچ جوره نمیشه عکسی رو که داخل مسیری غیر از پوشه public هست رو داخل سایت لود کرد.

یعنی به عبارت دیگه برای این asset ها بایستی لینک دانلود مستقیم فایل براشون وجود داشته باشه. و با توجه به ساختار پوشه بندی فریم ورک لاراول، کاربران وبسایت فقط میتونند به محتوای داخل فولدر public دسترسی داشته باشند. اگر دقت کنید بعد از آدرس URL سایتتون و علامت / هر چیزی که وارد کنید مربوط به پوشه ها و فایل های داخل public تون هست و شما هیچ وقت نمیتونید به محتوای بیرون این پوشه مثلا config یا .env دسترسی پیدا کنید.

از طرف دیگه باید دقت کنیم که هر گونه فایلی که داخل پوشه public قرار بگیره در دسترس عموم قرار میگیره. حتی اگر جایی در سایت بهشون لینک نداده باشیم، فقط کافیه اسم فایل و مسیرش رو بدونیم. پس فایل هایی که بعنوان مثال فقط باید بعد از ثبت نام یا پرداخت و ... در دسترس قرار بگیرند نباید داخل این فولدر قرار بگیرند. پس چاره چیه؟

یک فولدری داریم بنام storage/app که میاد همون نقشی که میخوایم رو بازی میکنه. یعنی یک انبار محتوایی هست که قابلیت دسترسی عمومی و دانلود با لینک مستقیم ندارند. بلکه باید هر زمان که خواستیم براشون یک URL موقتی ایجادکنیم و یا response با نوع download برگردونیم. یعنی اینجوری:

return response()->download('path/to/file');

حالا یک فایل هایی هم داریم که میخوایم داخل storage باشند و از متدهای اون بتونیم استفاده کنیم. از طرفی هم باید قابلیت دسترسی عمومی داشته باشند. مثلا تصویر آواتار کاربران و ... برای این جور موارد اومدن یک پوشه بنام public قرار دادند تو مسیر storage/app و گفتند این جور فایل هاتون رو بریزید داخل این پوشه. تا اینجای کار که همه چیز خوبه. ولی اگر یادتون باشه بالاتر اشاره کردم که شما بعنوان کاربر فقط میتونید تصاویر و کلا asset های فقط پوشه public قرار گرفته در روت پروژه رو ببینید و شامل این پوشه نمیشه.

به همین خاطر یک راه حل خیلی تمیز گذاشتند و اون هم ایجاد یک symbolic link هست از پوشه sotorage/app/public در پوشه public روت پروژه با نام storage و با دستور storage:link ایجاد میشه. اینجوری شما به هر یک از فایل های داخل storage و پوشه public که خواستید آدرس دهی کنید کافیه بگید:

<img href="/storage/ali.jpg">

و این یعنی فایل ali.jpg که در اصل داخل مسیر storage/app/public/ali.jpg قرار داره. دقت کنید فایل ها همچنان جاشون تغییر نکرده بلکه این symbolic link ساده هست که میاد اون ها در دسترس عمومی قرار میده.

یک قاعده کلی و رایج هم اینکه معمولا فایل های css و js و فونتها و اون دسته از تصاویری که در قالب وبسایت بکار رفتند رو داخل پوشه public روت پروژه قرار میدن و مواردی که به مرور زمان توسط ادمین ها و یا کاربران آپلود و ویرایش یا حذف میشن همگی میرن داخل storage/app. اگر میخواستیم دسترسی عمومی پیدا کنه هم که میرن داخل پوشه storage/app/public

JBolouri ( 5058 تجربه )
1 هفته پیش

@akabiri68
من از طریق storage فایل تصویر رو توی پوشه پابلیک جایی که دوست دارم ذخیره میکنم و آدرسشم توی بانک دارم...

حالا با کد زیر راحت بار گذاری میشه..

src="{{ asset('storage/'. $admin->image_addr) }}"

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

php artisan storage:link

درست شد..

بعضی وقتا که گیر الکی میده با پاک کردن کش هم دیدم حل میشه..

محمدحسن یگانه ( 18549 تجربه )
6 روز پیش
تخصص : Full-Stack Web Developer

اگر تو نسخه لوکالتون این symbolic link رو ایجاد کرده باشید و بعد محتویات پروژه رو zip کنید و به هاست یا سرورتون منتقل کنید، اون symlink از کار می افته و حتما بایستی یکبار پاک بشه و دستور storage:link رو در خورد هاست یا سرور اجرا کنید.

برای ارسال پاسخ باید وارد سایت شوید