函数文档

_wp_upload_dir()

💡 云策文档标注

概述

_wp_upload_dir() 是 wp_upload_dir() 的一个非过滤、非缓存版本,不检查路径,直接返回上传目录的路径和URL数组。它处理单站点和多站点环境下的上传目录配置,包括时间子目录生成。

关键要点

  • 函数是 wp_upload_dir() 的基础版本,无过滤器和缓存,适用于需要原始上传目录数据的场景
  • 参数 $time 可选,用于指定时间格式 'yyyy/mm',默认 null 时使用当前时间生成年月子目录
  • 返回数组包含 path、url、subdir、basedir、baseurl 和 error 字段,结构与 wp_upload_dir() 一致
  • 处理上传路径逻辑:优先使用 upload_path 选项,否则默认 wp-content/uploads,并考虑 UPLOADS 常量
  • 多站点支持:根据 ms_files_rewriting 等选项调整目录结构,如添加 /sites/{blog_id} 子目录
  • 如果启用 uploads_use_yearmonth_folders 选项,自动生成基于时间的子目录(如 /2023/10)

代码示例

function _wp_upload_dir( $time = null ) {
    // 函数实现代码,包括路径处理、多站点逻辑和时间子目录生成
    // 返回数组示例:['path' => '/var/www/wp-content/uploads/2023/10', 'url' => 'http://example.com/wp-content/uploads/2023/10', ...]
}

注意事项

  • 此函数不应用过滤器,不缓存结果,适合在需要避免 wp_upload_dir() 过滤影响时使用
  • 在多站点环境中,行为受 ms_files_rewriting、UPLOADS 等设置影响,需注意兼容性
  • 函数自 WordPress 4.5.0 引入,是核心内部函数,通常由 wp_upload_dir() 调用

📄 原文内容

A non-filtered, non-cached version of wp_upload_dir() that doesn’t check the path.

Parameters

$timestring|nulloptional
Time formatted in 'yyyy/mm'.

Default:null

Return

array See wp_upload_dir()

Source

function _wp_upload_dir( $time = null ) {
	$siteurl     = get_option( 'siteurl' );
	$upload_path = trim( get_option( 'upload_path' ) );

	if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) {
		$dir = WP_CONTENT_DIR . '/uploads';
	} elseif ( ! str_starts_with( $upload_path, ABSPATH ) ) {
		// $dir is absolute, $upload_path is (maybe) relative to ABSPATH.
		$dir = path_join( ABSPATH, $upload_path );
	} else {
		$dir = $upload_path;
	}

	$url = get_option( 'upload_url_path' );
	if ( ! $url ) {
		if ( empty( $upload_path ) || ( 'wp-content/uploads' === $upload_path ) || ( $upload_path === $dir ) ) {
			$url = WP_CONTENT_URL . '/uploads';
		} else {
			$url = trailingslashit( $siteurl ) . $upload_path;
		}
	}

	/*
	 * Honor the value of UPLOADS. This happens as long as ms-files rewriting is disabled.
	 * We also sometimes obey UPLOADS when rewriting is enabled -- see the next block.
	 */
	if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
		$dir = ABSPATH . UPLOADS;
		$url = trailingslashit( $siteurl ) . UPLOADS;
	}

	// If multisite (and if not the main site in a post-MU network).
	if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {

		if ( ! get_site_option( 'ms_files_rewriting' ) ) {
			/*
			 * If ms-files rewriting is disabled (networks created post-3.5), it is fairly
			 * straightforward: Append sites/%d if we're not on the main site (for post-MU
			 * networks). (The extra directory prevents a four-digit ID from conflicting with
			 * a year-based directory for the main site. But if a MU-era network has disabled
			 * ms-files rewriting manually, they don't need the extra directory, as they never
			 * had wp-content/uploads for the main site.)
			 */

			if ( defined( 'MULTISITE' ) ) {
				$ms_dir = '/sites/' . get_current_blog_id();
			} else {
				$ms_dir = '/' . get_current_blog_id();
			}

			$dir .= $ms_dir;
			$url .= $ms_dir;

		} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
			/*
			 * Handle the old-form ms-files.php rewriting if the network still has that enabled.
			 * When ms-files rewriting is enabled, then we only listen to UPLOADS when:
			 * 1) We are not on the main site in a post-MU network, as wp-content/uploads is used
			 *    there, and
			 * 2) We are not switched, as ms_upload_constants() hardcodes these constants to reflect
			 *    the original blog ID.
			 *
			 * Rather than UPLOADS, we actually use BLOGUPLOADDIR if it is set, as it is absolute.
			 * (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as
			 * as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files
			 * rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
			 */

			if ( defined( 'BLOGUPLOADDIR' ) ) {
				$dir = untrailingslashit( BLOGUPLOADDIR );
			} else {
				$dir = ABSPATH . UPLOADS;
			}
			$url = trailingslashit( $siteurl ) . 'files';
		}
	}

	$basedir = $dir;
	$baseurl = $url;

	$subdir = '';
	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
		// Generate the yearly and monthly directories.
		if ( ! $time ) {
			$time = current_time( 'mysql' );
		}
		$y      = substr( $time, 0, 4 );
		$m      = substr( $time, 5, 2 );
		$subdir = "/$y/$m";
	}

	$dir .= $subdir;
	$url .= $subdir;

	return array(
		'path'    => $dir,
		'url'     => $url,
		'subdir'  => $subdir,
		'basedir' => $basedir,
		'baseurl' => $baseurl,
		'error'   => false,
	);
}

Changelog

Version Description
4.5.0 Introduced.