PHP Allowed memory size of XXXXXXXX bytes

Я загружаю pdf файл, и сохраняю данные из этого файла в базу данных, но когда размер файла больше 1М, я получаю ошибку про ограничение памяти. После этой строки let magBytes = new Uint8Array(evt.target.result); я получаю массив более с 2-3 милион эелементами

$scope.parseFile = function(file) {
        let fileSize = file.size;
        let chunkSize = 512 * 1024; // bytes
        let offset = 0;

        if (fileSize > 52428800) {
            $scope.showMagUploadModal = true;
            $scope.showDateModal = false;
            $scope.showMagImportResultMessage = false;
            $scope.magMessage = 'File should not be more than 50MB';
        } else {
            // Now let's start the read with the first block
            $scope.chunkReaderBlock(offset, chunkSize, file, fileSize);
        }
    }


    $scope.chunkReaderBlock = function(_offset, length, _file, fileSize) {

        let readEventHandler = function(evt) {
            let magBytes = new Uint8Array(evt.target.result);
            if (evt.target.error == null && !$scope.loadFile) {
                $scope.magUploadFileProgressMessage = 'PLease wait! File is loading';
                _offset += magBytes.length;
                $scope.progressBar = Math.ceil((_offset / fileSize) * 100);
                $scope.loadFile = false;
                $scope.sendMagFile(magBytes, $scope.loadFile, _offset, length, _file, fileSize); // callback for handling read chunk
            } else if (evt.target.error != null) {
                $scope.magUploadFileProgressMessage = 'Sorry! An error occurred while downloading the file, please try again';
                return;
            }
        }

        let reader = new FileReader();
        let blob = _file.slice(_offset, length + _offset);
        reader.onload = readEventHandler;
        reader.readAsArrayBuffer(blob);
    }

    $scope.sendMagFile = function(magBytes, loadFile, _offset = null, length = null, _file = null, fileSize = null) {
        $http.post('/mag/upload', { 'mag_bytes':magBytes, 'is_file_loaded': loadFile}).then((result) => {
            if (result.status === 200) {
                if (loadFile) {
                    if (result.data.message === 'Map year is required') {
                        $scope.showDateModal = true;
                        $scope.magUploadFileProgressMessage = 'File loaded successfully';
                    } else if (result.data.message === 'Uploaded file is not a MAG') {
                        $scope.magMessage = 'Uploaded file is not a MAG';
                        $scope.showMagUploadModal = false;
                        $scope.showDateModal = false;
                        $scope.showMagImportResultMessage = true;
                    } else {
                        $scope.showMagUploadModal = false;
                        $scope.showDateModal = false;
                        $scope.showMagImportResultMessage = true;
                        $scope.magMessage = 'MAG imported result';
                    }
                } else {
                    if (_offset < fileSize) {
                        $scope.chunkReaderBlock(_offset, length, _file, fileSize);
                    } else {
                        $scope.loadFile = true;
                        $scope.sendMagFile(magBytes, true)
                    }
                }
            }

            // alert(777);
        }).catch((e) => {
            console.log(e);
        });
    }

и когда в php я вызываю function pack('C*'), тогда и получаю эту ошибку. Я здесь изменил первичную загрузку, загрузка файла зделал по частям, и не полущаю ошибку,

 if (!$isFileLoaded) {
            $magStr = call_user_func_array("pack", array_merge(array("C*"), $magBytes));
            if (count($magStr) < (512 * 1024)) {
                $_SESSION['mag_str'] = $magStr;
            } else {
                $_SESSION['mag_str'] .= $magStr;
            }

            return response()->json(['message' => 'File is loading']);
        } else {
            if (is_null($appraisalYear)) {
                $magStr = $_SESSION['mag_str'];
                $magObject = self::magDecode($magStr);
                if (!$magObject['Section_3_AppraisalDetails']) {
                    return response()->json(['message' => 'Uploaded file is not a MAG']);
                }
                $magAttachmentsData = self::magExtract($magStr);
                $_SESSION['mag_object'] = $magObject;
                $_SESSION['$mag_attachments_data'] = $magAttachmentsData;
                $section3 = $magObject['Section_3_AppraisalDetails'];

                if (isset($section3['appraisalYear']) && strpos($section3['appraisalYear'], 'Please select...') === false) {
                    $mapYearArray = explode('/', $section3['appraisalYear']);
                    $mapYear = $mapYearArray[0];
                } else {
                    return response()->json(['message' => 'Map year is required']);
                }
            } else {
                $mapYear = $appraisalYear;
                $magObject = $_SESSION['mag_object'];
                $magAttachmentsData = $_SESSION['$mag_attachments_data'];
                unset($_SESSION['mag_object']);
                unset($_SESSION['$mag_attachments_data']);
            }
        }

