【问题标题】:Add objects to an instance in PHP将对象添加到 PHP 中的实例
【发布时间】:2011-03-09 21:00:34
【问题描述】:

简介

我正在开发一个 MVC 框架,但遇到了问题。看来我试图完成的是所谓的单例设计方法——只初始化一次类。请记住,我试图在控制器 "acontroller" 中尽可能少地编写代码。

话虽如此,最后一个问题仍然存在:如何将对象添加到已经实例化的对象中?

拥有或至少查看实际源代码可能会有所帮助,而不仅仅是示例源代码,因此我已将源代码推送到我的 github。你可以在这里找到:https://github.com/derekmaciel/uMVC


代码说明

首先发生的是“幕后”,

  • Controller 类加载位于 /application/controller 中的控制器,在本例中为“acontroller”。
  • 之后,acontroller 类使用 Load 类加载模型(称为“amodel”),使用 $this->load->model("amodel"),该模型在 Controller __construct 中实例化。
  • $this->load->model("amodel") 的最终结果是:$controller->amodel =& new Amodel(),其中 $controller 是 Controller 实例(不是控制器,因为控制器加载型号会有所不同)。
  • 步骤 4:允许控制器访问已加载的模型 (amodel)。

代码结果

可以在此处找到这些脚本的当前输出的副本:http://pastebin.com/EJxuXaki

您会注意到的第一件事是,我收到了使用已弃用分配的警告。我现在将专注于错误。

您会注意到的第二件事是我首先 print_r()'d 控制器实例。里面有一个amodel对象,要添加到控制器中。

在那之后,我打印了 $this(控制器)对象。它拥有从 __construct() 获得的一切,但没有模型。

如果我能让控制器“看到”模型,那么我的问题就会解决。

还有: 无论如何我可以从控制器 acontroller 中删除“parent::init()”吗?我这样做只是为了让控制器可以同时访问 Load 和 Model 类,但我试图在控制器中放置尽可能少的代码,因此让控制器自动访问 Load 和 Model 会有很大帮助。

我希望我很清楚。感谢您的帮助

【问题讨论】:

  • 你的设计坏了。控制器没有理由成为单例。事实上,there is no reason to use Singletons in PHP at allAnd you should not use the global keyword either.
  • @Gordon 单例设计是我能想到的唯一方法,因为替代方案是依赖注入;我的目标是避免在我的应用程序中放置“系统”代码,并且只允许核心这样做。我需要找到一种方法,让我的应用程序可以访问我的 Core 可以访问的相同内容。
  • Weeeell,我猜你的框架首先是作为一个学习练习,所以继续犯这些错误:) 以后意识到它坏了没有错。

标签: php oop object singleton


【解决方案1】:

我个人认为单例方法不属于 MVC 框架,原因是加载的主要对象是模型、库和控制器,其他所有内容(例如路由器)通常都是硬编码的。

我要做的结构是创建以下类:

  • 模型加载器
  • 库加载器

并在系统启动期间包含它们,然后在您的主控制器中执行以下操作:

class Controller
{
    public $library;
    public $model;

    public function __construct()
    {
        $this->library = new LibraryLoader();
        $this->model = new ModelLoader();
    }
}

这会将 2 个加载器暴露给子控制器,您的模型/库应该保存一个私有数组来存储加载的对象,有点像这样:

class LibraryLoader extends ObjectLoader
{
     protected $_path = "/app/library/";
     protected $_ext = '.php';
}

class ModelLoader extends ObjectLoader
{
     protected $_path = "/app/models/";
     protected $_ext = '.php';
}

对象加载器如下所示:

class ObjectLoader
{
     protected $_path = "/app/";
     protected $_ext = '.php';

     public function __get($item)
     {
          /*
                * Load item here, the paths above would be overwritten
                * store the object in an array, make sure you check if its already loaded
           */
     }
}

这是非常基本的,但是在您的子控制器(例如 index / home 等)中,您可以执行以下操作:

class indexController extends Controller
{
    public function index()
    {
        $this->model->users->getUser(22);
        $this->library->security->validateInput("get","key");

        //As the objectLoader manages whats loaded, any further calls to the above would
        //use the same objects initiated as above.
    }
}

这应该可以帮助您入门,使用单例方法可以更简化它们。

【讨论】:

    【解决方案2】:

    我猜你需要在你的 controller.php 中包含 Model.php 才能使用模型类。

    include 'Model.php';
    include 'Load.php';
    

    【讨论】:

    • Model.php 和 Load.php 在 Controller 类中工作正常,但在控制器中却不行。我需要找到某种方法能够将其静默传递给控制器​​(无需在控制器中添加额外代码)
    【解决方案3】:

    从 PHP 5.3 开始,您可以使用 static 关键字来实例化一个类

    abstract class singleton
    {
        /**
         * Holds an insance of self
         * @var $instance
         */
        protected static $instance = NULL;
    
        /**
         * Prevent direct object creation
         */
        final private function  __construct() { }
    
        /**
         * Prevent object cloning
         */
        final private function  __clone() { }
    
        final public static function getInstance()
        {
            if(null !== static::$instance){
                return static::$instance;
            }
            static::$instance = new static();
            return static::$instance;
        }
    }
    
    class myclass extends singleton
    {
    }
    
    $myclass = myclass::getInstance();
    

    【讨论】:

    • 问题不在于我需要实例化类,我需要将一个对象“添加”到已经实例化的类中。 Acontroller 是由Controller 加载的,但随后Acontroller 需要加载Amodel。我可以将 Amodel 加载到 Controller,但我需要 Acontroller 可以访问它
    猜你喜欢
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多