Что может остановить сервер для отправки действительного ответа?

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

В настоящее время этот код у меня в контроллере Zend Framework 1:

public function uploadAction()
{
$this->_helper->viewRenderer->setNoRender();
$data = $errors = $line_of_text = [];

if ($this->getRequest()->isPost()) {
$path = '/cronjobs/uploads/charge_type_details';

if (!@mkdir($path, 0777, true) && !is_dir($path)) {
$data['error'][] = "Not able to create subdirectory: <strong>{$path}</strong>";
echo json_encode($data);

die();
}

$di = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($ri as $file) {
$file->isDir() ? rmdir($file) : unlink($file);
}

$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($path);
$adapter->addValidator('Extension', false, ['extension' => 'csv', 'case' => true]);
$adapter->addValidator('MimeType', false, 'text/plain');
$adapter->addValidator('Size', false, ['max' => ini_get('upload_max_filesize').'B']);

if ($adapter->isValid() === false) {
foreach ($adapter->getMessages() as $message) {
$data['error'][] = $message;
}

echo json_encode($data);

die();
}

$file     = $adapter->getFileInfo()['file'];
$ext      = pathinfo($file['name'])['extension'];
$new_path = $file['tmp_name'];

$file_handle = fopen($new_path, 'r');

while (($result = fgetcsv($file_handle)) !== false) {
if (array(null) !== $result) { // ignore blank lines
$line_of_text[] = $result;
}
}

$unique_rows = array_unique($line_of_text, SORT_REGULAR);

if (false === $this->isFileHeadersValid(
array_map('strtolower', $unique_rows[0]),
[
'country',
'charge_type',
'charge_type_code',
'business_sla_description',
'service_provider',
'sub_menu',
'charge_type_group',
'transaction_type',
'slc_code',
'coverage_code',
'standard_sla',

]
)
) {
$data['error'][] = $this->translate->_('Required file headers are not present. Please check the file and try again.');
echo json_encode($data);

die();
}

unset($unique_rows[0]);

$data['error'] = $errors;

$data['file'] = array(
'name'     => $file['name'],
'size'     => $adapter->getFileSize(),
'file_ext' => $ext
);
} else {
$data['error'] = 'Invalid request.';
}

echo json_encode($data);

die();
}

Эта функция вызывается Javascript как функция AJAX:

$('#fileupload').show().fileupload({
url: '/upload',
cache: false,
dataType: 'json',
done: function (e, data) {
if (data.result.error.length > 0) {
// process errors here
} else {
// do something here
}
}
})

Я загружаю файл размером около 1,5 МБ и около 9000 строк (это файл CSV).

Как только я загружаю этот файл, кажется, что все работает, и это означает, что выполнение кода на стороне PHP продолжается до последнего echo json_encode($data); без «ошибка». Я знал это, потому что я использую Xdebug для отладки кода в IDE.

По какой-то причине ответ не возвращается в браузер, и я получаю следующее сообщение: «Не удалось загрузить ответ», и я не могу правильно обработать ответ.

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Я проверил результат json_encode($data) присваивая его переменной var, все выглядит нормально в соответствии с этим выводом (имена файлов на изображениях и в этом примере отличаются, но это только для показа надлежащей функциональности):

{
"error": [],
"file": {
"name": "test1.csv",
"size": "1.24kB",
"file_path": "/data/tmp/php/uploads/phpSh2tZt",
"file_ext": "csv",
"delimiter": "",
"worksheets": []
}
}

Я проверил процесс в Chrome и Firefox, и нет Status на ответ отправлен, как вы могли видеть на изображениях выше. Зачем? Я не знаю, что еще нужно сделать, чтобы это исправить, я не знаю, откуда исходит ошибка (это не из PHP-кода, потому что, как я уже сказал, все работает правильно на уровне кода и логи так сказали), и я застрял в этой точке, кто-нибудь может дать мне некоторые идеи или подсказки по этому поводу?

Моя среда работает в Docker, если это поможет.

Настройка PHP выглядит следующим образом:

memory_limit = 2048M
post_max_size = 128M
upload_max_filesize = 128M
date.timezone = UTC
max_execution_time = 120
short_open_tag=On
serialize_precision=100
session.gc_maxlifetime=7200
session.entropy_length=0

PS: если вам нужна какая-либо информация, дайте мне знать, и я добавлю ее в ОП

ОБНОВИТЬ

Я только что узнал, где может быть проблема, и мне любопытно, почему. Имея следующий кусок кода:

$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($path);
$adapter->addValidator('Extension', false, ['extension' => 'csv', 'case' => true]);
$adapter->addValidator('MimeType', false, 'text/plain');
$adapter->addValidator('Size', false, ['max' => ini_get('upload_max_filesize').'B']);

if ($adapter->isValid() === false) {
foreach ($adapter->getMessages() as $message) {
$data['error'][] = $message;
}

echo json_encode($data);

die();
}

Делает полный код сбоев, получая неответ в браузере. Удаление проверки делает код для правильной работы:

$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($path);

Что там может быть не так? Я что-то здесь упускаю?

ОБНОВЛЕНИЕ 2

Вот как выглядит код:

....
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($path);
$adapter->addValidator('Extension', false, ['extension' => 'csv', 'case' => true]);
$adapter->addValidator('MimeType', false, ['text/plain', 'text/csv']);
$adapter->addValidator('Size', false, ['max' => $this->SizeToBytes(ini_get('upload_max_filesize'))]);

if ($adapter->receive() === false || $adapter->isValid() === false) {
foreach ($adapter->getMessages() as $message) {
$data['error'][] = $message;
}

echo json_encode($data);

return true;
}
....
private function SizeToBytes($val)
{
$val  = trim($val);
$last = strtolower($val[strlen($val) - 1]);
switch ($last) {
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}

return $val;
}

Это тоже не работает. Единственный способ заставить это работать — перейти на «ванильный» PHP следующим образом:

// Validate file mimetype
if (!in_array($adapter->getMimeType(), ['text/plain', 'text/csv'])) {
$data['error'][] = $this->translate->_('File is not valid only CSV files are accepted!');
echo json_encode($data);

return true;
}

// Validate file extension
if ($ext !== 'csv') {
$data['error'][] = $this->translate->_('File extension is not valid only CSV files are accepted!');
echo json_encode($data);

return true;
}

// Validate file size depending on php.ini upload_max_filesize configuration
$max = $this->SizeToBytes(ini_get('upload_max_filesize'));
if ($file['size'] > $max) {
$data['error'][] = $this->translate->_e('File size is not valid! The size should be less than: ').ini_get('upload_max_filesize').'B';
echo json_encode($data);

return true;
}

Таким образом, это работает как шарм.

2

Решение

Вы используете гораздо меньший максимальный размер (128 байт), чем вы предполагали.

Вы должны конвертировать ваши INI определены upload_max_filesize до полного целочисленного значения (~128000000).

Например:

$adapter->addValidator('Size', false, ['max' => 128000000]);
0

Другие решения

Учитывая Status & «почему»:

Я думаю, используя http_response_code (200) при обработке страницы может помочь ответ ajax.

0

Разве вы не должны вызывать «$ adapter-> receive ()» где-нибудь?

https://framework.zend.com/manual/1.11/en/zend.file.transfer.introduction.html

$adapter = new Zend_File_Transfer_Adapter_Http();

$adapter->setDestination('C:\temp');

if (!$adapter->receive()) {
$messages = $adapter->getMessages();
echo implode("\n", $messages);
}
0
По вопросам рекламы [email protected]