如何在 ExtJS 上传小部件中使用额外参数 Ivan Novakov

How to use the extra params in ExtJS Upload Widget by Ivan Novakov

我正在我的网络应用程序中使用 this upload widget

我正在使用 FormDataUploader,我能够很好地将文件上传到服务器目录。但是,我还想将额外的参数发送到处理上传的 php 文件。这就是我的尝试:

var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
    uploader : 'Ext.ux.upload.uploader.FormDataUploader',

    uploaderOptions : {
       url : 'uploadGallery.php'
    },

    synchronous : true,

    uploadParams : {
        ID_Person : ID_Person,
        ID_CI : ID_CI
    }

});

如您所见,我使用了 uploadParams,但是,我的 PHP 似乎无法接收。在我的 php 文件中,我有:

$ID_Person = $_GET['ID_Person'];
$ID_CI = $_GET['ID_CI'];

但是,我的PHP似乎无法获取这些参数。

我接下来做的是使用默认的 ExtJS 上传器:

var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
    uploaderOptions : {
        url : 'uploadExtJS.php'

    },

    synchronous : true,

    uploadParams : {
        ID_Person : ID_Person,
        ID_CI : ID_CI
    }

});

起初,我使用旧的 PHP 文件,它能够获取我发送的额外参数。但是,我似乎需要为 ExtJS 上传器使用不同的 PHP 文件。

这是我的 PHP 文件的样子:

<?php
/**
 * Example processing of raw PUT/POST uploaded files.
 * File metadata may be sent through appropriate HTTP headers:
 *   - file name - the 'X-File-Name' proprietary header
 *   - file size - the standard 'Content-Length' header or the 'X-File-Size' proprietary header
 *   - file type - the standard 'Content-Type' header or the 'X-File-Type' proprietary header
 * 
 * Raw data are read from the standard input.
 * The response should be a JSON encoded string with these items:
 *   - success (boolean) - if the upload has been successful
 *   - message (string) - optional message, useful in case of error
 */
require __DIR__ . '_common.php';
$config = require __DIR__ . '_config.php';

error_reporting(-1);
ini_set('display_errors', 'On');

/*
 * You should check these values for XSS or SQL injection.
 */
if (!isset($_SERVER['HTTP_X_FILE_NAME'])) {
    _error('Unknown file name');
}
$fileName = $_SERVER['HTTP_X_FILE_NAME'];
if (isset($_SERVER['HTTP_X_FILENAME_ENCODER']) && 'base64' == $_SERVER['HTTP_X_FILENAME_ENCODER']) {
    $fileName = base64_decode($fileName);
}
$fileName = htmlspecialchars($fileName);

$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);


$inputStream = fopen('php://input', 'r');
// $outputFilename = $config['upload_dir'] . '/' . $fileName;
$outputFilename = 'gallery' . '/' . $fileName;
$realSize = 0;
$data = '';

if ($inputStream) {
    if (! $config['fake']) {
        $outputStream = fopen($outputFilename, 'w');
        if (! $outputStream) {
            _error('Error creating local file');
        }
    }

    while (! feof($inputStream)) {
        $bytesWritten = 0;
        $data = fread($inputStream, 1024);

        if (! $config['fake']) {
            $bytesWritten = fwrite($outputStream, $data);
        } else {
            $bytesWritten = strlen($data);
        }

        if (false === $bytesWritten) {
            _error('Error writing data to file');
        }
        $realSize += $bytesWritten;
    }

    if (! $config['fake']) {
        fclose($outputStream);
    }
} else {
    _error('Error reading input');
}

if ($realSize != $size) {
    _error('The actual size differs from the declared size in the headers');
}

_log(sprintf("[raw] Uploaded %s, %s, %d byte(s)", $fileName, $mimeType, $realSize));
_response();

但是,我收到内部服务器 500 错误 - 这意味着我的 php 文件可能有问题。

我主要有两个问题:

  1. 如何使 uploadParams 与 FormDataUploader 一起工作?
  2. 如何为 ExtJS 数据上传器编写 PHP 上传器?

成功了。

uploadExtJS.php 文件应如下所示:

