【问题标题】:PHP Namespace 5.3 and WordPress WidgetPHP 命名空间 5.3 和 WordPress 小部件
【发布时间】:2011-07-11 23:07:28
【问题描述】:

我正在使用命名空间。

我尝试创建一个 WordPress 小部件 (http://codex.wordpress.org/Widgets_API)

对于命名空间,以下给出错误,因为无法传递参数(并且没有命名空间,它显然像往常一样工作)

 namespace a\b\c;
 class whatever extends \WP_Widget {
   function whatever() {
     parent::WP_Widget('name1', 'name2');
   }
 // .. other functions left out
 }
 add_action('widgets_init',
 create_function('', 'return register_widget("a\b\c\whatever");'));

嗯... 'parent::WP_Widget' 使用命名空间的正确语法是什么?

(COMPLETE 错误信息是:

Warning: Missing argument 2 for WP_Widget::__construct(), called in 
C:\xampp\htdocs\wp2\wp-includes\widgets.php on line 324 and defined in 
C:\xampp\htdocs\wp2\wp-includes\widgets.php on line 93

)

并且调试器显示没有通过:

Variables in local scope (#14)
$control_options = Undefined
$id_base = boolean false 
$name = Undefined
$widget_options =  Undefined

(只需要 $name)

【问题讨论】:

  • 在此处发布确切的错误消息。从代码来看,看起来并没有什么问题。另外,为什么你使用 parent 而不仅仅是 $this->WP_Widget?最后,WP_Widget 是 WP_Widget 类的构造函数吗?为什么函数与类同名?如果它是一个构造函数,那么最好使用 __construct()
  • 否:有,自 2.8 以来,小部件工厂是 WordPress 的一部分:如果您在 Eclipse 中单击 WP_Widget,您会得到它的定义...core.svn.wordpress.org/trunk/wp-includes/widgets 它应该被覆盖而不是被_construct,看源码(忍不住没写)
  • @dmitri: parent::WP_Widget 和 $this->WP_Widget 都提供相同的错误,这两种变体都在网络上使用。 WP_Widget 是根据 CODEX 应该被覆盖的函数。

标签: php wordpress namespaces


【解决方案1】:

您想调用父方法吗?只需使用parent::MethodName();

如果你想调用父构造函数,使用parent::__construct() - 如果你的构造函数被命名为类,将它重命名为__construct,这是多年来构造函数的首选名称......

【讨论】:

  • 谢谢,我一定错过了一些我已经在使用 parent::WP_Widget() 但我可能忽略了一些东西?
【解决方案2】:

在我看来你的问题不在命名空间,下面的代码就像一个魅力:

<?php
namespace Foo;

class Bar {
    function __construct( $foo ) {
        echo "$foo\n";
    }
}

namespace Foo\Bar;

class Foo extends \Foo\Bar {
    function __construct( ) {
        parent::__construct( "This should work." );
    }
}

$foo = new \Foo\Bar\Foo( );

如果您收到错误消息,说明其内容可能会有所帮助。

【讨论】:

  • @berry-langerak:很高兴知道这不是我的语法 GRIN。那这是什么?父类是默认的:core.svn.wordpress.org/trunk/wp-includes/widgets
  • 似乎 Wordpress 为旧的 PHP 4 类型构造函数提供了代理方法(嗯)。您可能要考虑改用 parent::__construct()。另外,在调用 __construct( ) 时,一定要在调用时至少两个参数。
  • 如果答案甚至不是对您问题的直接答案,您为什么要将答案标记为正确,如果 cmets 导致错误的解决,请更新您的帖子。
  • @RobertPitt 答案中的代码是正确的代码:我需要函数 _construct ,然后在答案中需要 parent::_construct ,而不是此处的文档代码:codex.wordpress.org/Widgets_API
【解决方案3】:

查看文档located here 似乎只需要名称,但 PHP 的工作方式还必须定义 pre 变量。

你有两种创建类的方法:

  • 答:
    • WP_Widget __construct ([string $id_base = false], string $name, [array $widget_options = array()], [array $control_options = array()])
  • 乙:
    • WP_Widget WP_Widget ([ $id_base = false], $name, [ $widget_options = array()], [ $control_options = array()])

根据偏好,您应该始终使用__construct 方法来初始化您的对象,我会像这样重写您的代码:

namespace a\b\c;

class whatever extends \WP_Widget
{
    function __construct()
    {
        parent::__construct('name1', 'name2');
    }

    /*
         * Other methods!
    */
}

WP_Widget::WP_Widget(..) 方法仅适用于 PHP4,不应在 PHP 5 或更高版本中使用。

现在看来您使用 PHP 5.3 作为名称空间,因此您可以执行以下操作:

add_action('widgets_init', function() {
    return register_widget(new a\b\c\whatever);
});

【讨论】:

  • 函数 __construct 做到了谢谢,答案比 berry 晚了一分钟,所以我将 berry 标记为答案。
  • regiser_widget 添加不适用于其中的 \a\b\c\,因为它在命名空间范围内。如果我删除命名空间部分,它会给出“警告:第 324 行 C:\xampp\htdocs\wp2\wp-includes\widgets.php 中的非法偏移类型”所以......我现在使用问题中的代码并将稍后检查如何执行此操作。谢谢。
  • 只需将a\b\c\whatever封装在一个字符串中并删除新关键字,这可能取决于Wordpress使用该值的方式。
  • 是的,有效: add_action('widgets_init',function(){ return register_widget('a\b\c\whatever'); });谢谢
  • 为 $id_base 传递 false 存在问题(从 WordPress 3.3.1 开始)。在 wp-admin/includes/widgets.php 中,$id_base 用作正则表达式的一部分(第 118 行),命名空间中的反斜杠会导致问题。我建议将您的示例更改为始终明确给出 $id_base,并注意它不应包含正则表达式元字符。特别是,它不应包含点,尽管它们可能不会作为 RE 元字符引起问题,但在表单处理中转换为下划线时会引起问题。
【解决方案4】:

我不使用 Wordpress,但从这个角度来看,这似乎是由于 Wordpress 的设计非常糟糕。他们似乎使用静态函数 WP_Widget 作为工厂但与类名共享相同的名称。如果它真的只是一个工厂,他们应该叫它工厂

此外,根据您在评论中发布的内容,您可能需要在子类中创建一个静态函数 WP_Widget(),然后甚至不调用父类。如果脚本真的希望您覆盖 WP_Widget,那么您应该这样做。

但是,我从来没有使用过 Wordpress,不看脚本很难判断。

您应该在此处发布确切的错误代码。

【讨论】:

  • 我已经发布了完整的确切错误代码,我可以添加堆栈跟踪吗?
【解决方案5】:

这对我来说很好用:

add_action('widgets_init', function() {                 
    register_widget('\a\b\c\whatever');
});

【讨论】:

  • register_widget accepts 类名和实例。如果需要使用类名,请改用\a\b\c\whatever::class
【解决方案6】:

您还可以使用 PHP 的原生 get_class 方法,它将任何类实例化的名称作为字符串返回。

https://www.php.net/manual/en/function.get-class.php

register_widget(get_class(new \UCI\Wordpress\Widget\Footer()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 2010-11-24
    相关资源
    最近更新 更多