问题
WordPress 2.5 引入了copy_dir()用于将目录从一个位置复制到另一个位置。此函数递归地创建必要的子目录并将文件复制到新文件夹中它们各自的位置。
但是,以前没有移动适用于所有文件系统的目录的功能。这意味着Core和扩展程序必须使用copy_dir(),然后删除原始版本。
移动目录不应需要太多内存、磁盘空间、时间或文件操作。它应该快速、易于调用且可靠。
解决方案
WordPress 6.2 ( #57375 ) 引入了该move_dir()
函数,它具有以下参数:
- from (string) – 目录的当前位置。
- to (string) – 目录的新位置。
- overwrite (bool) – 是否覆盖目的地。默认为假。
该函数将在成功时返回true
,或在失败时返回WP_Error对象。
失败包括:
$from
并且$to
是一样的。$overwrite
是false
并且目的地存在。$overwrite
是true
,并且无法删除现有目的地。- 如果回退到copy_dir()并且无法创建目标。
你如何使用它?
如果您打算使用move_dir()
, 并且目的地尚未被删除,则必须使用$overwrite
as调用它true
。
$result = move_dir( $from, $to, $overwrite );
if ( is_wp_error( $result ) ) {
return $result;
}
你什么时候可以开始使用它?
您可以立即开始替换copy_dir()的任意组合,并move_dir()
期待 WordPress 6.2 的发布。
一如既往,请执行充分的测试以确保您的代码在将其发布给生产/用户之前继续按预期工作。这包括在所有 WordPress 6.2 候选版本中进行测试。
它在 Core 中的什么地方使用?
move_dir()
现在已在#57557中的WP_Upgrader::install_package()方法中实现。这会影响所有升级路径,减少磁盘空间和内存使用,并提高速度以减少更新插件、主题和语言包时资源较少的系统的超时。
如果扩展器设置clear_working
为false
,或者目标存在并且有内容,则升级将改用copy_dir()。
这不是在核心更新中使用copy_dir()的替代品,因为有几个区域在这个过程中没有复制特定的子目录。
在引擎盖下
move_dir()
使用WP_Filesystem_Direct、WP_Filesystem_FTPext、WP_Filesystem_ftpsockets和WP_Filesystem_SSH2文件系统抽象::move()
的方法。
这不仅比copy_dir()和 delete 的组合更直观地移动目录,而且速度也快得多,并且在服务器上使用更少的磁盘空间和内存。
使用新引入的功能,OPcache 对所有移动的文件都无效wp_opcache_invalidate_directory()
。在 WordPress 6.2 的杂项开发说明中找到有关此功能的更多信息。
如果移动操作失败,move_dir()
则回退到copy_dir()。如果copy_dir()成功,则删除源目录。
虚拟盒子
在处理此功能时,Core 开发人员在 VirtualBox 中遇到了一个众所周知的问题,即文件存在和元数据在移动后可能不会更新。
当通过PHP和函数组合使用移动 A 到 C、移动 B 到 A、删除 C时,这会产生高度破坏性的结果。rename()
unlink()
move_dir()
利用调用的WP_Filesystem_*::dirlist()方法中对filesize()和filemtime()的调用来解决延迟的元数据更新。文件存在警告在移动目录后延迟 200 毫秒得到解决,这使文件系统的缓存有时间更新。wp_opcache_invalidate_directory()
这个错误是 VirtualBox 独有的。VirtualBox 6 和 7 中的广泛测试表明move_dir()
不会遇到此错误,并且可以安全使用。