从URL获取ID,为什么WP自己可以做到这一点,但提供的函数中没有一个是正确的?

时间:2016-01-16 作者:EFC

我有一组用于引用我的站点的绝对URL(在本例中,它们来自旧的.htaccess文件中的重定向)。所有这些URL都会解析到站点上的某个页面或帖子。换句话说,当我在浏览器中使用它们时,它们就工作了。

WordPress以某种方式将其中许多内容内部重定向到该帖子的永久链接的当前形式。因此,URL记录为/my-old-category/my-post-slug 可能是在/my-new-category/my-post-slug 相反WordPress在实践中应对这些变化没有问题。当我使用旧的URL时,我不会登陆404。

然而,当我以编程方式尝试发现目标页面和帖子的ID时,WordPress做得并不好。在本例中,从数千个URL的列表中,我最终发现了数百个未命中的URL。也不url_to_postid 也没有get_page_by_path 似乎一直有效。这是我最幸运的代码,但它仍然让我少了几百次查找。

foreach ( $array_of_urls as $url ) {
    $id = url_to_postid( $url );
    if ( $id == 0 ) {
        $base = basename( untrailingslashit( $url ) );
        $post = get_page_by_path( $base , OBJECT, \'page\' );
        if ( $post ) {
            $id = $post->ID;
        } else {
            $post = get_page_by_path( $base , OBJECT, \'post\' );
            if ( $post ) {
                $id = $post->ID;
            }
        }
    }
    echo "$id\\t$url\\n";
}
有没有更好的方法?就像我说的,当我在网站上实际使用这些旧URL时,WordPress能够找到合适的页面或帖子。为什么它不能用PHP向我提供这些页面和帖子的ID?

[顺便说一句,是的,我知道有number of other posts 关于StackExchange解决此问题的各个方面。但似乎没有人能帮我弄清真相。很抱歉重读旧地。]

更新根据下面@Milo的指导,我用redirect_guess_404_permalink 并且有更好的查找率。

foreach ( $array_of_urls as $url ) {
    $where = $wpdb->prepare("post_name LIKE %s", $wpdb->esc_like( basename( untrailingslashit( $url ) ) ) . \'%\');
    $id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE $where AND post_status = \'publish\'");
    echo "$id\\t$url\\n";
}
有人能改进这一点吗?

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

WordPress似乎在智能地重定向旧的URL,但它所做的只是猜测,而且大部分都是正确的,因为您的帖子的性质和URL结构是唯一的,足以让它正确猜测。在某些情况下,这一猜测可能会出错。

您可以在WordPress源代码中看到它在何处执行此操作,该函数的名称非常恰当redirect_guess_404_permalink.

API函数不会猜测,它要么是精确匹配,要么不是。如果你仔细想想,这是有道理的。您可以复制该功能并执行相同的操作LIKE 查询时间post_name 如果你想像WordPress一样找到一个可能的匹配项。