wp_upload_dir()
概述
wp_upload_dir() 函数用于获取当前上传目录的路径和 URL 信息,返回一个包含详细数据的数组。它支持通过选项、常量或时间参数自定义路径,并自动处理目录创建和错误检查。
关键要点
- 返回数组包含 path、url、subdir、basedir、baseurl 和 error 等键,分别表示上传目录的完整路径、URL、子目录、基础路径、基础 URL 和错误信息。
- 路径优先级:UPLOADS 常量 > upload_path 选项 > 默认 WP_CONTENT_DIR/uploads;URL 由 upload_url_path 选项或 WP_CONTENT_URL 常量决定。
- 如果 uploads_use_yearmonth_folders 设置为 true,会自动使用年/月格式的子目录。
- 函数可接受 $time、$create_dir 和 $refresh_cache 参数,控制时间格式、目录创建和缓存刷新。
- 使用 upload_dir 过滤器可以自定义返回的数组数据。
- 在创建目录失败时,会返回错误信息,提示服务器权限问题。
代码示例
$upload_dir = wp_upload_dir();
echo $upload_dir['path']; // 输出上传目录的完整路径
echo $upload_dir['url']; // 输出上传目录的完整 URL注意事项
- upload_path 选项自 WordPress 3.5 起已移除,仅用于向后兼容。
- 在多站点环境中,路径会附加站点 ID(如 /sites/2)。
- 函数可能返回 HTTP URL,在 SSL 网站上需手动处理 HTTPS,或使用过滤器调整。
- 调用函数时,如果 $create_dir 为 true 且目录不存在,会自动创建对应年/月子文件夹。
Returns an array containing the current upload directory’s path and URL.
Description
Checks the ‘upload_path’ option, which should be from the web root folder, and if it isn’t empty it will be used. If it is empty, then the path will be ‘WP_CONTENT_DIR/uploads’. If the ‘UPLOADS’ constant is defined, then it will override the ‘upload_path’ option and ‘WP_CONTENT_DIR/uploads’ path.
The upload URL path is set either by the ‘upload_url_path’ option or by using the ‘WP_CONTENT_URL’ constant and appending ‘/uploads’ to the path.
If the ‘uploads_use_yearmonth_folders’ is set to true (checkbox if checked in the administration settings panel), then the time will be used. The format will be year first and then month.
If the path couldn’t be created, then an error will be returned with the key ‘error’ containing the error message. The error suggests that the parent directory is not writable by the server.
Parameters
$timestring|nulloptional-
Time formatted in
'yyyy/mm'.Default:
null $create_dirbooloptional-
Whether to check and create the uploads directory.
Default true for backward compatibility.Default:
true $refresh_cachebooloptional-
Whether to refresh the cache.
Default:
false
Source
function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) {
static $cache = array(), $tested_paths = array();
$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time );
if ( $refresh_cache || empty( $cache[ $key ] ) ) {
$cache[ $key ] = _wp_upload_dir( $time );
}
/**
* Filters the uploads directory data.
*
* @since 2.0.0
*
* @param array $uploads {
* Array of information about the upload directory.
*
* @type string $path Base directory and subdirectory or full path to upload directory.
* @type string $url Base URL and subdirectory or absolute URL to upload directory.
* @type string $subdir Subdirectory if uploads use year/month folders option is on.
* @type string $basedir Path without subdir.
* @type string $baseurl URL path without subdir.
* @type string|false $error False or error message.
* }
*/
$uploads = apply_filters( 'upload_dir', $cache[ $key ] );
if ( $create_dir ) {
$path = $uploads['path'];
if ( array_key_exists( $path, $tested_paths ) ) {
$uploads['error'] = $tested_paths[ $path ];
} else {
if ( ! wp_mkdir_p( $path ) ) {
if ( str_starts_with( $uploads['basedir'], ABSPATH ) ) {
$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
} else {
$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
}
$uploads['error'] = sprintf(
/* translators: %s: Directory path. */
__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
esc_html( $error_path )
);
}
$tested_paths[ $path ] = $uploads['error'];
}
}
return $uploads;
}
Hooks
- apply_filters( ‘upload_dir’, array $uploads )
-
Filters the uploads directory data.
Changelog
| Version | Description |
|---|---|
| 2.0.0 | Introduced. |
Skip to note 9 content
Codex
More in-depth break down of the data returned.
value pairs /* $upload_dir now contains something like the following (if successful) Array ( [path] => C:pathtowordpresswp-contentuploads20105 [url] => <a href="http://example.com/wp-content/uploads/2010/05" rel="nofollow ugc">http://example.com/wp-content/uploads/2010/05</a> [subdir] => /2010/05 [basedir] => C:pathtowordpresswp-contentuploads [baseurl] => <a href="http://example.com/wp-content/uploads" rel="nofollow ugc">http://example.com/wp-content/uploads</a> [error] => ) // Descriptions [path] - base directory and sub directory or full path to upload directory. [url] - base url and sub directory or absolute URL to upload directory. [subdir] - sub directory if uploads use year/month folders option is on. [basedir] - path without subdir. [baseurl] - URL path without subdir. [error] - set to false. */ echo $upload_dir['path'] . '<br />'; echo $upload_dir['url'] . '<br />'; echo $upload_dir['subdir'] . '<br />'; echo $upload_dir['basedir'] . '<br />'; echo $upload_dir['baseurl'] . '<br />'; echo $upload_dir['error'] . '<br />'; $upload_url = ( $upload_dir['url'] ); $upload_url_alt = ( $upload_dir['baseurl'] . $upload_dir['subdir'] ); // Now echo the final result echo $upload_url . '<br />'; // Output - <a href="http://example.com/wp-content/uploads/2010/05" rel="nofollow ugc">http://example.com/wp-content/uploads/2010/05</a> // Using year and month based folders, the below will be the same as the line above. echo $upload_url_alt . '<br />'; // Output - <a href="http://example.com/wp-content/uploads/2010/05" rel="nofollow ugc">http://example.com/wp-content/uploads/2010/05</a> ?>Skip to note 10 content
screets
Strangely wp_upload_dir doesn’t return https for SSL websites. Hopefully they fix the issue soon. Here is the code below where you can get the upload dir and url in right way:
/** * Get the upload URL/path in right way (works with SSL). * * @param $param string "basedir" or "baseurl" * @return string */ function fn_get_upload_dir_var( $param, $subfolder = '' ) { $upload_dir = wp_upload_dir(); $url = $upload_dir[ $param ]; if ( $param === 'baseurl' && is_ssl() ) { $url = str_replace( 'http://', 'https://', $url ); } return $url . $subfolder; }Example:
// Get wp-content/uploads/myfolder by URL fn_get_upload_dir_var( 'baseurl', 'myfolder' ); // Now get full path of the same folder fn_get_upload_dir_var( 'basedir', 'myfolder' );Skip to note 11 content
Ewout
Note that the ‘upload_path’ option that is mentioned has been removed since WP3.5, so this check is only still there for backwards compatibility.
Skip to note 12 content
abellowins
I needed to NOT rely on Gravatar at all, and just use the buddypress profile avatar. Here is the result.
$avatar_url = bp_core_fetch_avatar(array('item_id'=>$user->ID,'html'=>false)); if (strpos($avatar_url, 'www.gravatar.com/avatar') !== false) { $upload_dir = wp_upload_dir(); $avatar_url = $upload_dir['baseurl'] . '/avatars/pi-gravatar.jpg'; }Skip to note 13 content
Codex
Basic example to produce the upload directory URL.
Skip to note 14 content
Dear
If you want to create a directory in wp-contents/uploads folder at the time of WordPress PlugIn activation, here is the code:
function yourprojectname_activate() { $upload = wp_upload_dir(); $upload_dir = $upload['basedir']; $upload_dir = $upload_dir . '/your-project-name'; if (! is_dir($upload_dir)) { mkdir( $upload_dir, 0700 ); } }Skip to note 15 content
markp
In case this helps anyone, on a multisite instance, the site and site number are appended to the end of the paths.
$upload_dir = wp_upload_dir(); // Single Site $upload_dir['baseurl']; // http://example.com/wp-content/uploads // Multisite $upload_dir['baseurl']; // http://example.com/wp-content/uploads/sites/site_no // Where site_no = Site IDIt’s important to note that the [‘subdir’] key still returns the year/month structure, but all other related paths add the above directories in a Multisite environment.
Skip to note 16 content
Watch Teller
In case helps anyone want to make define constants, moving and rename the multisite UPLOADS file.
//If planned rename UPLOADS file from wp-content/uploads to wp-content/pics //If NOT PLANNED force all uploads shared in one folder //Add define constants define ('UPLOADS', WP_CONTENT_DIR . '/' . 'pics'); in .htaccess //Sub-directories (like year/month) will still exist (if the network setting is enabled) //Register a filter for "upload_dir" add_filter( 'upload_dir', 'ms_upload_dir' ); function ms_upload_dir( $dirs ) { $dirs['baseurl'] = network_site_url( '/wp-content/pics') . '/sites/'.get_current_blog_id(); $dirs['basedir'] = ABSPATH . 'wp-content/pics' . '/sites/'.get_current_blog_id(); $dirs['path'] = $dirs['basedir'] . $dirs['subdir']; $dirs['url'] = $dirs['baseurl'] . $dirs['subdir']; return $dirs; } //If planned rename UPLOADS file from wp-content/uploads to wp-content/pics //If PLANNED force all uploads shared in one folder //Add define constants define ('UPLOADS', WP_CONTENT_DIR . '/' . 'pics'); in .htaccess //Sub-directories (like year/month) will still exist (if the network setting is enabled) //Register a filter for "upload_dir" add_filter( 'upload_dir', 'ms_upload_dir' ); function ms_upload_dir( $dirs ) { $dirs['baseurl'] = network_site_url( '/wp-content/pics'); $dirs['basedir'] = ABSPATH . 'wp-content/pics'; $dirs['path'] = $dirs['basedir'] . $dirs['subdir']; $dirs['url'] = $dirs['baseurl'] . $dirs['subdir']; return $dirs; } //If planned moving (and rename) UPLOADS file out from wp-content //If NOT PLANNED force all uploads shared in one folder //Add define constants define ('UPLOADS', 'pics'); in .htaccess //Sub-directories (like year/month) will still exist (if the network setting is enabled) //Register a filter for "upload_dir" add_filter( 'upload_dir', 'ms_upload_dir' ); function ms_upload_dir( $dirs ) { $dirs['baseurl'] = network_site_url( '/pics') . '/sites/'.get_current_blog_id(); $dirs['basedir'] = ABSPATH . 'pics' . '/sites/'.get_current_blog_id(); $dirs['path'] = $dirs['basedir'] . $dirs['subdir']; $dirs['url'] = $dirs['baseurl'] . $dirs['subdir']; return $dirs; } //If planned moving (and rename) UPLOADS file out from wp-content //If PLANNED force all uploads shared in one folder //Add define constants define ('UPLOADS', 'pics'); in .htaccess //Sub-directories (like year/month) will still exist (if the network setting is enabled) //Register a filter for "upload_dir" add_filter( 'upload_dir', 'ms_upload_dir' ); function ms_upload_dir( $dirs ) { $dirs['baseurl'] = network_site_url( '/pics'); $dirs['basedir'] = ABSPATH . 'pics'; $dirs['path'] = $dirs['basedir'] . $dirs['subdir']; $dirs['url'] = $dirs['baseurl'] . $dirs['subdir']; return $dirs; }