在同一函数中使用$_FILES变量上传图像和文件

时间:2016-05-05 作者:Kleeia

我想开始说我正在学习,我正在努力理解$_FILES$file_handler 这让我疯狂地使用这个功能,从前端表单上传附件。

我昨天发现的question 那是在使用$_FILES 在同一个函数中进行重写,所以一些好心的家伙建议用不同的方式更改此变量,如$whatever. 这两个文件都可以管理和上传,但当然这还没有发生,而且only files are uploaded. 有两个相对命名的表单输入:

图像:name="moreimages"name="morefiles"基本上,我的php已经达到了这一点:

if ($_FILES)
    {
        // Get the upload attachment files
        $images = $_FILES[\'moreimages\'];
        foreach ($images[\'name\'] as $key => $value)
        {
            if ($images[\'name\'][$key])
            {
                $image = array(
                    \'name\' => $images[\'name\'][$key],
                    \'type\' => $images[\'type\'][$key],
                    \'tmp_name\' => $images[\'tmp_name\'][$key],
                    \'error\' => $images[\'error\'][$key],
                    \'size\' => $images[\'size\'][$key]
                );

                //here I\'ve changed the $_FILES variable into something else
                $my_processed_images = array("moreimages" => $image);
                foreach ($my_processed_images as $image => $array)
                {
                    $newupload = project_images($image,$pid);
                }
            }
        }
        // Get the upload attachment files
        $files = $_FILES[\'morefiles\'];
        foreach ($files[\'name\'] as $key => $value)
        {
            if ($files[\'name\'][$key])
            {
                $file = array(
                    \'name\' => $files[\'name\'][$key],
                    \'type\' => $files[\'type\'][$key],
                    \'tmp_name\' => $files[\'tmp_name\'][$key],
                    \'error\' => $files[\'error\'][$key],
                    \'size\' => $files[\'size\'][$key],
                    \'post_mime_type\' => $files[\'type\'][$key]
                );
                $_FILES = array("morefiles" => $file);
                foreach ($_FILES as $file => $array)
                {
                    $uploadfile = project_file($file,$pid);
                }
            }
        }
    }
我的函数看起来像

function project_images($file_handler, $pid)
    {
        if ($_FILES[$file_handler][\'error\'] !== UPLOAD_ERR_OK) __return_false();
        require_once(ABSPATH . "wp-admin" . \'/includes/image.php\');
        require_once(ABSPATH . "wp-admin" . \'/includes/file.php\');
        require_once(ABSPATH . "wp-admin" . \'/includes/media.php\');
        $image_id = media_handle_upload( $file_handler, $pid );
        return $image_id;
    }
function project_file($file_handler, $pid)
    {
        if ($_FILES[$file_handler][\'error\'] !== UPLOAD_ERR_OK) __return_false();
        require_once(ABSPATH . "wp-admin" . \'/includes/image.php\');
        require_once(ABSPATH . "wp-admin" . \'/includes/file.php\');
        require_once(ABSPATH . "wp-admin" . \'/includes/media.php\');
        $file_id = media_handle_upload( $file_handler, $pid );
        update_post_meta($file_id,\'is_prj_file\',\'1\');
        return $file_id;
    }
我知道我的$file_handler 但我不知道该怎么办。真正发生的是调试$more_images 为空且未考虑,且$_FILES 进入第二个循环is uploaded 相反你能开车送我吗?

EDIT

“我的HTML表单”字段如下所示:

<input id="moreimages" accept="image/png, image/jpeg, image/gif" type="file" name="moreimages[]" >

<input id="morefiles" accept=".zip,.pdf,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.psd,.ai" type="file" name="morefiles[]" >
此外,我的AJAX POST状态正常,将这些参数发送给moreimages:

Content-Disposition: form-data; name="moreimages[]"; filename="Screen Shot 2016-04-05 at 16.48.10.png"
Content-Type: image/png

PNG
这些参数用于morefiles:

Content-Disposition: form-data; name="morefiles[]"; filename="articolo-slow-food-ararat.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
因此,我再次思考问题,这些数据是如何接收到php中的。

2 个回复
SO网友:user5200704

我确实覆盖了一些东西。我没有验证,只构建了结构化的验证和上传功能。您可以根据需要验证文件。

if ($_FILES)
    {
        // Get the upload attachment files
        $images = $_FILES[\'moreimages\'];
        $errors = \'\';
        foreach ($images[\'name\'] as $key => $value)
        {
            if ($images[\'name\'][$key])
            {
                $image = array(
                    \'name\' => $images[\'name\'][$key],
                    \'type\' => $images[\'type\'][$key],
                    \'tmp_name\' => $images[\'tmp_name\'][$key],
                    \'error\' => $images[\'error\'][$key],
                    \'size\' => $images[\'size\'][$key]
                );

                //here I\'ve changed the $_FILES variable into something else
                $_FILES[\'moreimages\'] = $image;
                if( is_wp_error( $moreimages = project_media_handle_upload(\'moreimages\',$pid) ) )
                $errors .= $moreimages->get_error_message();

            }
        }
        // Get the upload attachment files
        $files = $_FILES[\'morefiles\'];
        foreach ($files[\'name\'] as $key => $value)
        {
            if ($files[\'name\'][$key])
            {
                $file = array(
                    \'name\' => $files[\'name\'][$key],
                    \'type\' => $files[\'type\'][$key],
                    \'tmp_name\' => $files[\'tmp_name\'][$key],
                    \'error\' => $files[\'error\'][$key],
                    \'size\' => $files[\'size\'][$key],
                    \'post_mime_type\' => $files[\'type\'][$key]
                );
                $_FILES[\'morefiles\'] = $file;
                if( is_wp_error( $morefiles = project_media_handle_upload( \'morefiles\', $pid, \'file\' ) ) )
                $errors .= $morefiles->get_error_message();
            }
        }

        if( ! empty( $errors) )
        echo $errors;
    }

function image_and_files_validate_handle( $file ){
    // $file provide all values size, name etc
    // conditional statement here and return every time fixed key with message
    $file[\'error\'] =  \'File is invalid\';
    return $file;
}

function file_upload_validate_handle( $file ){
    // $file provide all values size, name etc
    // conditional statement here and return every time fixed key with message
    $file[\'error\'] =  $file[\'name\']. \' is invalid format.\';
    return $file;
}

add_action( \'project_media_handle_upload\', \'save_file_meta_content_id\', 10, 2 );

function save_file_meta_content_id( $fid, $type ){
  if( $type == \'file\')
  update_post_meta($fid,\'is_prj_file\',\'1\'); 
}


function project_media_handle_upload( $file_id, $pid, $type= "image" ){

  $action = \'image_upload_action\'; //  change custom action name easy to understand

  if( $type !== \'image\')
  $action = \'file_upload_action\'; 

  if( function_exists(\'check_upload_size\') )
  add_filter(  "{$action}_prefilter", \'check_upload_size\'); // wordpress default filter to check upload size

  add_filter(  "{$action}_prefilter", \'image_and_files_validate_handle\'); // both conditional validation for images and files
  add_filter(  "file_upload_action_prefilter", \'file_upload_validate_handle\');

  require_once(ABSPATH . "wp-admin" . \'/includes/image.php\');
  require_once(ABSPATH . "wp-admin" . \'/includes/file.php\');
  require_once(ABSPATH . "wp-admin" . \'/includes/media.php\');
  $result =  media_handle_upload( $file_id, $pid, array(), array( 
    \'test_form\' => false,
    \'action\' => $action
  ));

  if( ! is_wp_error($result) )
  do_action( \'project_media_handle_upload\', $result, $type );   

  return $result;
}

SO网友:Kleeia

每个人都很有用,我要感谢你们帮助了我。问题似乎确实出在$\\u FILES变量中,该变量会在2个循环中覆盖自身。经过几次尝试,我发现这个解决方案适合我,可以上传图像和文件。

if ($_FILES)
    {
        // I\'ve firstly declared main variables
        $images = $_FILES[\'moreimages\'];
        $files = $_FILES[\'morefiles\'];

        //then I check for both if they\'re empty. That was just it.
        if(!empty($images)) {
            foreach ($images[\'name\'] as $key => $value)
            {
                if ($images[\'name\'][$key])
                {
                    $image = array(
                        \'name\' => $images[\'name\'][$key],
                        \'type\' => $images[\'type\'][$key],
                        \'tmp_name\' => $images[\'tmp_name\'][$key],
                        \'error\' => $images[\'error\'][$key],
                        \'size\' => $images[\'size\'][$key]
                    );
                    $_FILES = array("moreimages" => $image);
                    foreach ( $_FILES as $image => $array ) {
                        if ( $_FILES[$image][\'error\'] !== UPLOAD_ERR_OK ) __return_false();
                        require_once( ABSPATH . "wp-admin" . \'/includes/image.php\' );
                        require_once( ABSPATH . "wp-admin" . \'/includes/file.php\' );
                        require_once( ABSPATH . "wp-admin" . \'/includes/media.php\' );
                        $image_id = media_handle_upload( $image, $pid );
                        update_post_meta( $pid, \'project_image\',$image_id);
                    }
                }

            }
        }
        if(!empty($files)) {
            foreach ($files[\'name\'] as $key => $value)
            {
                if ($files[\'name\'][$key])
                {
                    $file = array(
                        \'name\' => $files[\'name\'][$key],
                        \'type\' => $files[\'type\'][$key],
                        \'tmp_name\' => $files[\'tmp_name\'][$key],
                        \'error\' => $files[\'error\'][$key],
                        \'size\' => $files[\'size\'][$key]
                    );
                    $_FILES = array("morefiles" => $file);
                    foreach ( $_FILES as $file => $array ) {
                        if ( $_FILES[$file][\'error\'] !== UPLOAD_ERR_OK ) __return_false();
                        require_once( ABSPATH . "wp-admin" . \'/includes/image.php\' );
                        require_once( ABSPATH . "wp-admin" . \'/includes/file.php\' );
                        require_once( ABSPATH . "wp-admin" . \'/includes/media.php\' );
                        $file_id = media_handle_upload( $file, $pid );
                        update_post_meta( $file_id, \'is_prj_file\', \'1\');
                    }
                } 
            }
        }
    }
也许这段代码并不是很有效和完美,但它确实做到了。此外,它仍然没有文件验证服务器端,我稍后将按照前面的建议实现该服务器端。