乌徒帮技术范儿WordPressWordPress内核 › wordpress文件上传与文章附件的函数探讨

wordpress文件上传与文章附件的函数探讨

分类:WordPress内核

如果你愿意自己开发一个带有附件上传功能的wordpress文章插件,那么你一定要认真阅读这篇文章,它将告诉你关于wordpress中文件上传和文章附件时要用到的几个函数,以及它们到底如何开始工作的。那么废话就不多说了,我们直接通过一个完整的代码案例来讲解这一wordpress内部机制的实现。

一、创建一个file上传文件框

<form action="你要进行数据处理的php文件.php" method="post" enctype="multipart/form-data">
?? ?<input name="upload" type="file" id="upload-image" />
?? ?<button type="submit">上传</button>
?? ?<?php wp_nonce_field(); ?>
</form>

这是一个可以上传文件的form,我们首先应该有一个form来进行文件的上传。

二、进行文件上传的处理

创建一个php文件,即上面的form的目标文件。通过enctype="multipart/form-data"的file input发送过来的文件数据,我们要进行处理。

require_once(ABSPATH.'/wp-load.php');
require_once(ABSPATH.'/wp-admin/includes/file.php');
check_admin_referer();

if($_FILES['upload']['error'] == 0) :
?? ?$filename = $_FILES['upload']['name'];//只能用它作为文章和图片的标题post_title
?? ?$_FILES['upload']['name'] = iconv('UTF-8','GBK',$_FILES['upload']['name']);//把上传上来的图片名称转码为GBK,因为wp_handle_upload上传时不支持中文名称的图片
?? ?$uploaded_file = wp_handle_upload($_FILES['upload'],array('test_form' => false));
?? ?$file = $uploaded_file['file'];
?? ?$new_file = iconv('GBK','UTF-8',$file);//把wp_handle_upload返回的file转码为UTF-8,这样才能使用,并写入数据库,但是下面的wp_generate_attachment_metadata却还要用到$file
?? ?$url = iconv('GBK','UTF-8',$uploaded_file['url']);//把wp_handle_upload返回的url转码为UTF-8,这样才能在本页中使用,并写入数据库
?? ?$type = $uploaded_file['type'];
?? ?
?? ?if(isset($uploaded_file['error']))wp_die($uploaded_file['error']);
?? ?
?? ?$post_id = wp_insert_post(array('post_title' => preg_replace('/\.[^.]+$/','',$filename),'post_type' => 'post','post_status' => 'auto-draft'));
?? ?$post = get_post($post_id);
?? ?set_post_format($post,'image');

?? ?$attachment = array(
?? ??? ?'guid' => $url, 
?? ??? ?'post_mime_type' => $type,
?? ??? ?'post_title' => $filename,
?? ??? ?'post_content' => '',
?? ??? ?'post_status' => 'inherit'
?? ?);
?? ?$attach_id = wp_insert_attachment($attachment,$new_file,$post_id);
?? ?require_once(ABSPATH.'wp-admin/includes/image.php');//用以对图片进行裁剪
?? ?$attach_data = wp_generate_attachment_metadata($attach_id,$file);//之所以是用$file是因为该函数内部也不支持中文
?? ?$attach_data['file'] = iconv('GBK','UTF-8',$attach_data['file']);//这里和下面的foreach操作都是为了把wp_generate_attachment_metadata处理后的中文转码为UTF-8,这样才能写入数据库,需要提醒的是,只有UTF-8格式的字符串才能被wordpress识别
?? ?foreach($attach_data['sizes'] as $key => $sizes){
?? ??? ?$sizes['file'] = iconv('GBK','UTF-8',$sizes['file']);
?? ??? ?$attach_data['sizes'][$key]['file'] = $sizes['file'];
?? ?}
?? ?wp_update_attachment_metadata($attach_id,$attach_data);

?? ?set_post_thumbnail($post,$attach_id);
endif;

根据这一思路写的一个独立页面模板作为测试,下载上传到你的wordpress目录,新建一个页面,新建时选择投稿作为模板。

上面的整段代码实现的是对文件上传后的一系列处理:

1、首先引用wp-load.php和/wp-admin/includes/file.php,让这个文件能够使用wordpress的内部配置和函数。

2、check_admin_referer();对提交的wp_nonce_field();进行验证,防止从外部域名提交文件。

3、if($_FILES['upload']['error'] == 0) :对上传是否存在错误进行判断,$_FILES['upload']['error']的值有4个,你可以通过搜索引擎了解它们分别代表什么意思。

