Php Wordpress post对象在主题中调用get_header()后被修改

Php Wordpress post对象在主题中调用get_header()后被修改,php,wordpress,Php,Wordpress,我在我的主题中有一个自定义页面,我正在从另一个DB表创建一篇文章,然后我想在wordpress中显示这篇文章,就像它是一篇普通的文章一样。它似乎大部分时间都在工作,但在我调用get_header()之后,文章似乎被随机修改,我不明白为什么 我在apache中设置了一个mod rewrite规则来命中一个php文件,在这里我获得了所需的数据并构建了php对象。我使用此函数填充wordpress post对象 function BuildSimplePost($title, $body) {

我在我的主题中有一个自定义页面,我正在从另一个DB表创建一篇文章,然后我想在wordpress中显示这篇文章,就像它是一篇普通的文章一样。它似乎大部分时间都在工作,但在我调用get_header()之后,文章似乎被随机修改,我不明白为什么

我在apache中设置了一个mod rewrite规则来命中一个php文件,在这里我获得了所需的数据并构建了php对象。我使用此函数填充wordpress post对象

function BuildSimplePost($title, $body)
{
    require_once( SITEROOT . '/wp-load.php' );
    @$post = new WP_Post();
    @$post->ID = -1; 
    $post->post_parent  = 0;
    $post->post_title = $title;
    $post->post_name = "simple-response";
    $post->post_excerpt = substr($body, 0, 100);
    $post->comment_status = "closed";
    $post->ping_status = "closed";
    $post->post_type = "page";
    $post->post_content = $body;
    return $post;
}
一旦文章被排序,我就把这篇文章推到wordpress查询对象中,让主题完成剩下的工作

$posts = array($post);
$wp_query->posts = $posts;
$wp_query->post_count = count($posts);
$wp_query->found_posts = count($posts);
$wp_query->max_num_pages = 1;
$wp_query->post = $post;
$wp_query->is_404 = 0;
$wp_query->is_singular = 1;
$wp_query->is_single = 1;
$wp_query->page_id = $post->ID;

include get_template_directory()."/external-page.php";
内部
externalpage.php
没有什么奇怪的。它实际上是single.php的副本,删除了一些html。我遇到的问题是当
get_header()时在此文件中被调用,帖子将更改为其他内容。然后触发重定向,将用户带到wordpress网站上的另一个页面


有人知道为什么get_header方法会导致这样的重定向吗?

很难确切地说出您的帖子发生了什么变化。在我看来,你有两个选择:

  • 继续把你的内容放回帖子。这不是WordPress解决这个问题的方法,但可能是更简单的方法@ArtisticPhoenix上面的回答是正确的概念,但具体代码是错误的
  • 创建自定义帖子类型,即WordPress方式@CBroe提供了这一点,对于你对他的问题的回答(IMHO)应该是:“不管你的帖子类型有多复杂,如果你使用WordPress,你应该将它封装在CPT中。”
  • 把你的内容放回去 在某个地方保留一份post对象的副本,并在发生任何更改后立即将其放回原处。您可以创建一个新的全局视图:

    global $mypost;
    $mypost = BuildSimplePost(...);
    
    如果您知道
    $title
    $body
    参数,您可以在每次需要时再次调用函数。您还可以使用一个临时的
    update\u选项
    /
    get\u选项
    调用,或者其他一些功能

    有几个过滤器可能是cuplrit:

    • u post
      操作应更改
      $post
      。这是它真正做的一件事。您可能希望像这样坐在钩子堆栈的顶部:
      add_filter('the_post',function(){global$post,$mypost;$post=$mypost;},10000)
    • 在设置
      wp
      对象之前,有几个操作,您很可能会运行任何挂起的更改
      $post
      ,因为在此之前它是免费的。您可能有插件或主题挂接:
      parse\u request
      parse\u query
      pre\u get\u posts
      ,或
      posts\u selection
      。您可以尝试类似的操作
      add_filter('parse_request',function(){global$post;$post=$mypost;},10000)
    • 我看到一些插件开发人员在调用actions
      template\u redirect
      get\u header
      loop\u start
      after query
      时添加了一些更改
      $post
      全局的东西(以及其他他们可能不应该更改的东西)。见鬼,我自己做过几次。你可以用这些过滤器尝试同样的事情,尽管我认为它们不那么可疑。
    如果你的内容无法收回,你可以尝试一些非常脏的东西,比如在调用
    帖子之前强制输入。没有钩子,但如果你控制了主题,这很容易

    路 我知道你认为你的帖子很复杂,但我会告诉你这一点,因为我多年来一直深陷于可湿性粉剂代码中:打破可湿性粉剂帖子的模式会让人心痛。如果您没有使用帖子,也没有按照预期的方式使用帖子,那么您可能不应该使用WP。还有其他一些框架提供诸如用户身份验证、主题、数据库持久性、事件、REST等功能,而不需要WP的开销

    另一种方式 话虽如此,我过去使用WP是因为它是我无法控制的需求的一部分。当我的帖子变得太复杂时,我会创建一个包装器对象,如下所示:

    class MyPostWrapper {
      private $_Post;
      private $_Meta = array();
    
      public function __construct($post) {
        $this->_Post = get_post($post);
        $this->_Meta = $this->_LoadMeta();
      }
    
      private function _LoadMeta() {
        // Load everything into $_Meta: other tables, options, post meta, etc.
      }
    
      public function __get($name) {
        if (array_key_exists($name, $this->_Meta))
          return $this->_Meta[$name];
      }
    
      // Use a similar implementation for __set and __isset.
    
    }
    
    无论您的帖子变得多么复杂,您都可以使用单个包装器轻松管理其生命周期和所有线索


    那么你就不必担心谁在吃你的帖子了。如果他们是,他们可能应该是。

    你看过wordpress生成的实际源代码了吗。@ArtisticPhoenix wordpress有很多源代码。您能指定我需要查看的代码吗?不太可能,但您可能会看到2个
    标记或一些非常混乱的suff,或者像
    元刷新
    ,除非您查看,否则谁知道呢。也许你看到复活节兔子了?你不知道你认为你知道什么,直到你真正知道它。所以你是绕过所有的机制,可湿性粉剂已在船上处理自定义职位类型,有利于你自己的怪异法兰安装通过后门的方法。。。为什么?你也可以试试
    ob_start();获取_头()$content=ob_get_clean()
    将执行该函数,但在缓冲区中捕获输出,然后您将知道头中是否有某些内容正在执行该函数或某些功能。这是一个过程,你只需要消除一些东西。