在php中调用其他类的对象?

时间:2011-02-27 14:52:51

标签: php

我正在使用php / mysql开发一个网站。

我有3个文件config.phputils.phpmember.php。文件的代码如下,

config.php - $objPath->docrootlibs很好,我相信这没问题。

    /* Other library files & their object */
    require($objPath->docrootlibs.'/utils.php');
    $objUtils = new utils();

    require($objPath->docrootlibs.'/member.php');
    $objMember = new member();

utils.php中

    class utils{
        function getCurrentDateTimeForMySQL(){
            return date("Y-m-d H:i:s");
        }
    }

members.php

    class member{
        var $userid;
        var $username;

        function __construct(){
            $this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
        }
    }

现在当我在页面config.php中包含home.php简单的php include语句并运行该页面时,它会给我以下错误。

Notice: Undefined variable: objUtils in D:\wamp\www\site\libs\member.php on line 17

Fatal error: Call to a member function getCurrentDateTimeForMySQL() on a non-object in D:\wamp\www\site\libs\member.php on line 17

上面错误的行号不同,我只是从这里的代码中复制了特定的部分。

我不明白为什么会给出错误,因为在包含成员类之前,在配置页面上定义了utils类的对象。它应该检测到该对象。

请检查并帮助我理解并纠正此错误。

谢谢!

4 个答案:

答案 0 :(得分:2)

正如另一条评论所述,使用依赖注入。将utilities实用程序对象插入构造函数中。不要在全局范围内引入变量,尤其是在不同文件之间。这变得非常混乱,并创建了一些文件包含的强制命令。

class member {
   ...
   public function __construct(utils $objUtils) {
      $this->objUtils = $objUtils;
      ...
   }
}

在调用代码时:

$member = new member(new utils);

顺便说一句,我觉得很幽默,你的宏名称比其执行的操作更长。

另外,您需要一个实用工具类吗?实用程序可以只是功能吗?

答案 1 :(得分:2)

一种解决方案

与JavaScript不同,PHP不会通过范围冒泡,这意味着

    public function __construct(){
        $this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
    }

不知道$objUtils是什么,因为在本地范围内没有定义这样的对象。这意味着,您必须在该范围内使对象可用。最干净,最易维护的方法是将utils实例注入成员实例,例如

    public function __construct($utils){
        $this->lastactivity = $utils->getCurrentDateTimeForMySQL();
    }

但是,由于您似乎只在构造中使用该值,因此您的成员实例无需知道如何使用utils对象。那么为什么不直接从一开始就插入实际值,例如

    public function __construct($lastActivity){
        $this->lastactivity = $lastActivity;
    }

    // then do
    $utils  = new utils();
    $member = new member($utils->getCurrentDateTimeForMySQL());

关于全局

您肯定想要使用global关键字或static方法。两人都回到了全球范围。这意味着您不能再使用没有全局范围的成员类。这使得维护,重用,重构和测试更加困难。 OOP是关于封装的,通过从类到全局范围,你打破了封装。请使用依赖注入,如上所示。

除此之外,使用全局变量也会使您的代码更难阅读。查看成员ctor签名的开发人员可能会认为除了调用new member之外别无他法。这是谎言,因为她还必须设置utils实例。换句话说,您正在隐藏依赖项。开发人员必须查看实际代码以了解正在发生的事情。因此,明确依赖关系。

更多资源:


评论后编辑

如果确实需要该utils对象,请注入实例并将其分配给ctor中成员实例内的属性。然后,您可以从成员实例内的任何其他位置使用$this->utils->foo()访问它。

但是,实用程序类几乎总是设计糟糕的标志。它们更有可能被拆开并分成其他物体。试着找出可靠性。也许会员不应该使用Utils,但Utils应该是使用会员的其他东西。

出于好奇,为什么你还需要MySql的实用方法?如果在MySql中为lastActivity使用Timestamp列,则只要更新行,它就会自动更新。我假设您正在设置lastActivity,然后存储成员数据?

关于表现:你不应该担心表现。首先编写可读和可维护的代码。如果您认为自己的表现不够好,请使用XDebug对应用程序进行分析,看看究竟有什么影响。

答案 2 :(得分:0)

听起来config.php在全球范围内。使用$ objUtils时需要使用global关键字

    function __construct(){
        global $objUtils;
        $this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
    }

答案 3 :(得分:0)

由于你的getCurrentDateForMySQL不依赖于utils对象中的任何其他东西,为什么不把它变成静态函数呢?这样您就可以将member()方法转换为:

function __construct(){
    $this->lastactivity = utils::getCurrentDateTimeForMySQL();
}