我需要从可选择的帖子类别列表中隐藏“未分类”,并编写一些代码来实现这一点。This function worked fine 在WP 4.7.5之前,成功隐藏了以下类别:
add_filter(\'list_terms_exclusions\', \'myproject_hide_uncategorized\',1);
function myproject_hide_uncategorized( $exclude_query ) {
if (function_exists(\'get_current_screen\')) {
$currentScreen = get_current_screen();
if ($currentScreen->base == \'post\') {
$newquery = "";
$excluidos = array();
$excluidos[] = get_category_by_slug(\'sem-categoria\')->cat_ID;
$excluidos[] = get_category_by_slug(\'uncategorized\')->cat_ID;
foreach ($excluidos as $excluido) {
$newquery .= " AND t.term_id <> \'$excluido\' ";
}
$exclude_query .= $newquery;
}
}
return $exclude_query;
}
然而,在更高版本(4.8.1是目前为止的最新版本)上,每当我尝试编辑帖子或创建新帖子(访问“localhost/wp admin/post new.php”),我都会收到以下错误消息:
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 130968 bytes) in /var/www/html/wp-includes/class-wp-term-query.php on line 294
提高内存限制只会导致超时错误。我能够在WP 4.8和4.8.1的干净安装中复制该行为
看起来崩溃是由这四条线引起的,将其添加到functions.php
任何主题的文件似乎都会导致崩溃:
add_filter(\'list_terms_exclusions\', \'this_will_crash_wordpress\');
function this_will_crash_wordpress( $exclude_query ) {
get_category_by_slug(\'uncategorized\');
}
What changed between 4.7.5 that causes this error? How can I make it go away? Do I have to rewrite my code? If so, how?
最合适的回答,由SO网友:Tom J Nowell 整理而成
因为get_category_by
呼叫get_term_by
哪个呼叫get_terms
这将创建WP_Term_Query
运行list_terms_exclusions
过滤器,它运行调用get_category_by
哪个呼叫get_term_by
哪个呼叫get_terms
等等等等等等
Your problem is that of an infinite loop, 您在过滤器中调用的函数会触发它们被调用的过滤器。并不是WordPress发生了变化,而是过滤器一开始就不应该工作。
解决方案
断开环路
在调用之前,请解开过滤器
get_category_by
, 然后再把它钩住。
我不太喜欢这个选项
从术语ID更改为术语slug/name
您不需要找到具有名称的术语ID
uncategorized
, 您已经传入了SQL,所以请使用
t.slug <> \'uncategorized\'
或者类似的东西
这稍微好一点,但它仍然犯了一个基本的错误,即为MySQL提供了一个NOT选择器。这些类型的查询基本上很昂贵,而且无法扩展,您应该询问您想要什么,而不是不想要什么。
在PHP中提取术语
提取术语后,在PHP中手动提取不需要的术语。这是性能最好的选项,可扩展性最好。它对数据库更加友好
该metabox专门使用以下两个函数来显示术语:
wp_dropdown_categories
wp_terms_checklist
wp_dropdown_cats
可用于筛选的最终HTML输出
wp_dropdown_categories
虽然你可以
get_terms
并使用其过滤器更有效地删除该点之前的项。
For details on how to do that, see this question/answer这是我首选的解决方案
删除metabox并添加自己的
只要表单输入与标准metabox相同,就可以完全替换它,并且不需要保存代码。
我不太喜欢这个解决方案,因为它可能会干扰其他插件,并且需要付出最大的努力