dongmu1996 2011-02-27 14:52
浏览 176
已采纳

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

I am working on a website with php/mysql.

I have 3 files config.php, utils.php and member.php. code of the files are as below,

config.php - $objPath->docrootlibs is fine, I am sure there is no problem with this.

    /* 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();
        }
    }

Now when I am including the config.php inside a page home.php with simple php include statement and running that page then it gives me following error.

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

Line numbers in error above are different, I just copied the specific part from the code here.

I am not understanding why its giving error, because objects of utils class is defined on config page before including the member class. It should detect that object.

Please check and help me to understand and correct this error.

Thanks!

  • 写回答

4条回答 默认 最新

  • dswmmvrg40957 2011-02-27 15:17
    关注

    One Solution

    Unlike JavaScript PHP will not bubble up through scopes, which means

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

    does not know what $objUtils is, because there is no such object defined in the local scope. This means, you have to make the object available inside that scope. The cleanest and most maintainable way to do that is to inject the utils instance to the member instance, e.g.

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

    However, since you seem to be using that value on construction only anyway, there is no reason why your member instance has to know how to use the utils object. So why not just insert the actual value right from the start, e.g.

        public function __construct($lastActivity){
            $this->lastactivity = $lastActivity;
        }
    
        // then do
        $utils  = new utils();
        $member = new member($utils->getCurrentDateTimeForMySQL());
    

    On globals

    You definitely do not want to use the global keyword or static methods. Both couple back to the global scope. This means you can no longer use the member class without the global scope. This makes maintaining, reusing, refactoring and testing harder. OOP is about encapsulation and by reaching out from the class to the global scope you are breaking that encapsulation. Use Dependency Injection as shown above instead.

    Apart from that, using globals will also make your code harder to read. A developer looking at the ctor signature of member is likely to assume there is nothing else to do than just call new member. That's a lie, because she also has to setup the utils instance. In other words, you are hiding dependencies. The developer has to look at the actual code to understand what's going on. Thus, make dependencies explicit.

    Some more resources:


    EDITs after comments

    If you really need that utils object, inject the instance and assign it to a property inside the member instance in the ctor. Then you can access it with $this->utils->foo() from anywhere else inside the member instance.

    However, Utility classes are almost always a sign of bad design. It is much more likely that they should be broken apart and divided into/onto other objects. Try to find out the reponsibilities. Maybe Member should not use Utils, but Utils should be something else that uses Members.

    Out of curiosity, why do you need a utility method for MySql anyway? If you use a Timestamp column in MySql for lastActivity, it will automatically update whenever the row is updated. I am assuming you are setting the lastActivity and then store the member data?

    Regarding performance: you should not bother about performance. Write readable and maintainable code first and foremost. If you think your performance is not good enough, profile the application with XDebug to see what is really making an impact.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器