12 β Fayl yuklash¶
β¬ οΈ Oldingi: 11 β Form Objects Β· π Kitob boshi Β· Keyingi: 13 β Ro'yxatlar β‘οΈ
Bu bobda: foydalanuvchidan fayl β rasm, hujjat, avatar β qabul qilishni Livewire usulida o'rganamiz.
WithFileUploadstrait'i,wire:modelbilan<input type="file">ni bog'lash, vaqtinchalik yuklash (temporary upload) mexanizmi nima va nega ikki bosqichda ishlashi, saqlashdan oldintemporaryUrl()bilan rasmni ko'rsatish (preview),#[Validate]bilan tur va hajmni tekshirish, faylnistore()bilan doimiy saqlash, ko'p fayl yuklash, yuklash jarayonini foiz bilan ko'rsatish va β eng muhimi β xavfsizlik qoidalarini ko'ramiz. Oxirida to'liq avatar yuklash komponentini yig'amiz.
Nega fayl yuklash maxsus?¶
Hayotiy o'xshatish. Tasavvur qiling, do'stingizga xat yozayapsiz. Oddiy gaplarni β "salom", "yaxshimisan" β bitta konvertga solib jo'natasiz, bu oson. Lekin unga katta albom (yuzlab rasm) jo'natmoqchi bo'lsangiz-chi? Albomni konvertga sig'dira olmaysiz. Avval pochtaga olib borasiz, ular albomni alohida omborga qo'yadi, sizga kvitansiya beradi, keyin albom manzilga yetkaziladi. Faylar ham xuddi shunday: ular oddiy so'zlar emas, ular og'ir yuk β alohida muomalani talab qiladi.
Avvalgi boblarda biz wire:model bilan matn, raqam, checkbox kabi oddiy qiymatlarni server bilan bog'ladik (06-bob). Bu qiymatlar har so'rovda snapshot ichida (JSON sifatida) oldinma-ketin yuradi: brauzerdan serverga va orqaga. Bu yengil qiymatlar uchun ajoyib ishlaydi.
Lekin fayl β bu oddiy qiymat emas. Fayl bir necha megabayt bo'lishi mumkin. Uni JSON snapshot ichiga "tiqib" har bir kichik o'zgarishda u yoq-bu yoqqa tashib bo'lmaydi β bu sekin va isrofgarchilik bo'lar edi. Shu sababli Livewire faylni boshqacha boshqaradi.
Texnik tilda aytganda: oddiy
publicxususiyatlar har so'rovda (de)serialize qilinadi, fayl esa bir marta vaqtinchalik serverga yuklanadi va keyin faqat uning kalit (identifikator) snapshot ichida yuradi. Asl og'ir fayl serverda kutib turadi.
Bu jarayonni vaqtinchalik yuklash (temporary upload) deb ataymiz va u shu bobning yuragi. Avval shu mexanizmni tushunamiz, keyin kod yozamiz.
Vaqtinchalik yuklash mexanizmi¶
Foydalanuvchi fayl tanlaganda, Livewire uni darhol serverga yuklaydi β lekin doimiy joyga emas, vaqtinchalik papkaga. Faqat foydalanuvchi "Saqlash" tugmasini bosgandagina fayl o'sha vaqtinchalik papkadan doimiy joyga (masalan storage/app/public/photos) ko'chiriladi.
Nega ikki bosqich? Sababi oddiy va aqlli:
- Validatsiya saqlashdan oldin. Fayl vaqtinchalik joyda turganida uni tekshirib ko'ramiz: rasmmi? hajmi me'yordami? Agar xato bo'lsa β uni doimiy joyga umuman saqlamaymiz.
- Preview (oldindan ko'rish). Vaqtinchalik faylga maxsus havola (
temporaryUrl()) bersa bo'ladi β foydalanuvchi rasmni saqlashdan oldin ko'radi. "Mana shu rasmni tanladingizmi?" degandek. - Tejamkorlik. Forma to'ldirilayotganda boshqa maydonlar (ism, izoh) o'zgaradi β har gal og'ir faylni qayta yubormaslik kerak. Fayl bir marta yuklanadi, qolgani snapshot orqali yengil yuradi.
Quyidagi diagramma butun yo'lni β tanlashdan to doimiy saqlashgacha β ko'rsatadi:
Eslatma
Vaqtinchalik fayllar abadiy turmaydi. Livewire ularni belgilangan vaqtdan (sukut bo'yicha 24 soat) keyin avtomatik tozalaydi. Ya'ni foydalanuvchi faylni tanlab, lekin "Saqlash"ni bosmasa, fayl bir kun ichida o'chib ketadi β server axlatga to'lmaydi.
WithFileUploads trait'i¶
Fayl yuklashni yoqish uchun komponentga bitta trait qo'shamiz: Livewire\WithFileUploads. Trait β bu komponentga "qo'shimcha qobiliyat" beradigan tayyor kod to'plami. Aynan shu trait yuqorida tushuntirgan butun vaqtinchalik yuklash mexanizmini ortda yoqib beradi.
SFC (Single-File Component) formatida u shunday yoziladi:
{{-- resources/views/components/β‘avatar-upload.blade.php --}}
<?php
use Livewire\Component;
use Livewire\WithFileUploads; // 1) trait'ni import qilamiz
new class extends Component
{
use WithFileUploads; // 2) anonim klass ichida ulaymiz
public $photo; // 3) fayl shu xususiyatda turadi
};
?>
<div>
{{-- ... --}}
</div>
E'tibor bering: use Livewire\WithFileUploads; faylning yuqorisida (import), use WithFileUploads; esa anonim klassning ichida (ulash) yoziladi. Ikkalasi ham kerak.
Ehtiyot bo'ling
Agar use WithFileUploads; ni klass ichiga qo'yishni unutsangiz, fayl yuklashga urinilganda Livewire MissingFileUploadsTraitException xatosini beradi. Bu β eng tez-tez uchraydigan boshlang'ich xato. Xato matni o'zi sizga trait'ni qo'shishni eslatadi.
Birinchi fayl input'i¶
Endi faylni qabul qiladigan property va Blade input'ni qo'shamiz. Property oddiy public $photo; β boshlang'ich qiymati bo'sh (null). Blade tomonda esa odatiy HTML fayl input'iga wire:model="photo" qo'shamiz:
{{-- resources/views/components/β‘avatar-upload.blade.php --}}
<?php
use Livewire\Component;
use Livewire\WithFileUploads;
new class extends Component
{
use WithFileUploads;
public $photo; // tanlangan fayl shu yerda saqlanadi
};
?>
<div>
<input type="file" wire:model="photo">
</div>
Mana shu β bor-yo'g'i. Foydalanuvchi fayl tanlagan zahoti Livewire avtomatik faylni vaqtinchalik papkaga yuklaydi. Hech qanday tugma bosish shart emas β wire:model tanlovni sezadi va yuklashni boshlaydi.
Texnik jihatdan,
$photoxususiyati endi oddiy matn emas. Yuklangandan keyin u maxsus obyekt βTemporaryUploadedFileβ bo'ladi. Bu obyekt asl faylning nomi, hajmi, turi va vaqtinchalik joydagi yo'lini biladi. Biz bu obyektning metodlaridan (temporaryUrl(),store(),getClientOriginalName()) foydalanamiz.
Livewire 3 da qanday edi?
WithFileUploads, wire:model bilan fayl input, temporaryUrl() va store() β bularning hammasi Livewire 3 da ham aynan shu nomlar bilan ishlardi. Fayl yuklash mexanizmida 4-versiyada tub o'zgarish bo'lmadi: oldin o'rgangan bilimingiz bu yerda to'liq to'g'ri.
Preview β saqlashdan oldin ko'rsatish¶
Foydalanuvchi avatar tanladi. Uni saqlashdan oldin ko'rsatib qo'ysak yaxshi bo'lardi β "siz tanlagan rasm shu, to'g'rimi?" Aynan shu yerda vaqtinchalik yuklashning kuchi ko'rinadi: fayl allaqachon serverda turibdi, demak unga havola berish mumkin.
temporaryUrl() metodi vaqtinchalik faylga maxsus, vaqtincha amal qiladigan havola qaytaradi. Uni rasm tegida ishlatamiz:
{{-- resources/views/components/β‘avatar-upload.blade.php --}}
<div>
<input type="file" wire:model="photo">
{{-- $photo bo'lsa (ya'ni fayl tanlangan bo'lsa) β preview ko'rsatamiz --}}
@if ($photo)
<img src="{{ $photo->temporaryUrl() }}" width="120" alt="Tanlangan rasm">
@endif
</div>
@if ($photo) sharti muhim: fayl hali tanlanmaganida $photo null bo'ladi va temporaryUrl() ni chaqirib bo'lmaydi. Fayl tanlangach @if rost bo'ladi va rasm ko'rinadi.
Quyidagi diagramma preview qanday ishlashini β vaqtinchalik fayl serverda turishi va brauzer unga havola orqali murojaat qilishini ko'rsatadi:
Faqat ko'rish mumkin bo'lgan turlar
temporaryUrl() faqat ko'rish mumkin (previewable) bo'lgan fayllarda ishlaydi: rasmlar (jpg, png, gif, webp, svg), shuningdek ba'zi audio/video. PDF yoki .docx kabi hujjat uchun temporaryUrl() xato beradi β chunki brauzer ularni rasm sifatida ko'rsata olmaydi. Hujjatlar uchun preview o'rniga oddiygina fayl nomini ko'rsating (pastda ko'ramiz).
Validatsiya β har doim tekshiring¶
Endi eng muhim qismga keldik: validatsiya. Foydalanuvchi yuklagan faylga hech qachon ishonib bo'lmaydi. U rasm o'rniga zararli skript yuklashga, yoki 500 MB li ulkan fayl bilan serverni bo'g'ishga urinishi mumkin. Shuning uchun har bir fayl yuklashda turini va hajmini tekshirish majburiy.
Validatsiyani 10-bobda o'rgangan #[Validate] atributi bilan qo'yamiz. Fayl uchun eng ko'p ishlatiladigan qoidalar:
| Qoida | Ma'nosi |
|---|---|
image |
Fayl rasm bo'lishi shart (jpg, png, gif, webp, ...) |
mimes:pdf,docx |
Fayl turi ro'yxatdagilardan biri bo'lishi shart |
max:1024 |
Maksimal hajm β kilobaytda (1024 KB = 1 MB) |
required |
Fayl tanlangan bo'lishi shart |
{{-- resources/views/components/β‘avatar-upload.blade.php --}}
<?php
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Validate;
new class extends Component
{
use WithFileUploads;
#[Validate('image|max:1024')] // rasm bo'lsin va 1 MB dan oshmasin
public $photo;
};
?>
<div>
<input type="file" wire:model="photo">
{{-- xato xabari (masalan, "rasm 1 MB dan katta") shu yerda chiqadi --}}
@error('photo') <span style="color:#dc2626">{{ $message }}</span> @enderror
</div>
max qoidasidagi son kilobayt ekanini yodda tuting: max:1024 = 1 MB, max:5120 = 5 MB. Bu eng ko'p qiladigan adashuvlardan biri.
Maslahat
wire:model="photo" faylni darhol yuklaganligi uchun, Livewire fayl yuklangan zahoti uni avtomatik validatsiya qiladi β agar siz xususiyatga #[Validate] qo'ygan bo'lsangiz. Ya'ni foydalanuvchi 10 MB li rasm tanlasa, "Saqlash"ni bosishidan oldin xato ko'rinadi. Bu yoqimli, tez fikr-mulohaza beradi.
Doimiy saqlash β store()¶
Validatsiyadan o'tdik, preview ko'rsatdik. Endi foydalanuvchi "Saqlash" tugmasini bosganda faylni doimiy joyga ko'chiramiz. Buni store() metodi qiladi:
public function save()
{
$this->validate(); // 1) avval qoidalarni qayta tekshiramiz (xavfsizlik)
// 2) faylni doimiy diskka ko'chiramiz va qaytgan yo'lni olamiz
$path = $this->photo->store('photos', 'public');
// $path endi: "photos/aBc123...jpg" β shuni bazaga saqlaymiz
}
store() ikkita argument oladi:
- Birinchi β papka nomi (
'photos'). Fayl shu papka ichiga saqlanadi. - Ikkinchi β disk nomi (
'public').publicdiskstorage/app/publicga ishora qiladi va veb orqali ochiq bo'ladi.
store() qaytaradigan qiymat β faylning yangi yo'li (masalan photos/aBc123XyZ.jpg). Asl fayl nomini Livewire xavfsizlik uchun tasodifiy nomga almashtiradi. Aynan shu yo'lni bazaga saqlaysiz β keyin rasmni ko'rsatish uchun shundan foydalanasiz.
Bir nechta foydali variant bor:
// 'public' diskka public ko'rinishda saqlash (yuqoridagining qisqasi):
$path = $this->photo->storePublicly('photos');
// o'z nomingiz bilan saqlash (avtomatik tasodifiy nom o'rniga):
$path = $this->photo->storeAs('photos', 'avatar-' . auth()->id() . '.jpg', 'public');
public/storage havolasi
public diskdagi fayllar veb orqali ko'rinishi uchun bir martalik ulanish kerak: terminalda php artisan storage:link buyrug'ini ishga tushiring. Bu public/storage papkasini storage/app/public ga bog'laydi. Buni unutsangiz, rasm saqlanadi-yu, lekin brauzerda 404 bo'lib ko'rinmaydi.
Path'ni bazaga saqlash¶
Real ilovada saqlangan yo'lni odatda foydalanuvchining (yoki postning) yozuviga yozamiz:
public function save()
{
$this->validate();
$path = $this->photo->store('avatarlar', 'public');
// tizimga kirgan foydalanuvchining avatar ustunini yangilaymiz
auth()->user()->update(['avatar' => $path]);
$this->reset('photo'); // formani tozalaymiz
$this->dispatch('avatar-yangilandi'); // boshqalarga xabar (18-bob)
}
Bazada faqat yo'l (qisqa matn) saqlanadi, faylning o'zi emas. Rasmni ko'rsatganda esa shunday yozamiz:
Ko'p fayl yuklash¶
Ba'zan bir nechta fayl kerak β galereya, mahsulot rasmlari, ilova fayllari. Bunda property massiv bo'ladi va input'ga multiple atributini qo'shamiz:
{{-- resources/views/components/β‘galereya.blade.php --}}
<?php
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Validate;
new class extends Component
{
use WithFileUploads;
#[Validate(['photos.*' => 'image|max:1024'])] // HAR BIR element tekshiriladi
public $photos = []; // massiv β bo'sh boshlanadi
public function save()
{
$this->validate();
foreach ($this->photos as $photo) {
$photo->store('galereya', 'public'); // har birini saqlaymiz
}
}
};
?>
<div>
{{-- multiple β bir nechta fayl tanlash imkonini beradi --}}
<input type="file" wire:model="photos" multiple>
{{-- har bir tanlangan rasmni preview qilamiz --}}
<div>
@foreach ($photos as $photo)
<img src="{{ $photo->temporaryUrl() }}" width="80" alt="Tanlangan rasm">
@endforeach
</div>
<button wire:click="save">Hammasini saqlash</button>
</div>
Bu yerda ikkita yangilik bor:
- Validatsiya
photos.*β yulduzcha (*) "massivdagi har bir element" degani. Ya'ni har bir tanlangan rasm alohida tekshiriladi. @foreachbilan preview β$photosmassiv bo'lgani uchun tsikl bilan har birini ko'rsatamiz.
Quyidagi diagramma bitta fayl va ko'p fayl orasidagi farqni β property massiv bo'lishi va har bir element alohida vaqtinchalik yuklanishini β ko'rsatadi:
Eslatma
Ko'p fayl bilan ishlaganda foydalanuvchi tanlovni ikki marta qilsa, ikkinchi tanlov birinchisining ustiga yozilmaydi β Livewire wire:model xulqiga bog'liq. Galereyaga "qo'shib borish" kabi murakkab xulq kerak bo'lsa, faylarni saqlagandan keyin $this->reset('photos') bilan tozalab, navbatma-navbat qo'shing.
Yuklash jarayonini ko'rsatish¶
Katta fayl yuklanayotganda foydalanuvchi "nimadir bo'lyaptimi?" deb hayron bo'lmasligi kerak. Livewire fayl yuklash davomida ishlatish uchun ikki vosita beradi.
Birinchisi β siz keyingi boblarda chuqurroq o'rganadigan wire:loading. Fayl yuklanayotganda biror belgini ko'rsatadi:
<input type="file" wire:model="photo">
{{-- fayl serverga yuklanayotganda ko'rinadi, tugagach yo'qoladi --}}
<div wire:loading wire:target="photo">Yuklanmoqda, kuting...</div>
wire:target="photo" muhim: u "faqat photo xususiyati yuklanayotganda ko'rsat" deydi, boshqa har qanday so'rovda emas.
Ikkinchisi β aniq foiz kerak bo'lsa, Livewire maxsus brauzer hodisasi tarqatadi: livewire-upload-progress. Uni Alpine bilan ushlab, jonli progress-bar yasash mumkin:
<div
x-data="{ progress: 0, yuklanmoqda: false }"
x-on:livewire-upload-start="yuklanmoqda = true"
x-on:livewire-upload-finish="yuklanmoqda = false"
x-on:livewire-upload-error="yuklanmoqda = false"
x-on:livewire-upload-progress="progress = $event.detail.progress"
>
<input type="file" wire:model="photo">
{{-- progress β 0 dan 100 gacha foiz --}}
<div x-show="yuklanmoqda">
Yuklanmoqda: <span x-text="progress"></span>%
</div>
</div>
Bu yerda $event.detail.progress β Livewire bergan foiz (0β100). Alpine (22-bob) buni x-text orqali ekranda yangilab turadi. Katta fayllar bilan ishlaydigan ilovalarda bu β yaxshi tajriba.
Hujjat (PDF, docx) yuklash¶
Rasm emas, hujjat β masalan PDF rezyume yoki Word fayli β yuklash deyarli bir xil. Farqi: validatsiyada image o'rniga mimes:... ishlatamiz va preview o'rniga fayl nomini ko'rsatamiz (chunki PDF ni <img> bilan ko'rsatib bo'lmaydi).
<?php
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Validate;
new class extends Component
{
use WithFileUploads;
#[Validate('mimes:pdf,docx|max:5120')] // PDF yoki docx, eng ko'pi 5 MB
public $hujjat;
public function save()
{
$this->validate();
$path = $this->hujjat->store('hujjatlar', 'public');
// $path ni bazaga saqlang
}
};
?>
<div>
<input type="file" wire:model="hujjat">
{{-- preview emas β faqat tanlangan fayl nomini ko'rsatamiz --}}
@if ($hujjat)
<p>Tanlangan fayl: {{ $hujjat->getClientOriginalName() }}</p>
@endif
@error('hujjat') <span style="color:#dc2626">{{ $message }}</span> @enderror
<button wire:click="save">Saqlash</button>
</div>
getClientOriginalName() β foydalanuvchi tanlagan faylning asl nomini qaytaradi (masalan rezyume.pdf). Eslatib o'tamiz: bu nomni faqat ko'rsatish uchun ishlating; faylni saqlaganda Livewire baribir xavfsiz tasodifiy nom beradi.
S3 (bulut omborida) saqlash¶
Loyiha o'sganda fayllarni o'z serveringizda emas, Amazon S3 kabi bulut omborida saqlash kerak bo'lishi mumkin. Yaxshi yangilik: kodingiz deyarli o'zgarmaydi β faqat disk nomini 's3' qilasiz:
S3 ni config/filesystems.php da sozlaganingizdan so'ng, qolgan hammasi avvalgidek ishlaydi.
S3 vaqtinchalik fayllarni tozalash
S3 ishlatganda vaqtinchalik fayllar ham S3 ga yuklanadi. Ular o'z-o'zidan o'chmaydi β buni sozlash kerak. Livewire'da maxsus buyruq bor: php artisan livewire:configure-s3-upload-cleanup. U S3 bucket'ingizga "24 soatdan keyin vaqtinchalik fayllarni avtomatik o'chir" qoidasini o'rnatadi. Aks holda bucket ortiqcha vaqtinchalik fayllarga to'lib ketadi.
Xavfsizlik β eng muhim qism¶
Fayl yuklash β ilovaning eng xavfli nuqtalaridan biri. Tashqaridan keladigan fayl β bu sizning serveringizga begona tomonidan qo'yiladigan narsa. Quyidagilarni hech qachon unutmang.
Xavfsizlik β har doim validate qiling
- Har bir fayl yuklashga
#[Validate]qo'ying. Hech bir fayl tekshiruvsiz o'tmasligi kerak. Turini (image,mimes:...) va hajmini (max:...) chegaralang. - Foydalanuvchi bergan fayl nomiga ishonmang. Ism ichida
../../../etc/passwdkabi xavfli yo'l bo'lishi mumkin. Shuning uchunstore()ni ishlatib, Livewire'ga xavfsiz tasodifiy nom berishga ruxsat bering βgetClientOriginalName()ni faqat ekranda ko'rsatish uchun ishlating, hech qachon saqlash yo'li sifatida emas. - Hajmni cheklang.
maxqoidasisiz foydalanuvchi ulkan fayl bilan serveringizni "bo'g'ib" qo'yishi (DoS) mumkin. PHP ningupload_max_filesizesozlamasini ham tekshiring. - Faqat kutilgan turlarni qabul qiling. Avatar uchun
imageβphp,exe,shkabi bajariladigan fayllarni hech qachon qabul qilmang. - Avtorizatsiya. Faylni boshqa birovning yozuviga biriktirayotgan bo'lsangiz,
$this->authorize(...)bilan ruxsatni tekshiring (23-bob).
Esda tuting: validatsiya β bu shunchaki "to'g'ri ishlashi uchun" emas, bu himoya devori. Uni o'tkazib yuborish β ilovangizni ochiq qoldirish demak.
To'liq misol: avatar yuklash¶
Endi bilganlarimizni birlashtiramiz. Quyida β preview, validatsiya, doimiy saqlash, formani tozalash va muvaffaqiyat xabarini o'z ichiga olgan to'liq avatar yuklash komponenti. Bu kod jonli Livewire 4 loyihada ishga tushirilib tekshirilgan.
{{-- resources/views/components/β‘avatar-upload.blade.php --}}
<?php
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Validate;
new class extends Component
{
use WithFileUploads;
#[Validate('image|max:1024')] // rasm, eng ko'pi 1 MB
public $photo;
public ?string $saqlangan = null; // saqlangan rasm yo'li
public function save(): void
{
// 1) qoidalarni tekshiramiz (xavfsizlik devori)
$this->validate();
// 2) faylni doimiy 'public' diskka ko'chiramiz
$this->saqlangan = $this->photo->store('avatarlar', 'public');
// 3) real ilovada bu yo'lni bazaga yozasiz:
// auth()->user()->update(['avatar' => $this->saqlangan]);
// 4) formani tozalaymiz
$this->reset('photo');
}
};
?>
<div style="max-width:360px">
<h2>Profil rasmi</h2>
{{-- fayl tanlash --}}
<input type="file" wire:model="photo" accept="image/*">
{{-- yuklash jarayoni --}}
<div wire:loading wire:target="photo">Yuklanmoqda...</div>
{{-- saqlashdan oldin preview --}}
@if ($photo)
<div>
<p>Oldindan ko'rish:</p>
<img src="{{ $photo->temporaryUrl() }}" width="120" alt="Tanlangan avatar">
</div>
@endif
{{-- validatsiya xatosi --}}
@error('photo')
<p style="color:#dc2626">{{ $message }}</p>
@enderror
{{-- saqlash tugmasi --}}
<button wire:click="save">Saqlash</button>
{{-- muvaffaqiyat --}}
@if ($saqlangan)
<p style="color:#16a34a">Avatar saqlandi: {{ $saqlangan }}</p>
@endif
</div>
Bu komponentni sahifaga qo'yish uchun marshrut yozamiz (04-bob da ko'rganimizdek):
Endi /avatar manziliga kirib, rasm tanlasangiz: u darhol yuklanib preview ko'rinadi, "Saqlash"ni bosganingizda esa storage/app/public/avatarlar ichiga ko'chadi va yashil "saqlandi" xabari chiqadi. accept="image/*" esa brauzer fayl tanlash oynasida faqat rasmlarni ko'rsatadi β yana bir kichik qulaylik.
Tekshirib ko'ring
Yuqoridagi komponentni yarating, marshrutni qo'shing, php artisan storage:link ni bir marta ishga tushiring va /avatar ga kiring. Avval kichik rasm tanlang β preview ko'rinadimi? Keyin 2 MB dan katta rasm tanlab ko'ring β max:1024 xato xabarini berishi kerak.
Xulosa¶
- Fayl oddiy property emas β u og'ir, shuning uchun Livewire uni har so'rovda emas, bir marta vaqtinchalik yuklaydi, keyin faqat kalitini snapshot orqali tashiydi.
- Fayl yuklashni yoqish uchun komponentga
use Livewire\WithFileUploads;trait'ini qo'shing (import + klass ichidause). <input type="file" wire:model="photo">β fayl tanlangan zahoti avtomatik vaqtinchalik papkaga yuklanadi.- Vaqtinchalik yuklash ikki bosqichli: avval vaqtinchalik joyga (preview + validatsiya uchun), keyin "Saqlash"da doimiy joyga. Vaqtinchalik fayllar 24 soatda avtomatik tozalanadi.
- Preview:
@if ($photo) <img src="{{ $photo->temporaryUrl() }}"> @endifβ faqat rasm/ko'riladigan turlar uchun. - Validatsiya majburiy:
#[Validate('image|max:1024')](hajm kilobaytda),mimes:pdf,docx, ko'p fayl uchunphotos.*. - Doimiy saqlash:
$path = $this->photo->store('papka', 'public');β qaytgan yo'lni bazaga saqlang, faylni emas. - Ko'p fayl:
public $photos = [];+wire:model="photos" multiple+@foreachpreview. - Xavfsizlik: har doim validate qiling, foydalanuvchi fayl nomiga ishonmang, hajmni cheklang, faqat kutilgan turlarni qabul qiling.
Amaliy mashqlar¶
-
Avatar (oson).
WithFileUploadsishlatib, bitta rasm qabul qiladigan komponent yozing.#[Validate('image|max:1024')]qo'ying,temporaryUrl()bilan preview ko'rsating va "Saqlash"dastore('avatarlar', 'public')bilan saqlang. Saqlangan yo'lni ekranda chiqaring. -
PDF hujjat (o'rta). Endi rasm emas, PDF qabul qiladigan komponent yozing:
#[Validate('mimes:pdf|max:5120')]. Preview o'rnigagetClientOriginalName()bilan tanlangan fayl nomini ko'rsating. Noto'g'ri tur (masalan.jpg) tanlanganda chiqadigan xato xabarini kuzating. -
Ko'p rasmli galereya (o'rta).
public $photos = []vawire:model="photos" multiplebilan bir nechta rasm qabul qiling.#[Validate(['photos.*' => 'image|max:1024'])]qo'ying,@foreachbilan barcha previewlarni ko'rsating va "Saqlash"da tsikl bilan har birini saqlang. -
Progress-bar (qiyin). 1-mashqdagi avatar komponentiga Alpine bilan jonli yuklash foizini qo'shing:
x-on:livewire-upload-progress="progress = $event.detail.progress"ishlatib, katta rasm yuklanayotganda 0 dan 100 gacha foizni ko'rsating. -
Avatarni almashtirish (qiyin). 1-mashqni kengaytiring: foydalanuvchining eski avatari bo'lsa, yangisini saqlashdan oldin eskisini diskdan o'chiring (
Storage::disk('public')->delete($eskiYol)). Yangi yo'lni bazaga yozing. Eski faylni o'chirmasdan oldin u haqiqatan mavjudligini tekshirishni unutmang.
β¬ οΈ Oldingi: 11 β Form Objects Β· π Kitob boshi Β· Keyingi: 13 β Ro'yxatlar β‘οΈ