什么可以阻止服务器发送有效的响应?

时间:2016-12-28 16:51:04

标签: php apache zend-framework php-5.5 zend-framework-mvc

这个问题与this one有关,我很难解决问题,但令人惊讶的是没有。我将再次编写相同的代码 (我删除了注释和代码片段,这只是一个常规示例),只是为了使这篇文章易于理解。

目前这是我在Zend Framework 1控制器中的代码:

$('#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
        }
    }
})

这个函数被Javascript称为AJAX函数:

echo json_encode($data);

我上传的文件大小约为1.5 MB,大约有9000行(这是一个CSV文件)。

一旦我上传该文件,一切似乎都有效,这意味着PHP端的代码执行将持续到最后json_encode($data)没有“错误”。我之所以知道这一点,是因为我正在使用Xdebug来调试IDE上的代码。

由于某种原因,响应没有回到浏览器,我最终得到以下消息:“无法加载响应”,我无法正确处理响应。

enter image description here

enter image description here

enter image description here

我确实通过将{ "error": [], "file": { "name": "test1.csv", "size": "1.24kB", "file_path": "/data/tmp/php/uploads/phpSh2tZt", "file_ext": "csv", "delimiter": "", "worksheets": [] } } 的结果分配给var来检查结果,并且根据此输出,一切似乎都很好(图像上的文件名和此示例不同,但这仅用于显示正确的功能) :

Status

我已在Chrome和Firefox中检查了该过程,并且您发送的响应中没有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 ,如您在上面的图片中看到的那样。为什么?我不知道还有什么办法可以解决这个问题,我不知道错误来自哪里(它不是来自PHP代码,因为正如我所说的所有在代码级别正常工作而日志就是这样说的)而且我是坚持到这一点,能不能给我一些想法或线索呢?

如果有帮助,我的环境正在Docker中运行。

PHP设置如下:

$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();
}

PS:如果您需要任何类型的信息,请告诉我,我会将其添加到OP

更新

我刚刚发现问题所在,我对“为什么”感到好奇。拥有以下代码:

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

通过在浏览器上获取非响应来使完整代码失败。移开验证使代码正常工作:

....
$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;
}

那里可能出现什么问题?我在这里遗失了什么?

更新2

目前这是代码的样子:

// 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;
}

这也不起作用。我实现这一目标的唯一方法是转向“vanilla”PHP,如下所示:

value = 'Water'

这种方式就像魅力一样。

3 个答案:

答案 0 :(得分:0)

您使用的最大尺寸(128字节)比预期的要小得多。

您应该将ini定义的/tmp转换为完整的整数值(〜upload_max_filesize)。

例如:

128000000

答案 1 :(得分:0)

关于Status& “为什么”:

我认为在处理ajax响应的页面上使用http_response_code(200)可能有所帮助。

答案 2 :(得分: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);
}