如何用简单的表格上传图片?

时间:2013-05-05 作者:Monogot

我在我的个人资料页面中编写插件,我想通过“浏览”按钮和“目录”字段创建上传,上传并返回图像url。我不想使用媒体上传。

我以前读过Set Featured Image Front Frontend Form? 我不懂代码帮我解决这个问题?

3 个回复
SO网友:s_ha_dum

有几个部分。

您需要添加enctype 到配置文件窗体。

function edit_form_type_wpse_98375() {
    echo \' enctype="multipart/form-data"\';
}
add_action(\'user_edit_form_tag\',\'edit_form_type_wpse_98375\');
然后在表单中添加一个字段。

function user_fields_wpse_98375($profileuser) {
  $_profile_photo = get_user_meta($profileuser->data->ID,\'_profile_photo\',true);

  echo \'<h3>\'.__(\'Additional User Data\',THEME_TEXTDOMAIN).\'</h3>\';
    echo \'<tr class="show-admin-bar">\';
      echo \'<th scope="row">\'.__(\'Profile Photo\', THEME_TEXTDOMAIN).\'</th>\';
      echo \'<td\'.$tspan.\'>\';
        echo \'<fieldset>\';
          echo \'<legend class="screen-reader-text"><span>\'.__(\'Profile Photo\', THEME_TEXTDOMAIN).\'</span></legend>\';
          echo \'<label for="profile_photo">\';
            echo \'<input name="profile_photo" type="file" id="profile_photo" value="" />\';
          echo \'</label><br />\';
        echo \'</fieldset>\';
      echo \'</td>\';
    echo \'</tr>\';
  echo \'</table>\';
}
add_action(\'show_user_profile\', \'user_fields_wpse_98375\');
add_action(\'edit_user_profile\', \'user_fields_wpse_98375\');
然后保存数据。

function save_user_custom($id=false) {
  global $_FILES,$_POST;
  if (false === $id) return false;

  // save image
  if (isset($_FILES)) {
    if (isset($_FILES[\'profile_photo\'])){
      if (0 === $_FILES[\'profile_photo\'][\'error\']) {
        // This is where you save the file
        // Maybe use wp_handle_upload
        // Or use the Filesystem API
        // not sure what you want to do
      }
    }
    unset($up);
  }
}
add_action(\'personal_options_update\',\'save_user_custom\');
add_action(\'edit_user_profile_update\',\'save_user_custom\');
wp_handle_upload 可能是最简单的。抄本:

if ( ! function_exists( \'wp_handle_upload\' ) ) 
    require_once( ABSPATH . \'wp-admin/includes/file.php\' );
$uploadedfile = $_FILES[\'file\'];
$upload_overrides = array( \'test_form\' => false );
$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
if ( $movefile ) {
    echo "File is valid, and was successfully uploaded.\\n";
    var_dump( $movefile);
} else {
    echo "Possible file upload attack!\\n";
}
Thefile 输入类型的工作方式(主要)与任何其他表单输入一样。如果你给它起个这样的名字my_uploads[\'profile_photo\'] 而不仅仅是profile_photo 您将获得一个数组。这将反映在$_FILES 处理表单提交时的变量。您可以添加任意多个file 通过构建该数组,甚至只是给它们起不同的名称,可以根据需要进行输入。尽可能动态添加file 输入,这是非常简单的Javascript。

参考文献

http://codex.wordpress.org/Function_Reference/wp_handle_upload
http://codex.wordpress.org/Filesystem_API

SO网友:Ralf912

我想你对PHP和文件上传还不是很熟悉。因此,我从一些基础知识开始,以一个简单的类结束。

如果您尚未阅读basics about file uploads 使用PHP,现在就开始。没有人会在这里为你解释,这是离题的。

让我们从基本的HTML表单开始

if( empty( $_FILES ) ) {
global $pagenow;
$url = admin_url( $pagenow );
?>
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="<?php echo $url; ?>" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>
<?php
} else {
    $imageupload = new File_Upload();
    $attachment_id = $imageupload->create_attachment();
    var_dump( $attachment_id );
}
这很简单。如果超全局数组$_FILES 为空,表示没有上载文件,请显示上载表单。如果不为空,请处理上载。我使用admin_url() 以及$pagenow var创建操作url。如果您在前端使用上载表单,则必须使用home_url() 或者类似的东西。

用HTML发送文件后,您必须处理上载的文件。这将在File_Upload

class File_Upload
{
    /**
     * Index key from upload form
     * @var string
     */
    public $index_key = \'\';

    /**
     * Copy of superglobal array $_FILES
     * @var array
     */
    public $files = array();

    /**
     * Constructor
     * Setup files array and guess index key
     */
    public function __construct(){

        if ( isset( $_FILES ) && ! empty( $_FILES ) ) {
            $this->files = $_FILES;
            $this->guess_index_key();
        }

    }

    /**
     * Set/overwrites the index key
     * Converts $name with type casting (string)
     *
     * @param   string  $name   Name of the index key
     * @return  string  ::name  Name of the stored index key
     */
    public function set_field_name_for_file( $name = \'\' ) {
        $this->index_key = ( ! empty( $name ) ) ? (string) $name : \'\';
        return $this->index_key;
    }

    /**
     * Converts uploaded file into WordPress attachment
     *
     * @return  boolean     Whether if the attachment was created (true) or not (false)
     */
    public function create_attachment(){

        // move the uploaded file from temp folder and create basic data
        $imagedata = $this->handle_uploaded_file();

        // if moving fails, stop here
        /*
         * For Production
         * Set and return an error object with WP_Error()
         */
        if ( empty( $imagedata ) )
            return false;

        /*
         * For Production
         * Check if $imagedata contains the expected (and needed)
         * values. Every method could fail and return malicious data!!
         */
        $filename = $imagedata[\'filename\'];

        // create the attachment data array
        $attachment = array(
                \'guid\'           => $imagedata[\'url\'] . \'/\' . $filename,
                \'post_mime_type\' => $imagedata[\'type\'],
                \'post_title\'     => preg_replace(\'/\\.[^.]+$/\', \'\', $filename ),
                \'post_content\'   => \'\',
                \'post_status\'    => \'inherit\'
        );

        // insert attachment (posttype attachment)
        $attach_id = wp_insert_attachment( $attachment, $filename );

        // you must first include the image.php file
        // for the function wp_generate_attachment_metadata() to work
        require_once( ABSPATH . \'wp-admin/includes/image.php\' );

        /*
         * For Production
         * Check $attach_data, wp_generate_attachment_metadata() could fail
         * Check if wp_update_attachment_metadata() fails (returns false),
         * return an error object with WP_Error()
         */
        $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
        wp_update_attachment_metadata( $attach_id, $attach_data );

        return $attach_id;

    }

    /**
     * Handles the upload
     *
     * @return  array   $return_data    Array with informations about the uploaded file
     */
    protected function handle_uploaded_file() {

        // get the basic data
        $return_data = wp_upload_dir();

        // get temporary filepath and filename from $_FILES ($this->files)
        $tmp_file = ( isset( $this->files[$this->index_key] ) && ! empty( $this->files[$this->index_key] ) ) ?
            (string) $this->files[$this->index_key][\'tmp_name\'] : \'\';

        $tmp_name = ( isset( $this->files[$this->index_key] ) && ! empty( $this->files[$this->index_key] ) ) ?
            (string) $this->files[$this->index_key][\'name\'] : \'\';

        // stop if something went wrong
        if ( empty( $tmp_file ) )
            return false;

        // set filepath
        $filepath = $return_data[\'filepath\'] = $return_data[\'path\'] . \'/\' . basename( $tmp_name );

        // move uploaded file from temp dir to upload dir
        move_uploaded_file( $tmp_file , $filepath );

        // set filename
        $filename = $return_data[\'filename\'] = basename( $filepath );

        // set filetype
        /*
         * For Production
         * You should really, really check the file extension and filetype on 
         * EVERY upload. If you do not, it is possible to upload EVERY kind of 
         * file including malicious code.
         */
        $type = wp_check_filetype( $filename, null );
        $return_data[\'file_ext\'] = ( isset( $type[\'ext\'] ) && ! empty( $type[\'ext\'] ) ) ?
        $type[\'ext\'] : \'\';

        $return_data[\'type\'] = ( isset( $type[\'type\'] ) && ! empty( $type[\'type\'] ) ) ?
        $type[\'type\'] : \'\';

        // return the results
        return $return_data;

    }

    /**
     * Try to fetch the first index from $_FILES
     *
     * @return  boolean     Whether if a key was found or not
     */
    protected function guess_index_key() {

        $keys = array_keys( $_FILES );

        if ( ! empty( $keys ) ) {
            $this->index_key = $keys[0];
            return true;
        }

        return false;

    }

}
这是一个基本类not for production! 文件上载是一个非常敏感的话题,您必须自己验证和清理所有数据。否则,可能有人上传恶意代码并入侵您的服务器/博客/网站!

现在,一步一步地,在何时何地发生了什么。

通过创建类的实例,该类尝试创建超全局数组的副本$_FILES. 如果使用超全局阵列,请不要触摸它们!也许代码的其他部分(插件或主题)也需要其中的数据。构造函数中发生的下一件事是,我们尝试猜测索引键。正如您所知,我们可以传递多个文件$_FILES 可以包含所有上载文件的数据。如果需要处理多个文件,请循环$_FILES 并将索引键设置为set_field_name_for_file()

// get the indexes from $_FILES
$keys = array_keys( $_FILES );
$upload_processor = new File_Upload();
foreach ( $keys as $key ) {
  $upload_processor->set_field_name_for_file( $key );
  $upload_processor->create_attachment();
}
set_field_name_for_file() 如果您想从HTML表单中pic一个特定字段,也需要使用,否则类将使用它可以找到的第一个索引。

下一步是处理上传的文件。方法create_attachment() 调用受保护的方法handle_uploaded_file(), 您不必手动执行。这个handle_uploaded_file() 方法只需收集和设置一些所需的路径和文件名。

最后一步是创建附件。create_atatchment() 将设置所有需要的数据并为您创建附件。该方法返回ID ,以便您可以使用访问所有附件数据get_post( [id] )

$imageupload = new File_Upload();
$attachment_id = $imageupload->create_attachment();
[some other code]        
$attachment = get_post( $attachment_id );
$image_url  = $attachment->guid;

printf( \'<p><img src="%s"></p>\', $image_url );

Some words about error handling

我在生产环境的类代码中编写了一些提示。A我上面提到过,文件上传是一个非常敏感的话题。你必须检查、验证和清理一切。WordPress具有内置错误处理WP_Error(). 使用它!并检查上载是否成功is_wp_error().

PHP可以设置一些错误消息,说明上传失败的原因。但是PHP不会返回清晰的文本消息,它会返回错误代码。将这些代码转换为明文的方法如下所示:

受保护的函数guess\\u upload\\u错误($err=0){

$errcodes = array(
    \'Unknown error\',
    \'The uploaded file exceeds the upload_max_filesize directive in php.ini.\',
    \'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.\',
    \'The uploaded file was only partially uploaded.\',
    \'No file was uploaded.\',
    \'Missing a temporary folder.\',
    \'Failed to write file to disk.\',
    \'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.\'
);

return ( isset( $errcodes[$err] ) ) ?
    $errcodes[$err] : \'Unknown error\';
}

您必须检查上载是否成功,这可能如下所示(在方法中handle_upload_file())

// stop if something went wrong
if ( empty( $tmp_file ) ) {

    $code = ( isset( $this->files[$this->index_key][\'error\'] ) ) ?
        $this->files[$this->index_key][\'error\'] : 0;

    $msg = $this->guess_upload_error( $code );

    return new WP_Error( \'uploaderror\', \'Upload failed with message: \' . $msg );
}
然后在调用类时必须处理错误

if ( empty( $_FILES ) ) {

global $pagenow;
$url = admin_url( $pagenow );
?>
<!-- HTML form-->
<?php
} else {
    $imageupload = new File_Upload();
    $attachment_id = $imageupload->create_attachment();

    if ( is_wp_error( $attachment_id ) ) {

        echo \'<ol>\';
        foreach ( $attachment_id->get_error_messages() as $err )
            printf( \'<li>%s</li>\', $err );
        echo \'</ol>\';

    } else {

        // do something with the created attachment
        $attachment = get_post( $attachment_id );
        $image_url  = $attachment->guid;

        printf( \'<p><img src="%s"></p>\', $image_url );

    }
}
Always remember: 永远不要让失败的上传不被处理!

SO网友:Asha

add Code in function file

add_action(\'wp_ajax_custom_action\', \'custom_action\');
add_action(\'wp_ajax_nopriv_custom_action\', \'custom_action\');
function custom_action() {

$post_id =12;
    //print_r($_FILES); exit;
    global $wpdb;
    //$response = array();

    if( $_FILES[\'uploadedfiles\']) {

    $file = $_FILES[\'uploadedfiles\'];
    require_once( ABSPATH . \'wp-admin/includes/admin.php\' );
    $file_return = wp_handle_upload( $file, array(\'test_form\' => false ) );
    if( isset( $file_return[\'error\'] ) || isset( $file_return[\'upload_error_handler\'] ) ) {
        return false;
    } else {
        $filename = $file_return[\'file\'];
        $attachment = array(
            \'post_mime_type\' => $file_return[\'type\'],
            \'post_title\' => preg_replace( \'/\\.[^.]+$/\', \'\', basename( $filename ) ),
            \'post_content\' => \'\',
            \'post_status\' => \'inherit\',
            \'guid\' => $file_return[\'url\']
        );
        $attachment_id = wp_insert_attachment( $attachment, $file_return[\'url\'] );
        require_once(ABSPATH . \'wp-admin/includes/image.php\');
        $attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
        wp_update_attachment_metadata( $attachment_id, $attachment_data );

        update_post_meta($post_id, \'_thumbnail_id\', $attachment_id);
        if( 0 < intval( $attachment_id ) ) {
          return $attachment_id;
        }
    }
    return false;

    }

    //$response[\'message\'] = \'Image Uploaded!!!\';
    //echo json_encode($response);
    wp_die();


}
结束

相关推荐

Resize uploaded images

Possible Duplicate:Resizing all images 我有一个我建立的新闻门户,客户想要不同大小的特色图片。我已经准备好了我想要的第一个尺寸,他们已经发布了大约200多篇帖子,都准备好了这个尺寸。现在,如果我改变大小,它只会在新帖子上改变/或重新上传当前的特色图片(手工操作太多了)。我的问题是,有没有办法调整上传图像的大小?