<?php
/**
 * Example processing of raw PUT/POST uploaded files.
 * File metadata may be sent through appropriate HTTP headers:
 *   - file name - the 'X-File-Name' proprietary header
 *   - file size - the standard 'Content-Length' header or the 'X-File-Size' proprietary header
 *   - file type - the standard 'Content-Type' header or the 'X-File-Type' proprietary header
 * 
 * Raw data are read from the standard input.
 * The response should be a JSON encoded string with these items:
 *   - success (boolean) - if the upload has been successful
 *   - message (string) - optional message, useful in case of error
 */
// require  __DIR__ . '_common.php';
// $config = require  __DIR__ .  '_config.php';

require_once '_common.php';
$config = require_once '_config.php';

error_reporting(-1);
ini_set('display_errors', 'On');

/*
 * You should check these values for XSS or SQL injection.
 */
if (!isset($_SERVER['HTTP_X_FILE_NAME'])) {
    _error('Unknown file name');
}
$fileName = $_SERVER['HTTP_X_FILE_NAME'];
if (isset($_SERVER['HTTP_X_FILENAME_ENCODER']) && 'base64' == $_SERVER['HTTP_X_FILENAME_ENCODER']) {
    $fileName = base64_decode($fileName);
}
$fileName = htmlspecialchars($fileName);

$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);


$inputStream = fopen('php://input', 'r');
$outputFilename = $config['upload_dir'] . '/' . $fileName;
// $outputFilename = 'gallery' . '/' . $fileName;
$realSize = 0;
$data = '';

if ($inputStream) {
    if (! $config['fake']) {
        $outputStream = fopen($outputFilename, 'w');
        if (! $outputStream) {
            _error('Error creating local file');
        }
    }

    while (! feof($inputStream)) {
        $bytesWritten = 0;
        $data = fread($inputStream, 1024);

        if (! $config['fake']) {
            $bytesWritten = fwrite($outputStream, $data);
        } else {
            $bytesWritten = strlen($data);
        }

        if (false === $bytesWritten) {
            _error('Error writing data to file');
        }
        $realSize += $bytesWritten;
    }

    if (! $config['fake']) {
        fclose($outputStream);
    }
} else {
    _error('Error reading input');
}

if ($realSize != $size) {
    _error('The actual size differs from the declared size in the headers');
}

_log(sprintf("[raw] Uploaded %s, %s, %d byte(s)", $fileName, $mimeType, $realSize));
_response(true, "okay");

_common.php 看起来像:

<?php

function _log($value){
    error_log(print_r($value, true));
}


function _response($success = true, $message = 'OK'){
    $response = array(
        'success' => $success,
        'message' => $message
    );

    echo json_encode($response);
    exit();
}

function _error($message){
    return _response(false, $message);
}

_config.php 应如下所示:

<?php
return array(
    'upload_dir' => 'gallery',
    'fake' => false
);
?>

现在我正在使用 uniqid()microtime() 使用唯一名称,并将图像保存到子目录(或主 upload/gallery 下的任何文件夹)文件夹)使用 uploadParams() 属性.

编辑 1:重命名上传的文件

只需更改此行:

$fileName = htmlspecialchars($fileName);

至:

$fileName = uniqid() . '_' . microtime();

编辑 3:从您的附加参数中获取自定义子目录

首先,确保从 ExtJS 网络应用程序创建上传对话框时,您是这样做的:

var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
    uploaderOptions : {
        url : 'uploadExtJS.php'

    },
    synchronous : true,
    uploadParams : {
        ID_1 : ID_1,
        ID_2 : ID_2 // you can put waaay more if you want
    }
});

并在您的 uploadExtJS.php 中执行此操作(在您定义新文件名的部分和检查输入流的部分之间)

$fileName = uniqid() . '_' . microtime();

$mimeType = htmlspecialchars($_SERVER['HTTP_X_FILE_TYPE']);
$size = intval($_SERVER['HTTP_X_FILE_SIZE']);

$ID_1 = $_GET['ID_1'];
$ID_2 = $_GET['ID_2'];

$newFilePath = $config['upload_dir'] . '/' . $ID_1 . '/' . $ID_2;

if (!file_exists($newFilePath)) {
    mkdir($newFilePath, 0777, true);
}

$inputStream = fopen('php://input', 'r');
$outputFilename = $newFilePath . '/' . $fileName;

$realSize = 0;
$data = '';

如你所见,我定义了一个$newFilePath变量,在创建之前检查它是否存在,然后上传到那个目录。

希望这对以后遇到此问题的任何人有所帮助。