這個問題與this one有關,我很難解決這個問題,但令人驚訝的是不是。我會再次編寫相同的代碼(我已經刪除了評論和代碼片斷,這只是一個普遍的例子),只是爲了讓這篇文章可以理解。什麼可能會阻止服務器發送有效響應?
目前,這是在Zend框架1個控制器的代碼我有:
public function uploadAction()
{
$this->_helper->viewRenderer->setNoRender();
$data = $errors = $line_of_text = [];
if ($this->getRequest()->isPost()) {
$path = '/cronjobs/uploads/charge_type_details';
if ([email protected]($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 MB的大小和約9000行(這是一個CSV文件)。
只要我上傳該文件似乎一切正常,這意味着PHP端的代碼執行直到最後echo json_encode($data);
沒有「錯誤」。我確實知道這一點,因爲我使用Xdebug來調試IDE上的代碼。
由於某種原因,響應沒有回到瀏覽器,我最終收到以下消息:「無法加載響應」,我無法正確處理響應。
我沒有被分配給一個變種,一切檢查的json_encode($data)
結果似乎是罰款,按照該輸出(圖像和本文件名示例是不同的,但這只是爲了顯示正確的功能):
{
"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:如果你需要任何種類的信息讓我知道,我將它添加到OP
UPDATE
我剛剛發現問題出在哪裏,我對「爲什麼」很好奇。有以下一段代碼:
$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;
}
這樣,它就像一個魅力。
如果您使用的Xdebug不能你通過它退一步,看到它在驗證碼停止點什麼? – mickadoo
@mickadoo是的,我有Xdebug,但代碼稍微直到執行結束沒有錯誤,這很奇怪 – ReynierPM
嗯,但你說驗證代碼失敗。它是否在沒有驗證碼的情況下工作100% - 您是否在瀏覽器中獲得正確的回覆? – mickadoo