но когда все это объединяется в одно целое я снова полущаю эту ошибку, в этих двух функциях снова исползуется functions pack() и unpack().

private function magDecode($binary_content) {
        $streams = array();
        $start = ">>stream";
        $end = "endstream";
        $start_len = strlen($start);
        $end_len = strlen($end);
        $start_count = 0;
        $end_count = 0;
        $off = true;
        $from = -1;
        for ($i = 0; $i < strlen($binary_content) - $end_len; $i++) {
            if ($off) {
                $start_detect = substr($binary_content, $i, $start_len);
                if ($start_detect == $start) {
                    $start_count++;
                    $off = false;
                    $from = $i + $start_len;
                }
            } else {
                $end_detect = substr($binary_content, $i, $end_len);
                if ($end_detect == $end) {
                    $end_count++;
                    $off = true;
                    $streams[] = substr($binary_content, $from, $i - $from);
                }
            }
        }

        $result = null;

        foreach ($streams as $key => $value) {
            $byte_array = unpack('C*', $value);
            if ($byte_array[1] == 10) {
                $byte_array = array_slice($byte_array, 1);
            } else if ($byte_array[1] == 13 && $byte_array[2] == 10) {
                $byte_array = array_slice($byte_array, 2);
            }
            if ($byte_array[0] == 72 && $byte_array[1] == 137) {
                $value = @gzuncompress(call_user_func_array("pack", array_merge(array("C*"), $byte_array)));
                preg_match('/AppraisalSummary/', $value, $d); // searching for MAG data
                if (count($d) > 0) {
                    $value = str_replace(array("\r", "\n"), '', $value);
                    try { // some zipped values are not what we need and cannot be processed properly, exceptions are thrown
                        $result = self::extract_from_xml($value)['xfa:datasets']['xfa:data']['Root'];
                    } catch (Exception $e) {}
                }
            }
        }

        return $result;
    }

и

private function magExtract($binary_content) {
        $extracted = array();
        preg_match_all('/EF<<\/F (.*?) R>>\/F\((.*?)\)\/Type\/Filespec\/UF.*?>>/s', $binary_content, $data_array);
        $indexes = $data_array[1];
        $filenames = $data_array[2];
        $content = array();
        foreach ($indexes as $key => $index) {
            $filename = $filenames[$key];
            $end = "endstream";
            $end_len = strlen($end);
            preg_match('/'.$index.' obj.*?>>stream/s', $binary_content, $matches, PREG_OFFSET_CAPTURE);
            $from = $matches[0][1]+strlen($matches[0][0]);
            for ($i = $from; $i < strlen($binary_content) - $end_len; $i++) {
                $end_detect = substr($binary_content, $i, $end_len);
                if ($end_detect == $end) {
                    $content[] = substr($binary_content, $from, $i - $from);
                    break;
                }
            }
            $byte_array = unpack('C*', $content[$key]);
            if ($byte_array[1] == 10) {
                $byte_array = array_slice($byte_array, 1);
            } else if ($byte_array[1] == 13 && $byte_array[2] == 10) {
                $byte_array = array_slice($byte_array, 2);
            }
            $value = @zlib_decode(call_user_func_array("pack", array_merge(array("C*"), $byte_array)));
            if (strlen($value) != 0) {
                $extracted[$filename] = $value;
            }
        }
        return $extracted;
    }

Я получаю эту опибку в этом строке.

$byte_array = unpack('C*', $content[$key]);

Кто нибудь может помочь мне. Заранее спасибо .


Ответы (0 шт):