如何在 OOP 单例中将参数传递给 add_feed

How to pass parameters to add_feed in an OOP singleton

当 WPML 处于活动状态时,我很难用每种语言创建单独的页面提要(URL 列表)。

计划为每种语言使用不同的提要名称,例如 feed_name_enfeed_name_fr

我编写了以下函数来遍历网站上的每种可用语言,并且应该为每种语言输出一个仅包含特定语言页面的提要。

我找到了其他示例,展示了如何使用闭包在 add_action 中传递参数。 (例如 add_action('init', function() use($param) { some_out_of_scope_function($param) } )

但是在我的函数中出现以下错误:

Object of class Closure could not be converted to string in

我怀疑是因为我用OOP把函数封装在一个数组里add_feed( $feedname, array( $this, ... ) )。但我不知道如何解决这个问题。

我该如何处理?

$feedname = 'feed_name'; 

private function createLanguageFeeds(){

    foreach($this->wpml_languages as $lang){

        // add the lang to the feed name. example: feed_name_en
        $feedname = $this->feedname . '_' . $lang;

        // making sure that the feed is created
        if ( ! in_array( $feedname, $wp_rewrite->feeds ) ) {
            $wp_rewrite->feeds[] = $feedname;
            flush_rewrite_rules( FALSE );
        }

        add_feed( $feedname, array( $this, function() use ($lang) {$this->create_page_feed($lang);} ) );
    }
}

private function create_page_feed($lang){
    // echo pages
}

如果您使用的是 PHP 5.4 或更高版本,您只需将带有 $lang 参数的闭包传递给 add_feed() 函数,$this 将保留引用对象:

add_feed( $feedname, function() use ($lang) {$this->create_page_feed($lang);} );

请注意,您的 create_page_feed() 方法需要 public 以便 WordPress 可以访问它:

public function create_page_feed($lang){
    // echo pages
}

(有关详细信息,请参阅 What is the difference between public, private, and protected?。)

这是一个经过测试且有效的演示插件,它使用单例模式注册提要:

<?php
/**
 * Plugin Name:       Singleton RSS Feed
 * Plugin URI:        https://cabrerahector.com
 * Description:       A demo RSS feed built using the Singleton pattern.
 * Version:           1.0.0
 * Author:            Hector Cabrera
 * Author URI:        https://cabrerahector.com/
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain:       singleton-rss-feed
 * Domain Path:       /languages
 */

class Singleton_RSS_Feed
{
    /**
     * The unique instance of the plugin.
     *
     * @var Singleton_RSS_Feed
     */
    private static $instance;

    /**
     * Gets an instance of our plugin.
     *
     * @return Singleton_RSS_Feed
     */
    public static function get_instance()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Constructor.
     */
    private function __construct()
    {
        // Actions
        add_action('init', array($this, 'createFeed'));
    }

    /**
     * Register the feed.
     */
    public function createFeed()
    {
        global $wp_rewrite;

        $feedname = 'some_rrs_feed';
        $lang = 'en';

        // Making sure that the feed is created
        if ( ! in_array( $feedname, $wp_rewrite->feeds ) ) {
            $wp_rewrite->feeds[] = $feedname;
            flush_rewrite_rules( FALSE );
        }

        add_feed( $feedname, function() use ($lang) {$this->renderFeed($lang);} );
    }

    /**
     * Renders the feed.
     *
     * @param string $lang
     */
    public function renderFeed($lang)
    {
        header( 'Content-Type: application/rss+xml' );
        ?>
        <xml version="1.0" encoding="UTF-8">
        <rss version="2.0">
            <channel><title>RSS Feed in <?php echo $lang; ?> language</title></channel>
        </rss>
        <?php
    }
}

$Singleton_RSS_Feed = Singleton_RSS_Feed::get_instance();

提要将在此处提供:https://www.example.com/feed/some_rrs_feed

感谢@cabrerahector,他为我指出了正确的解决方案。

对于那些想看我更正代码的人,这里是解决方案。

简单的线

add_feed( $feedname, array( $this, function() use ($lang) {$this->create_page_feed($lang);} ) );

必须改为

add_feed( $feedname, function() use ($lang) {$this->create_page_feed($lang);} );

完整代码为:

$feedname = 'feed_name'; 

private function createLanguageFeeds(){

    foreach($this->wpml_languages as $lang){

        // add the lang to the feed name. example: feed_name_en
        $feedname = $this->feedname . '_' . $lang;

        // making sure that the feed is created
        if ( ! in_array( $feedname, $wp_rewrite->feeds ) ) {
            $wp_rewrite->feeds[] = $feedname;
            flush_rewrite_rules( FALSE );
        }

        add_feed( $feedname, function() use ($lang) {$this->create_page_feed($lang);} );
    }
}

private function create_page_feed($lang){
    // echo pages
}