4、利用wp_handle_upload函数,上传文件到wordpress默认的文件目录下,该函数是wordpress内部的文件上传处理函数,你可以通过开发文档了解该函数的具体参数的用法。如果无需有特殊要求,用本代码提供的参数即可。wp_handle_upload的返回值有三个,分别是上传之后的文件的FILE所在绝对地址,type文件类型,以及URL文件的访问地址。

5、if(isset($uploaded_file['error']))wp_die($uploaded_file['error']);判断文件上传和处理是否成功。不成功时wp_die假死。

6、接下来是文章附件的处理。首先要创建一个文章,我们的目的是得到该文章的ID值。

$post_id = wp_insert_post(array('post_title' => preg_replace('/\.[^.]+$/','',$filename),'post_type' => 'post','post_status' => 'auto-draft'));

7、将wp_handle_upload上传处理之后的文件作为该文章的附件

$attachment = array(
?? ?'guid' => $url, 
?? ?'post_mime_type' => $type,
?? ?'post_title' => $filename,
?? ?'post_content' => '',
?? ?'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment,$new_file,$post_id);

8、这并不完美,我们用下面的代码对图片进行裁剪。更新图片的信息

require_once(ABSPATH.'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attach_id,$file);//之所以是用$file是因为该函数内部也不支持中文
wp_update_attachment_metadata($attach_id,$attach_data);

9、set_post_thumbnail($post,$attach_id);把该图片作为文章的特色图片。

三、字符集处理

你会发现在代码中增加了很多注释的部分,解释说使用$new_file和$file的问题,这些都是为了解决字符集问题。在wordpress中,如果你上传的图片是中文名的图片,例如“乌徒帮.jpg”,那么就会出现上传之后存放的文件名是乱码,而数据库中是正常的中文名的情况。网络上有很多解决windows主机空间不支持中文名图片上传的问题的方法,其实都不完全可靠,问题有时还会复发,而且都是采用修改系统文件的方法。我在这段代码中详细的给出了整个字符集处理的解决方案。

在wordpress处理图片上传的过程中,如果你的主机不支持wordpress默认的UTF-8的图片上传,那么就会出现上传的图片名称变为乱码,获取不到图片的URL地址。在这里,我们对上述的上传步骤再做一个引申:上传中,有些涉及数据库数据更新,有的只涉及文件处理。无论是文件处理还是数据库数据的变化,都有可能由于你传递的参数不对导致乱码,不是文件本身乱码就是数据库中的乱码。

wp_handle_upload和wp_generate_attachment_metadata是文件处理的函数,它们将负责对文件进行上传后另存为到附件目录下、对上传的图片按照规定的尺寸进行裁剪创建多个图片副本的操作。

wp_insert_post、wp_insert_attachment和wp_update_attachment_metadata是数据处理函数,它们并不操作文件,而是将处理后返回的数据写入到数据库中。

那么这个过程里,我们就必须了解到:对文件进行处理时,我们要使用iconv('UTF-8','GBK',$_FILES['upload']['name']);处理后的参数,即文件名是GBK格式(正常的中文),而进行数据处理时,又要使用原本的,或者通过iconv('GBK','UTF-8',$file);转换回来的UTF-8格式的数据,wordpress数据库不认识GBK的数据。这样一来,你就能慢慢理解,为何我上文要大费周章的进行数据格式的转换了。

已有3条评论 快速评论
  1. 陈东海 #4369楼 2014/09/16 18:20:22 回复

    楼层错误的妈妈都不认识了

  2. 否子戈 #1929楼 回复给@1920楼 2012/09/14 20:00:39 回复

    你好,你所说的“和ludou的投稿怎样结合”是什么意思,不是很理解?本文提供了较为基本的文件上传思路,遇到具体的问题的时候还需要结合实际情况进行修改。

    上传一张图片作为文章的特色图片:
    1、首先从上面的代码中剖析出上传文件的部分,先上传图片到服务器;
    2、其次利用这篇文章的ID,根据这个ID使用wp_insert_attachment和wp_update_attachment_metadata将这张上传的图片的信息插入数据库,成为文章的附件;
    3、set_post_thumbnail($post,$attach_id);来实现把对应的附件作为文章的特色图片。

  3. cxxc #1920楼 2012/09/14 16:16:54 回复

    请问这个和ludou的投稿怎样结合?我需要上传一张图片作为文章特色图片,另外,还需要上传ppt/doc/pdf文档作为文章附件……

填写个人信息,赶快回复吧!