在PHP控制器中调用模型功能的最佳选择

Mat*_*ood 4 php oop model-view-controller dependency-injection

我正在使用PHP构建自定义MVC框架.我的问题是当我想通过控制器类访问任何模型类时.我看到这样做的一种方法是通过使用魔术方法(如get和set)的注册表设计模式,尽管PHP get和set被一些人认为是不好的做法.我已经读过通过容器完成的依赖注入,但是我不能看到它有效地工作,因为容器必须调用模型,否则它必须包含会破坏MVC目的并创建大型超类的模型.单身人士被视为不良做法.我提到的方法是否有任何解决方案或改进.这可能只是我对PHP需求改进的理解和了解.

目前我有这个:router.php(通过GET变量加载控制器

 <?php

class router {



function __construct() {

    if (file_exists("controller/".$_GET['url']."Controller.php"))  {


       function __autoload($controller) {

           $controlinclude = "controller/".$controller.".php";
            include $controlinclude;

      }
       $control = $_GET['url']."Controller";
        new $control();


    }
    else    {

        // throw exception
    }

}

}
?>
Run Code Online (Sandbox Code Playgroud)

希望这样做

ter*_*ško 5

首先......不要在路由机制中放置自动加载脚本.你正在混合责任.你最好为此创建一个单独的类spl_autoload_register.

Neeext ..不要在构造函数上放置复杂的操作.它使你的代码有点不可测试.也许你应该是这样的:

// you might want to replace $_GET with $_SERVER['QUERY_STRING'] later
$router = new Router( $_GET['url'] );

// where 'default' is the name of fallback controller
$controller_class = $router->get_controller( 'default' );
$method_name = $router->get_action( 'index' );

$model_factory = new ModelFactory( new PDO( ... ) );
$controller = new {$controller_class}( $model_factory );
$controller->{$method_name}();
Run Code Online (Sandbox Code Playgroud)

另外,你应该研究php 名称空间....Controller只有知道课程所在的位置才能结束课程.

好的......回到模特儿.

关于Web开发社区中的模型存在相当普遍的误解(我将此归咎于RoR).MVC中的模型不是类,而是包含大量实例的应用程序层.大多数实例属于两种类型中的一种.履行以下职责:

  • 域逻辑:

    处理所有计算,计算和所有域特定细节.该组中的对象不知道数据的实际存储位置和方式.他们只操纵信息.

  • 数据访问

    通常由符合DataMapper模式的对象组成(不要与同名的ORM混淆..没有共同之处).负责存储域对象的数据并检索它们.可能在数据库中......可能不会.这是您的SQL查询的位置.

在半现实世界的情况下()它可能看起来像这样(与代码abowe相关):

class SomeController
{
   // ... snip ...
   protected $model_factory = null;
   // ... snip ...

   public function __construct( ModelFactory $factory )
   {
       $this->model_factory = $factory;
   }
   // ... snip ...

   public function action_foobar()
   {
      $user = $this->model_factory->build_object( 'User' );
      $mapper = $this->model_factory->build_mapper( 'User' );

      $user->set_id(42);
      $mapper->fetch($user);

      if ( $user->hasWarning()  )
      {
          $user->set_status( 'locked' );
      }

      $mapper->store( $user );
   }

   // ... snip ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,没有迹象表明数据是如何存储的.如果用户帐户是新帐户或已存在,则无关紧要.

您可能会觉得有些材料很有用

影片

图书: