什么可能会阻止服务器发送有效响应?
这个问题与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;
}
这样,它就像一个魅力。
您正在使用比您预期的小得多的最大大小(128字节)。
您应该将您的ini定义的upload_max_filesize
转换为完整整数值(〜128000000
)。
例如:
$adapter->addValidator('Size', false, ['max' => 128000000]);
这也没有工作要么 – ReynierPM
关于Status
& “为什么”:
我认为使用http_response_code(200)页面处理Ajax响应可能会有帮助。
我不认为这是一个很好的解决方案,因为请求可能会失败 – ReynierPM
不应该在某处调用“$ 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);
}
检查**更新2 **有你的答案...我使用'$ adapter-> receive()=== false' ... – ReynierPM
如果您使用的Xdebug不能你通过它退一步,看到它在验证码停止点什么? – mickadoo
@mickadoo是的,我有Xdebug,但代码稍微直到执行结束没有错误,这很奇怪 – ReynierPM
嗯,但你说验证代码失败。它是否在没有验证码的情况下工作100% - 您是否在浏览器中获得正确的回复? – mickadoo