设置API GET_OPTION最佳实践

时间:2020-04-15 作者:Arg Geo

我的自定义主题中有很多选项,其中大多数选项如下:get_option(\'my_option\')[\'depth\'][\'more_depth\'] 因为它们是数组。为了以“更简洁”的方式编写代码,我创建了一个函数:

function my_options($key){
   $options = array(
      \'depth_more_depth\' => get_option(\'my_option\')[\'depth\'][\'more_depth\']
         .
         .
         .
   );
   return $options[$key];
}
我把这个选项称为:my_options(\'depth_more_key\'); 这是否可以接受?我的意思是,使用的函数越多,代码编译越慢,尤其是在我的情况下my_options() 函数经常被调用。是否有一种更好、更有效的方法(被视为“最佳实践”)来实现这一点?

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

是否有一种更好、更有效的方法(被视为“最佳实践”)来实现这一点?

Yes! 在单个选项中存储结构化数据是一种糟糕的做法。您应该使用选项名称来分隔数据。

否则,通过使用数组和对象,WordPress无法将其存储在数据库中,因此必须将其转换为字符串,这意味着:

聪明的用户可以插入序列化的数据,当在下一页加载时检索到该选项时,这些数据就会变成真正的数组和对象。这被称为对象反序列化攻击,人们早就知道,调试工具会显示序列化的PHP而不是干净的值,修改这些值的SQL查询会破坏这些值,PHP序列化数据包含字符串长度。因此,简单的站点迁移可能会破坏站点options.php UI或网络管理UI来更新选项值。通过将所有选项合并为一个选项,您可能会遇到选项大小的上限。您无法控制自动加载哪些选项。因为它们都存储为单个选项,所以要么全部自动加载,要么全部不加载

因此,请使用选项名称来命名您的值,而不是数组。e、 g。my_option_depth_mor_depth. 您甚至可以使用类似于文件夹路径的斜杠。一些流行的插件采用这种方法,带有操作和过滤器名称,例如ACF

我的意思是,使用的函数越多,代码编译的速度就越慢,尤其是在我的情况下,my\\u options()函数经常被调用。

要看到这种减速,您需要定义许多函数。您的单一功能将使您的站点速度降低几微秒。这将是难以察觉的,在统计上是无关紧要的。

重要的是你的函数做什么,而不是有多少函数。

然而,我相信你是在错误的假设下get_option 重新调用数据库。事实并非如此。

在请求开始时,WP在单个查询中获取标记为自动加载的每个选项加载选项时,这些选项存储在WP_Cache, 以及任何帖子和他们的元数据。第二次呼叫get_option 甚至都不接触数据库所谓的get_option 重复是便宜的。如果这就是你的全部功能,那么你就没有什么好害怕的了。不要猜测这些事情,要测量它们。

其他注意事项:

函数调用get_option 然后立即使用[] 操作人员它从不检查这些数组键是否存在,或者该选项是否包含数组。因此,如果未事先设置该选项,则首次使用该选项时将崩溃$key 要检查此类密钥是否确实存在,没有验证$key 实际上是一个字符串,它可能是一个数组,一个对象,null, etc参数应具有类型提示,例如。( string $key )[ 1,2,3,4 ] 而不是array( 1,2,3,4 )总体而言,您尝试使用该功能的方法对性能的影响可以忽略不计。试图让它更快将是一个微观优化,不值得你的时间。其他地方很可能会有巨大的业绩提升。例如避免前端的DB写操作、消除HTTP请求、避免通过post元数据搜索post等

关于主题Mods的一个注意事项,您提到的选项用于主题设置,这意味着you\'re not using the correct API, you should be using theme mods instead.

使用get_theme_mod 而不是get_option. WP将自动为主题的值和键命名名称空间,这样即使另一个主题具有相同的名称,也无所谓。这是您应该使用的API,最好与定制器一起使用。

相关推荐

将选项添加到“Menus”编辑器的“Screen Options”部分

我正在开发一个向WordPress菜单编辑器添加自定义选项的系统,我想将其与屏幕选项面板集成。在我的研究中,我找不到任何关于修改现有屏幕选项菜单的内容;这可能吗?请参见下面的屏幕截图,以更好地了解我要实现的目标。外观>菜单上的默认“屏幕选项”:外观>菜单上的目标“屏幕选项”: