Laravel web loyihalaringizda katta o'lchamdagi fayllarni serverga yuklash.

Serverga ma'lumotlarni yuklash web loyihalarimizda doimuy uchraydigan ishlardan biri hisoblanadi. Agar yuklanadigan fayl hajmi katta bo'lsa yuklash funksionalini qilishda e'tibor beradigan jihatlarimiz haqida bu maqolada misollar bilan tushuntiramiz.
Oxirgi ishlagan loyihamizda katta hajmdagi (4GB) faylllarni yuklashda muammolarga duch keldik. Hajm katta bo'lgani uchun brower xususiyatlari hamda internetning doimiy bir xil uzulmasdan ishlashiga bog'liq bo'lgani uchun yuklash davomida uzilishga duch keldik. Php da ruxsat berilgan konfiguratsiyalarni quyidagiga o'zgartirganimizda ham muammolar oxirigacham yechilmadi:
upload_max_filesize = 5000M
post_max_size = 5000M
max_input_time = 3000
max_execution_time = 3000
Shu sababli muammoning effektiv yechimlarni qidirish davomida quyidagi ikkita kutubxonaga duch keldim: resumable.js va laravel-chunk-upload shundan so'ng bizda fayl hajmi qancha bo'lishidan qatiy nazar 10GB yoki unda ko'prog'ida ham muammosiz yukladik. Agar qiziq bulsa quyidagi biz bu haqida to'liq ma'lumotlarni keltiramiz.
1# Frontend sozlamalar
Avvalambor biz loyihamiz frontend qismda faylni kichik bo'laklarga bo'lib yuklash imkoniyatni beradigan kutubxonani o'rnatamiz
- resuumable kutubxonasini CDN orqali o'rnatib oling
https://cdn.jsdelivr.net/npm/resumablejs@1.1.0/resumable.min.js
- Quydigai HTML kodlarni faylni yuklash formangizga qo'shing. Bu kod faylni yuklash va sahifada ko'rsatish (bizning holatda video format bo'lgani uchun) imkonini beradi.
<div class="container pt-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header text-center">
<h5>Upload File</h5>
</div>
<div class="card-body">
<div id="upload-container" class="text-center">
<button id="browseFile" class="btn btn-primary">Brows File</button>
</div>
<div style="display: none" class="progress mt-3" style="height: 25px">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 75%; height: 100%">75%</div>
</div>
</div>
<div class="card-footer p-4" style="display: none">
<video id="videoPreview" src="" controls style="width: 100%; height: auto"></video>
</div>
</div>
</div>
</div>
</div>
- Resumable kutubxonasini ishlatish uchun quyidagi javascript kodlarni kiritamiz:
<script type="text/javascript">
let browseFile = $('#browseFile');
let resumable = new Resumable({
target: '{{ route('files.upload.large') }}',
query:{_token:'{{ csrf_token() }}'} ,// CSRF token
fileType: ['mp4'],
chunkSize: 10*1024*1024, // default is 1*1024*1024, this should be less than your maximum limit in php.ini
headers: {
'Accept' : 'application/json'
},
testChunks: false,
throttleProgressCallbacks: 1,
});
resumable.assignBrowse(browseFile[0]);
resumable.on('fileAdded', function (file) { // fayl tanlanishi bilan progressbar ishga tushadi
showProgress();
resumable.upload() // fayl yuklash boshlanadi.
});
resumable.on('fileProgress', function (file) { // progress bar fayl yuklanishiga qarab yangilanib boradi
updateProgress(Math.floor(file.progress() * 100));
});
resumable.on('fileSuccess', function (file, response) { // Progressbar yuklanish yakunlashi
response = JSON.parse(response)
$('#videoPreview').attr('src', response.path);
$('.card-footer').show();
});
resumable.on('fileError', function (file, response) { // xatolik bo'lsa ekranga chiqaramiz
alert('Fayl yuklashda xatolik.')
});
let progress = $('.progress');
function showProgress() {
progress.find('.progress-bar').css('width', '0%');
progress.find('.progress-bar').html('0%');
progress.find('.progress-bar').removeClass('bg-success');
progress.show();
}
function updateProgress(value) {
progress.find('.progress-bar').css('width', `${value}%`)
progress.find('.progress-bar').html(`${value}%`)
}
function hideProgress() {
progress.hide();
}
</script>
2# Loyihamiz backend sozlamalari
Keyingi bosqicha fayl yuklash uchun backend qismini tayyorlaymiz. Bo'laklab yuklanayotgan faylning qabul qilish va birlashtirish uchun laravel-chunk-upload kutubxonasini ishlatamiz.
- laravel-chunk-upload composer orqali o'rnatish
composer require pion/laravel-chunk-upload
- Controllerimizda quyidagi metod fayllarni qabul qiladi va serverga saqlaydi.
public function uploadLargeFiles(Request $request) {
$receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request));
if (!$receiver->isUploaded()) {
// faylni yuklashni iloji yuq
}
$fileReceived = $receiver->receive(); // faylni yuklash
if ($fileReceived->isFinished()) { // faylni yuklash to'liq yakunlandi
$file = $fileReceived->getFile(); // get file
$extension = $file->getClientOriginalExtension();
$fileName = str_replace('.'.$extension, '', $file->getClientOriginalName()); //format qo'shilmagan fayl nomi
$fileName .= '_' . md5(time()) . '.' . $extension; // unikal fayl nomi
$disk = Storage::disk(config('filesystems.default'));
$path = $disk->putFileAs('videos', $file, $fileName);
// vaqtinchalik fayllarni o'chirish
unlink($file->getPathname());
return [
'path' => asset('storage/' . $path),
'filename' => $fileName
];
}
// fayl tuliq yuklanmagan bulsa nechi foiz yuklanganini frontendga jo'natish
$handler = $fileReceived->handler();
return [
'done' => $handler->getPercentageDone(),
'status' => true
];
}
Yuqorida keltirilgan kodlarimiz loyihangizda katta hajmdagi faylarni yuklash yordam berdiga degan umidaman 😊.




