在header.php中调用全局$wpdb的对象方法

时间:2014-10-02 作者:user54952

我正在以面向对象的方式开发Wordpress插件,我想使用全局$wpdb变量从Wordpress数据库读取数据。

全局$wpdb变量是从一个特定的类方法中调用的。该类在插件编辑器中定义,但对象本身在标头中实例化。我的主题的php文件。

此方法成功地回显了我硬编码的HTML,但不会回显它们之间本应从$wpdb读取的数据。

提前感谢您的帮助!

编辑:以下是代码:

Class Custom_Header 
{
public function print_header()
    {
    if ( isset($_SESSION[\'header\']) )
    {
    switch ($_SESSION[\'header\'])
        {
            case 1:
            {
            global $wpdb;
            $wpdbinfo = $wpdb->get_results("SELECT * FROM bo_mytable WHERE id=3");
            $content="<div>".$wpdbinfo->nameinfo."</div>";
            return $content;
            }
        }
     }
     }
}
然后在标题中。php:

$custom_header = new Custom_Header();
echo $custom_header->print_header();
如上所述,我可以看到DIV已经得到了正确的回应,但里面的内容没有:-(。

2 个回复
最合适的回答,由SO网友:Justin Bell 整理而成

我认为问题可能在于:

$wpdbinfo = $wpdb->get_results("SELECT * FROM bo_mytable WHERE id=3");
$wpdb->get_results() 返回对象数组,但您正在引用上的属性$wpdbinfo (->nameinfo). 您可以通过$wpdbinfo 数组,或者如果您确定只会得到一条记录(如果id 是主键),您可以使用$wpdb->get_row().

SO网友:gmazzap

如中所述Codex, wpdb::get_results():

函数将整个查询结果作为array

(加粗的矿山)

那么,你的$wpdbinfo 不是对象,而是数组WP_DEBUG, 您的代码引发了警告。

当您需要一个单行表单db时,请使用wpdb::get_row() 当您需要单个变量时(如示例中所示),请使用wpdb::get_var().

示例:

class Custom_Header {

  private $db;

  function __construct() {
    $this->db = $GLOBALS[\'wpdb\'];
  }

  public function print_header() {
    if ( ! isset( $_SESSION[\'header\'] ) ) {
      return;
    }
    switch ( $_SESSION[\'header\'] ) {
      case 1:
        $nameinfo = $this->db->get_var( "SELECT nameinfo FROM bo_mytable WHERE id=3" );
        return printf( "<div>%s</div>", esc_html( $nameinfo ) );
    }
  }
}
如果这不起作用,请确保$_SESSION[\'header\'] 设置并等于1。

最后,应该避免在代码中硬编码表名,因为db前缀很容易更改。

一旦您使用OOP方法进行编码,并且似乎正在使用自定义表,您就可以创建一个自定义类来包装wpdb,并使用正确的前缀设置表。

实例

<?php 
namespace MyPlugin;

class MyDb {

  private static $instance;
  /** @var array $tables Custom table names, without prefix */
  private static $tables = array( \'my_table_1\', \'my_table_2\', \'my_table_3\' );
  private $db;

  /**
   * Makes an instance of this class accessible from anywhere
   */
  static function instance() {
    if ( is_null( static::$instance ) ) {
       $class = get_called_class();
       static::$instance = new $class;
    }
    return static::$instance;
  }

  /**
   * Proxies all method calls to wpdb
   */
  function __call( $name, $args ) {
    return call_user_func_array( array( $this->db, $name ), $args );
  }

  /**
   * Proxies all property access to wpdb
   */
  function __get( $name ) {
    return $this->db->$name;
  }

  function __construct() {
    $this->db = $GLOBALS[\'wpdb\'];
  }

  /**
   * Set custom table names in wpdb
   */
  function prepareTables() {
    foreach ( static::$tables as $table ) {
      $wpdb->$table = $this->db->prefix . $table;
    }
  }
}
现在,在插件的某个地方,您可以:

add_action( \'plugins_loaded\', function() {
   $mydb = MyDb::instance();
   $mydb->prepareTables();
   if ( is_multisite() ) {
     add_action( \'switch_blog\', function() use($mydb) {
       $mydb->prepareTables();
     } );
   }
} );
通过这种方式,首先将自定义表设置为wpdb属性,如果是多站点,则在切换博客时更新该设置。

现在,您的自定义头类变成如下所示:

<?php 
namespace MyPlugin;

class Custom_Header {

  private $db;

  function __construct( MyDb $db ) {
    $this->db = $db;
  }

  public function print_header() {
    if ( ! isset( $_SESSION[\'header\'] ) ) {
      return;
    }
    switch ( $_SESSION[\'header\'] ) {
      case 1:
        // note how table name is dynamic 
        $q = "SELECT nameinfo FROM {$this->db->mytable} WHERE id=3";
        $nameinfo = $this->db->get_var( $q );
        return printf( "<div>%s</div>", esc_html( $nameinfo ) );
    }
  }
}
在你的header.php

$custom_header = new MyPlugin\\Custom_Header( MyPlugin\\MyDb::instance() );
echo $custom_header->print_header();
请注意,上面的代码需要PHP 5.3+

结束