Проблема с временным каталогом PHP

Я новичок в этом временном каталоге и управляю файлами на сервере с помощью PHP, поэтому любая помощь будет полезна. Итак, суть здесь в том, что я нажимаю, чтобы загрузить либо один конкретный файл, либо все файлы. Хитрость заключается в том, что в зависимости от конкретного условия данные возвращаются из API в виде потока, а другое возвращается как контент (в данном случае html). На мой взгляд, эта логика должна работать. У меня есть сообщение, возвращающееся как истинное или ложное, чтобы определить, является ли это потоком или это содержимое файла. Но что-то в этих двух условиях нарушается. Мне удалось заставить работать все виды дел. По отдельности они скачивают нормально, но потом перерывы в массовой загрузке или наоборот, если я перемещу код. Какие-либо предложения?

public function downloadTranslations(Request $request, $id)
{
    $target_locales = $request->input("target_locale");
    $has_source = $request->input("source");
    $client = new API(Auth::user()->access_token, ZKEnvHelper::env('API_URL', 'https://myaccount.site.com'));
    $document = Document::find($id);
    $job_document = JobDocument::where('document_id', $id)->first();
    $job = Job::find($job_document->job_id);

    $file = tempnam('tmp', 'zip');
    $zip = new ZipArchive();
    $zip->open($file, ZipArchive::OVERWRITE);
    $name_and_extension = explode('.', $document->name);

    if($target_locales == null){
        $target_locales = [];
        foreach ($job->target_languages as $target_language) {
            $target_locales[] = $target_language['locale'];
        }
    }
    foreach($target_locales as $target_locale){
        $translation = $client->downloadDocument($document->document_id, $target_locale);
        $stream = Stream::factory($translation->get('body'));
            $filename = $name_and_extension[0] . ' (' . $target_locale . ').' . $name_and_extension[1];
            if($translation->get('message') == 'true') {

                $tmpfile = tempnam(sys_get_temp_dir(), 'lingo');

                $handle = fopen($tmpfile, 'w');
                fwrite($handle, $stream->getContents());
                $zip->addFile($tmpfile, $filename);

                fclose($handle);
            }
            else if($translation->get('message') == 'false'){
                $zip->addFromString($filename, $translation->get('body'));
            };
        }
        $translation = $client->downloadDocument($document->document_id, null, null);

        $filename = $name_and_extension[0].  ' (Source).'.$name_and_extension[1];
        $zip->addFromString($filename, $translation->get('body'));
        $zip->close();

    return response()->download($file, $name_and_extension[0].'.zip')->deleteFileAfterSend(true);

1 ответ

Я нашел это в вашем коде, я даже не знаю, как он не тормозит:

        else if($translation->get('message') == 'false'){
            $zip->addFromString($filename, $translation->get('body'));
        };

я не думаю, что точка с запятой должна быть там... в любом случае.

Я также вижу в вашем коде это: $file = tempnam('tmp', 'zip');

Убедитесь, что эта функция действительно создает разные значения, возможно, возвращая эту строку, если нет, то в запросе из вашего потока может быть какое-то состояние гонки.

Это проблема, с которой я столкнулся несколько недель назад. Попробуйте что-то вроде этого: добавьте мой код к вашим потребностям..

    $zip_name = 'yourAmazing.zip';
    $zip_path = storage_path('temp/');

    // If the zip path doesnt exist, create it.
    if (!file_exists($zip_path)) {
        File::makeDirectory($zip_path);
        mkdir($zip_path, 666, true);
    }else{
        // Do nothing realy
    }

    // If the zip file already exist, delete it so you don't have problems when trying to create it again and you don't have to validate if each file is on there
    if (file_exists($zip_path . $zip_name)) {
        File::delete($zip_path . $zip_name);
    }

    // create your zip
    $zip = Zip::create($zip_path . $zip_name);
    // add your temp folder files
    $zip->add(storage_path('/temp/folderofyourfiles'));

    $zip->close();

    // DELETE directory where the files where stored, 
    // since they are already on the zip
    File::deleteDirectory(storage_path('/temp/folderofyourfiles'));

    // DELETE AFTER SEND does what it says assuring it delete the temp file
    // However, if the transfer is interrupted, the file wont delete, since the
    // send event was not terminated. Leaving the file there, thats why i check 
    // that the ZIP doesn't exist already
    return response()
           ->download($zip_path . $zip_name, 'The name for your download')
           ->deleteFileAfterSend(true);
Другие вопросы по тегам