如何在两个函数之间共享变量?

时间:2016-05-30 作者:Mike Oberdick

所以这是我的插件代码的一部分。我是一个新手,所以要友善。我读过关于全局变量的书,但我似乎无法让它发挥作用,我读到你无论如何都不应该使用它们。那么,在不必为每个函数重新声明变量的情况下,编写下面代码的最佳方法是什么呢?这是full code 如有必要。

// Display the product badge on the shop page

add_action( \'woocommerce_after_shop_loop_item_title\', \'wc_simple_product_badge_display_shop\', 30 );
function wc_simple_product_badge_display_shop() {
    $title = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_title\', true ); // badge title
    $class = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_class\', true ); // badge class
    $duration = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_duration\', true ); // badge duration
    $postdate = get_the_time( \'Y-m-d\' ); // post date
    $postdatestamp = strtotime( $postdate ); // post date in unix timestamp
    $difference = round ((time() - $postdatestamp) / (24*60*60));  // difference in days between now and product\'s post date

    if ( !empty( $title ) && empty( $duration ) || !empty( $title ) && $difference <= $duration ){ // Check to see if there is a title and the product is still within the duration timeframe if specified
        $class = !empty( $class ) ? $class : \'\';
        echo \'<span class="wc_simple_product_badge \' . $class . \'">\' . $title . \'</span>\';
    }
}

// Display the product badge on the single page

add_filter( \'woocommerce_single_product_image_html\', \'wc_simple_product_badge_display_single\' );    
function wc_simple_product_badge_display_single( $img_html ) {
    $title = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_title\', true ); // badge title
    $class = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_class\', true ); // badge class
    $duration = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_duration\', true ); // badge duration
    $single_opt = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_single_page_option\', true ); // badge on single page
    $postdate = get_the_time( \'Y-m-d\' ); // post date
    $postdatestamp = strtotime( $postdate ); // post date in unix timestamp
    $difference = round ((time() - $postdatestamp) / (24*60*60));  // difference in days between now and product\'s post date

    if ( !empty( $title ) && empty( $duration ) && $single_opt === \'yes\' || !empty( $title ) && $difference <= $duration && $single_opt === \'yes\' ){ // Check to see if there is a title and the product is still within the duration timeframe ()if specified) and the checkbox is checked to show on single page view
        $class = !empty( $class ) ? $class : \'\';
        echo \'<span class="wc_simple_product_badge \' . $class . \'">\' . $title . \'</span>\';
        return $img_html;
}

    elseif ( $single_opt === \'no\' ) { // Check to see if the checkbox is unchecked to show on single page view
        return $img_html;
    }

}

2 个回复
SO网友:fuxia

创建一个类以将变量存储为私有内部成员。设置post对象时设置变量,这就是操作the_post.

然后将类方法指定为回调,而不是单独的函数。

以下是稍微重新格式化的代码:

班级

class WPSE_WC_Badge
{
    private $title = \'\';    
    private $class = \'\';    
    private $duration = \'\';    
    private $postdate = \'\';    
    private $postdatestamp = \'\';    
    private $difference = 0;

    public function __construct( \\WP_Post $post )
    {
        $this->title         = get_post_meta( $post->ID, \'_wc_simple_product_badge_title\', TRUE ); // badge title
        $this->class         = get_post_meta( $post->ID, \'_wc_simple_product_badge_class\', TRUE ); // badge class
        $this->duration      = get_post_meta( $post->ID, \'_wc_simple_product_badge_duration\', TRUE ); // badge duration
        $this->postdate      = get_the_time( \'Y-m-d\', $post ); // post date
        $this->postdatestamp = strtotime( $this->postdate ); // post date in unix timestamp
        // difference in days between now and product\'s post date
        $this->difference = round( ( time() - $this->postdatestamp ) / DAY_IN_SECONDS );
    }

    function loop()
    {
        if ( ! empty( $this->title ) && empty( $this->duration )
             || ! empty( $this->title ) && $this->difference <= $this->duration
        )
        { // Check to see if there is a title and the product is still within the duration timeframe if specified
            echo \'<span class="wc_simple_product_badge \' . $this->class . \'">\' . $this->title . \'</span>\';
        }
    }

    function single( $img_html )
    {
        $single_opt = get_post_meta( get_the_ID(), \'_wc_simple_product_badge_single_page_option\', TRUE ); // badge on single page

        if ( ! empty ( $this->title ) && empty( $this->duration ) && $single_opt === \'yes\'
             || ! empty( $this->title ) && $this->difference <= $this->duration && $single_opt === \'yes\'
        )
        {
            echo \'<span class="wc_simple_product_badge \' . $this->class . \'">\' . $this->title . \'</span>\';

            return $img_html;
        }

        return $img_html;
    }
}
以及注册

add_action( \'the_post\', function( \\WP_Post $post ) {

    $badge = new WPSE_WC_Badge( $post );

    // Display the product badge on the shop page
    add_action( \'woocommerce_after_shop_loop_item_title\', [ $badge, \'loop\' ], 30 );
    // Display the product badge on the single page
    add_filter( \'woocommerce_single_product_image_html\', [ $badge, \'single\' ] );
});
我还没有测试过这个,请把它作为起点。

SO网友:Richard Green

虽然Toscho的答案没有错,但使用类可以避免这个问题,OP最初的问题是关于globals的使用,因此这些答案应该直接针对这个问题。

---使用全局变量---

在全局范围内(不在函数或类似函数内)定义的任何变量本质上都是全局变量。要访问函数中的全局with,必须使用global关键字,例如。global $myglobal

下面是经过重构的代码,以演示:

<?php

$product_data = array();

// populating the global on a hook before the other two
add_action(\'woocommerce_before_single_product\',\'populate_product_data\');
function populate_product_data() {
    global $product_data;

    $postdate = get_the_time( \'Y-m-d\' ); // post date
    $postdatestamp = strtotime($postdate);

    $product_data = array(
        \'title\'         => get_post_meta( get_the_ID(), \'_wc_simple_product_badge_title\', true ), // badge title
        \'class\'         => get_post_meta( get_the_ID(), \'_wc_simple_product_badge_class\', true ), // badge class
        \'duration\'      => get_post_meta( get_the_ID(), \'_wc_simple_product_badge_duration\', true ), // badge duration
        \'single_opt\'    => get_post_meta( get_the_ID(), \'_wc_simple_product_badge_single_page_option\', true ), // badge on single page
        \'postdate\'      => $postdate,
        \'postdatestamp\' => $postdatestamp, // post date in unix timestamp
        \'difference\'    => round ((time() - $postdatestamp) / (24*60*60)),  // difference in days between now and 
    );
}

add_action( \'woocommerce_after_shop_loop_item_title\', \'wc_simple_product_badge_display_shop\', 30 );
function wc_simple_product_badge_display_shop() {
    global $product_data;

    if ( !empty( $product_data[\'title\'] ) && empty( $product_data[\'duration\'] ) || !empty( $product_data[\'title\'] ) && $product_data[\'difference\'] <= $product_data[\'duration\'] ){ // Check to see if there is a title and the product is still within the duration timeframe if specified
        $class = !empty( $class ) ? $class : \'\';
        echo \'<span class="wc_simple_product_badge \' . $product_data[\'class\'] . \'">\' . $product_data[\'title\'] . \'</span>\';
    }
}

// Display the product badge on the single page

add_filter( \'woocommerce_single_product_image_html\', \'wc_simple_product_badge_display_single\' );    
function wc_simple_product_badge_display_single( $img_html ) {
    global $product_data;

    if ( !empty( $product_data[\'title\'] ) && empty( $product_data[\'duration\'] ) && $product_data[\'single_opt\'] === \'yes\' || !empty( $product_data[\'title\'] ) && $product_data[\'difference\'] <= $product_data[\'duration\'] && $product_data[\'single_opt\'] === \'yes\' ){ // Check to see if there is a title and the product is still within the duration timeframe ()if specified) and the checkbox is checked to show on single page view
        $class = !empty( $product_data[\'title\'] ) ? $product_data[\'title\'] : \'\';
        echo \'<span class="wc_simple_product_badge \' . $product_data[\'class\'] . \'">\' . $product_data[\'title\'] . \'</span>\';
        return $img_html;
}

    elseif ( $product_data[\'single_opt\'] === \'no\' ) { // Check to see if the checkbox is unchecked to show on single page view
        return $img_html;
    }

}

相关推荐

Class variables in shortcodes

不知道我做错了什么,但我有以下代码:class the_shortcode { //Define Class Variables private $var; public function __construct() { add_shortcode( \'the_single\', array( $this, \'shortcode_2\' )); }&#