将自定义字段添加到来自自定义表的发布对象

时间:2012-11-21 作者:Igor

我正在为WordPress编写一个计数器插件,它将跟踪每日和总视图。

通常,您会使用post元字段来存储此类信息。但我不能:

我不能使用元字段,因为元字段不能更新,否则会丢失以前的值(没有锁定)。例如:

元字段“dviews”的值为10。请求#1传入时,它将获取字段并使用$oldValue+1(=11)调用update\\u meta。这将在一个只能发生一个请求的世界中起作用。但在现实世界中,存在多个并发请求。因此,当来自请求#1的工作者正在保存“11个dviews”时,其他请求可能已经将该值增加到17。结果:来自请求#1的工作者将把统计信息设置回11-我将丢失7个视图。在一个安静繁忙的网站上,这可能是一个真正的问题。

解决方案:我创建了另一个表“视图”,其中包含两个字段:post\\u id和dviews。

我现在可以运行“INSERT…ON DUPLICATED KEY UPDATE…*”语句。这非常强大,我保存了一个查询。

问题:我现在想在管理仪表板中显示视图(作为edit.php中的列)。我可以通过*pre_get_posts*、*posts_fields*和*posts_joins*这样的钩子连接我的表视图,因此我的字段在循环中可用。

但是当我想获取一个post对象(我使用的是*get\\u post*)时,我的字段就会丢失,因为函数不使用循环中的post。

我能做什么?

写我自己的“get\\u post”函数我想避免只针对统计数据的额外查询。当在仪表板表中显示100条帖子时,我会得到额外的100条查询,仅用于统计数据。不太好。是否有可靠的方法从循环访问已经填充的帖子?我真的不明白为什么“get\\u post”不使用这些数据。也许有人能解释一下?

我还希望避免操纵核心表。但我不确定是否有更好的方法,因为

function &get_post(&$post, $output = OBJECT, $filter = \'raw\') {

    // [...]

        if ( ! $_post = wp_cache_get($post_id, \'posts\') ) {
            $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id));

    // [...]
}
// (from wp-includes\\post.php)
将询问缓存并至少运行其自己的不可挂接查询。

3 个回复
SO网友:Tom J Nowell

或者,不更新元字段,而是添加一个新的元字段!

接下来的问题是,哪个元的值最高,以及如何清理其他元字段。

我将如何做到这一点,而不是重新发明轮子,我可以看到,谷歌在计算一个页面的浏览量方面已经做得很好了。我还可以看到Google Analyticator甚至向我展示了前5名,并给了我一张图表。

因此,请使用Google API,或集成其他现有解决方案。甚至wordpress。com(&A);WP Stats将结果发送到远程计算机,而不是本地托管整个Stats包和数据库。

使用post meta、或options、或自定义表等将降低页面加载速度,使数据库变得更大,并带来许多问题,而不仅仅是锁定表行。

关于性能的最后一点,我还要承认,在速度/可扩展性和数据的新鲜度之间,存在着内在的权衡。如果您在前端有一个始终100%准确的计数器,那么它会带来计算和后勤成本。

另一方面,近似值不需要经常更新,并且可以更容易地缓存。突然间,您的程序有了喘息的空间,您可以调整更新率以适应您的站点和环境。

SO网友:IgniteWoo Team

MySQL将防止您在正在写入/编辑的记录上发生冲突。因此,您实际上可以使用post元字段存储计数器等。只需编写自己的查询即可读取值并同时更新所有值。

示例:

update wp_postmeta set meta_value = ( (CAST meta_value AS DECIMAL) + 1 ) where meta_key = "my_counter" and post_id = 123
像这样的。。。

SO网友:Luke Chinworth

首先,选择并加入自定义表:

add_filter(\'post_clauses\', function($clauses) {
    $clauses[\'fields\'] .= ", my_table.my_column";
    $clauses[\'join\'] .= " JOIN my_table ON my_table.post_id = wp_posts.ID";
    return $clauses;
});
然后,在循环中,您可以使用get_post_field(\'my_column\')

结束

相关推荐