Skip to main content

Command Palette

Search for a command to run...

Laravel web loyihalaringizda katta o'lchamdagi fayllarni serverga yuklash.

Updated
3 min read
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.

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 😊.

More from this blog

Rashidov Nuriddin

34 posts