【发布时间】:2011-09-22 15:47:27
【问题描述】:
我有一个包含这些方法的抽象类:
<?php
public static function getInstance() {
$me = get_called_class();
if (!isset(self::$_instances[$me])) {
$ref = new ReflectionClass($me);
self::$_instances[$me] = $reflection_object->newInstance();
self::$_instances[$me]->init();
}
return self::$_instances[$me];
}
public function __construct() {
$me = get_class($this);
if(isset(self::$_instances[$me])) {
throw new Exception('The singleton class has already been instantiated!');
} else {
self::$_instances[$me] = $this;
$this->_className = $me;
}
}
在同级单例中实例化时,它的工作方式完全符合我的预期。我在尝试从不共享相同超类的子类中获取实例时遇到问题。
我的堆栈跟踪是:
Fatal error: Call to undefined method Keywords_AdminMenu_OptionsTable::init() in D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-content\plugins\LocalGiant_WPF\library\LocalGiant\Module\Abstract.php on line 149
Call Stack:
0.0012 331664 1. {main}() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-admin\admin.php:0
0.7772 3224864 2. do_action() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-admin\admin.php:151
0.7774 3225792 3. call_user_func_array() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-includes\plugin.php:405
0.7774 3225808 4. Keywords_AdminMenu->showMenu() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-includes\plugin.php:405
0.7796 3227016 5. Keywords_AdminMenu_View::showMenu() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-content\plugins\LocalGiant_WPF\modules\Keywords\AdminMenu.php:29
0.7821 3240776 6. Keywords_AdminMenu_OptionsTable->prepareItems() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-content\plugins\LocalGiant_WPF\modules\Keywords\AdminMenu\View.php:25
0.7822 3241824 7. LocalGiant_Module_Abstract->getInstance() D:\webroot\domains\dev.slbmeh.com\htdocs\wordpress\wp-content\plugins\LocalGiant_WPF\modules\Keywords\AdminMenu\OptionsTable.php:90
init() 方法是 Singleton 超类中的一个抽象方法。类 Keywords_AdminMenu_OptionsTable 是来自一组单独库的类的子类,来自 WordPress 的 WP_List_Table。
Keywords_AdminMenu_Options 类表的分解副本如下:
<?php
class Keywords_AdminMenu_OptionsTable extends WP_List_Table {
public function __construct(){
global $status, $page;
//Set parent defaults
parent::__construct( array(
'singular' => 'module',
'plural' => 'modules',
'ajax' => false
) );
}
function prepareItems() {
/* SNIP - Prepare my SQL query. */
$moduleDatabase = Database_Module::getInstance();
$current_page = $this->get_pagenum();
$keywords = $moduleDatabase->simpleQuery($sql, $moduleLoader->getMyNamespace());
/* SNIP - Handle my SQL data. */
}
}
WP_List_Table 的内容在这里找到:http://core.trac.wordpress.org/browser/tags/3.2.1//wp-admin/includes/class-wp-list-table.php
【问题讨论】:
-
这是一个相当大的课程,所以我会放一个链接。 core.trac.wordpress.org/browser/tags/3.2.1//wp-admin/includes/… 并将其添加到问题中。
-
我不明白这个问题。
-
在我看来,你的
get_called_class返回Keywords_AdminMenu_OptionsTable,而你却期待Database_Module。 -
是的,这是预期的设计吗?或者它是一个错误?任何解决方法的想法?
-
奇怪的是 get_call_class() 在这种情况下的功能。它不返回直接调用类,也不返回第一个调用类。它在中间的某个地方。第一个调用的类是 Keywords_AdminMenu,它是 WordPress 操作的回调。
标签: php oop inheritance singleton