或者如果我需要这种能力,我需要采取其他方向吗?
#1 楼
对于想了解更多有关文件上传的人,这里有一个快速入门,涵盖了主要主题和痛点。请注意,这是在Linux机器上使用WordPress 3.0编写的,并且代码只是教授这些概念的基本概述。我确定这里的某些人可以为改进实施提供建议。概述您的基本方法
至少有三种方法将图像与帖子相关联:使用post_meta字段用于存储图像路径,可以使用post_meta字段来存储图像的媒体库ID(稍后会详细介绍),或者将图像作为附件分配给帖子。本示例将使用post_meta字段来存储图像的媒体库ID。 YMMV。
多部分编码
默认情况下,WordPress的创建和编辑表单没有enctype。如果要上传文件,则需要在表单标签中添加“ enctype ='multipart / form-data'”,否则$ _FILES集合将完全无法通过。在WordPress 3.0中,有一个挂钩。在某些以前的版本中(不确定具体内容),您必须字符串替换形式标签。
function xxxx_add_edit_form_multipart_encoding() {
echo ' enctype="multipart/form-data"';
}
add_action('post_edit_form_tag', 'xxxx_add_edit_form_multipart_encoding');
创建元框并上传字段
由于您大多数人可能已经知道如何创建元框,因此我不会做太多工作,但是我只是说您只需要一个带有文件字段的简单元框。在下面的示例中,我包含了一些代码来查找现有图像,并在存在图像时显示它。我还包括一些简单的错误/反馈功能,该功能使用post_meta字段传递错误。您将需要更改它以使用WP_Error类...仅用于演示。
function xxxx_render_image_attachment_box($post) {
// See if there's an existing image. (We're associating images with posts by saving the image's 'attachment id' as a post meta value)
// Incidentally, this is also how you'd find any uploaded files for display on the frontend.
$existing_image_id = get_post_meta($post->ID,'_xxxx_attached_image', true);
if(is_numeric($existing_image_id)) {
echo '<div>';
$arr_existing_image = wp_get_attachment_image_src($existing_image_id, 'large');
$existing_image_url = $arr_existing_image[0];
echo '<img src="' . $existing_image_url . '" />';
echo '</div>';
}
// If there is an existing image, show it
if($existing_image_id) {
echo '<div>Attached Image ID: ' . $existing_image_id . '</div>';
}
echo 'Upload an image: <input type="file" name="xxxx_image" id="xxxx_image" />';
// See if there's a status message to display (we're using this to show errors during the upload process, though we should probably be using the WP_error class)
$status_message = get_post_meta($post->ID,'_xxxx_attached_image_upload_feedback', true);
// Show an error message if there is one
if($status_message) {
echo '<div class="upload_status_message">';
echo $status_message;
echo '</div>';
}
// Put in a hidden flag. This helps differentiate between manual saves and auto-saves (in auto-saves, the file wouldn't be passed).
echo '<input type="hidden" name="xxxx_manual_save_flag" value="true" />';
}
function xxxx_setup_meta_boxes() {
// Add the box to a particular custom content type page
add_meta_box('xxxx_image_box', 'Upload Image', 'xxxx_render_image_attachment_box', 'post', 'normal', 'high');
}
add_action('admin_init','xxxx_setup_meta_boxes');
处理文件上传
此是最大的一个-实际上,通过挂入save_post操作来处理文件上传。我在下面添加了一个注释非常严重的函数,但我想指出它使用的两个主要WordPress函数:
wp_handle_upload()很好地处理了上传操作。您只需将其传递给$ _FILES数组中的字段引用和一系列选项即可(不必太担心这些,您唯一需要设置的重要选项就是test_form = false。相信我)。但是,此功能不会将上传的文件添加到媒体库。它仅执行上载操作并返回新文件的路径(也方便地返回完整的URL)。如果有问题,它将返回错误。
wp_insert_attachment()将图像添加到媒体库,并生成所有适当的缩略图。您只需向其传递一个选项数组(标题,帖子状态等)以及您刚刚上传的文件的本地路径(而非URL)。将图像放入媒体库的妙处在于,您可以稍后通过调用wp_delete_attachment并将其传递给该项目的媒体库ID(在下面的函数中执行此操作)来轻松删除所有文件。使用此功能,您还需要使用wp_generate_attachment_metadata()和wp_update_attachment_metadata(),它们确实可以实现您期望的功能-生成媒体项的元数据。
function xxxx_update_post($post_id, $post) {
// Get the post type. Since this function will run for ALL post saves (no matter what post type), we need to know this.
// It's also important to note that the save_post action can runs multiple times on every post save, so you need to check and make sure the
// post type in the passed object isn't "revision"
$post_type = $post->post_type;
// Make sure our flag is in there, otherwise it's an autosave and we should bail.
if($post_id && isset($_POST['xxxx_manual_save_flag'])) {
// Logic to handle specific post types
switch($post_type) {
// If this is a post. You can change this case to reflect your custom post slug
case 'post':
// HANDLE THE FILE UPLOAD
// If the upload field has a file in it
if(isset($_FILES['xxxx_image']) && ($_FILES['xxxx_image']['size'] > 0)) {
// Get the type of the uploaded file. This is returned as "type/extension"
$arr_file_type = wp_check_filetype(basename($_FILES['xxxx_image']['name']));
$uploaded_file_type = $arr_file_type['type'];
// Set an array containing a list of acceptable formats
$allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png');
// If the uploaded file is the right format
if(in_array($uploaded_file_type, $allowed_file_types)) {
// Options array for the wp_handle_upload function. 'test_upload' => false
$upload_overrides = array( 'test_form' => false );
// Handle the upload using WP's wp_handle_upload function. Takes the posted file and an options array
$uploaded_file = wp_handle_upload($_FILES['xxxx_image'], $upload_overrides);
// If the wp_handle_upload call returned a local path for the image
if(isset($uploaded_file['file'])) {
// The wp_insert_attachment function needs the literal system path, which was passed back from wp_handle_upload
$file_name_and_location = $uploaded_file['file'];
// Generate a title for the image that'll be used in the media library
$file_title_for_media_library = 'your title here';
// Set up options array to add this file as an attachment
$attachment = array(
'post_mime_type' => $uploaded_file_type,
'post_title' => 'Uploaded image ' . addslashes($file_title_for_media_library),
'post_content' => '',
'post_status' => 'inherit'
);
// Run the wp_insert_attachment function. This adds the file to the media library and generates the thumbnails. If you wanted to attch this image to a post, you could pass the post id as a third param and it'd magically happen.
$attach_id = wp_insert_attachment( $attachment, $file_name_and_location );
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
$attach_data = wp_generate_attachment_metadata( $attach_id, $file_name_and_location );
wp_update_attachment_metadata($attach_id, $attach_data);
// Before we update the post meta, trash any previously uploaded image for this post.
// You might not want this behavior, depending on how you're using the uploaded images.
$existing_uploaded_image = (int) get_post_meta($post_id,'_xxxx_attached_image', true);
if(is_numeric($existing_uploaded_image)) {
wp_delete_attachment($existing_uploaded_image);
}
// Now, update the post meta to associate the new image with the post
update_post_meta($post_id,'_xxxx_attached_image',$attach_id);
// Set the feedback flag to false, since the upload was successful
$upload_feedback = false;
} else { // wp_handle_upload returned some kind of error. the return does contain error details, so you can use it here if you want.
$upload_feedback = 'There was a problem with your upload.';
update_post_meta($post_id,'_xxxx_attached_image',$attach_id);
}
} else { // wrong file type
$upload_feedback = 'Please upload only image files (jpg, gif or png).';
update_post_meta($post_id,'_xxxx_attached_image',$attach_id);
}
} else { // No file was passed
$upload_feedback = false;
}
// Update the post meta with any feedback
update_post_meta($post_id,'_xxxx_attached_image_upload_feedback',$upload_feedback);
break;
default:
} // End switch
return;
} // End if manual save flag
return;
}
add_action('save_post','xxxx_update_post',1,2);
权限,所有权和安全性
如果上传时遇到问题,则可能与权限有关。我不是服务器配置方面的专家,所以如果这部分不正确,请更正我。
首先,确保您的wp-content / uploads文件夹存在,并且由apache:apache拥有。如果是这样,您应该能够将权限设置为744,一切都应该可以正常工作。所有权很重要-如果目录未被正确拥有,即使将perms设置为777有时也无济于事。
您还应该考虑限制使用htaccess文件上传和执行的文件的类型。这样可以防止人们上载不是图像的文件,也无法执行伪装成图像的脚本。您应该在Google上搜索更多权威信息,但是您可以像这样进行简单的文件类型限制:
<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
order deny,allow
deny from all
</Files>
评论
非常感谢MathSmath!正是我所需要的。希望我能给这个答案更多赞誉!
– Michal Mau
2011年1月25日下午4:21
极好的解释!非常感谢您扩展的唯一内容是如何使公众无法访问特定的上载文件。换句话说,如果您要创建特定的帖子类型,则只有具有特定功能的用户才能访问所有上传的文件。您能详细说明一下吗?
– NetConstructor.com
2011-1-25在11:25
对于任何想要在前端上载文件的人,您都需要包括以下代码,以便可以访问wp_handle_upload()函数:if(!function_exists('wp_handle_upload'))require_once(ABSPATH。'wp-admin / include / file.php');
–尼克·布登(Nick Budden)
2011年11月10日17:27
@ NetConstructor.com我建议您创建一个问题,因为该问题不在此答案的范围之内。
–hitautodestruct
13年3月7日在12:51
#2 楼
@MathSmath提供的代码是正确的。但是,如果要处理许多上传字段,或者要上传多个文件,则必须对其进行大量修改。此外,它不利用WordPress媒体库来上传文件(这可以完成所有操作)
我建议您看一下类似Meta Box的插件。该插件支持两种上传文件的方式:
通过HTML5
input[type="file"]
,它使用上面的类似代码(请参阅文档)和通过WordPress媒体库(请参阅文档)。
它可以帮助您减少编写和维护代码的工作量,尤其是当您要创建多个上载时。
免责声明:我是Meta Box的作者。
评论
检查tdo-forms插件,也许这是简单的解决方案这个问题可能与以下问题有关:wordpress.stackexchange.com/questions/4291/…