使用命名空间自动加载,无法理解范围和继承

时间:2016-07-03 20:33:54

标签: php oop model-view-controller frameworks psr-4

背景

我正在尝试从头开始构建我自己的个人MVC框架以用于我自己的教育......对于这个问题的帮助我已经将框架剥离到极其简化的级别。

以下是存储库:https://github.com/JethroHazelhurst/psr-4-mvc

我使用PSR-4标准自动加载类,所以我的命名空间遵循我的目录结构。

到目前为止我有什么

这是我的目录结构

enter image description here

在我的索引页面上,我有自动加载器并正在实例化Core \ Router类。

<?php

spl_autoload_register(function ($class) {
    $root = dirname(__DIR__);   // directory - e.g. http://www.example.com
    $file = $root . '/' . str_replace('\\', '/', $class) . '.php'; // adds a leading slash and replaces '\' with '/'
    // checks if the file exists and is readable
    if (is_readable($file)) {
        require $file; // if it is then the file is required
    }
});

$mountain = new Core\Router;

$mountain->instantiateController();
$mountain->callAction();

在我的Core \ Router类中,我有两个函数,第一个:

  1. 实例化\ App \ Controllers \ Everest控制器。
  2. 调用父级“Master”Controller
  3. 中的loadModel()函数

    第二个:

    1. 在实例化的'Everest'控制器中调用一个动作(about())
    2. Namespace Core;
      
      class Router
      {
          public function instantiateController()
          {
              $this->_controller = new \App\Controllers\Everest(); // hard coded
              $this->_controller->loadModel('Sherpas'); // hard coded
          }
      
          public function callAction()
          {
              $this->_controller->about(); // hard coded
          }
      }
      

      接下来,在我的Everest控制器类中,我有一个父构造函数和一个方法。

      <?php
      
      Namespace App\Controllers;
      
      class Everest extends \Core\Controller
      {
          public function __construct()
          {
              parent::__construct();
          }
      
          public function about()
          {
              $this->view->test = $this->model->hello();
              $this->view->render('AboutEverest');
          }
      }
      

      在我的“主控制器”中,所有其他控制器继承我实例化一个新的主“视图”类。该主控制器是'loadModel()函数所在的位置。

      <?php
      
      Namespace Core;
      
      class Controller
      {
          public function __construct()
          {
              $this->view = new View;
          }
      
      
      
          public function loadModel($name)
          {
              $path = '../App/Models/' . $name . '_Model.php';
      
              if (file_exists($path)) {
      
                  require $path;
      
                  $modelName = '\App\Models\Sherpas_Model';
      
                  $model = new $modelName;
                  return $model;
              }
          }
      }
      

      问题和错误

      我很难理解对象和类如何在框架内进行交互,甚至为我制定问题也很困难。

      我收到此错误

      enter image description here

      问题

      为什么我收到此错误?

      我个人认为这是因为我的所有控制器都在与其父控制器(Core)不同的命名空间(App \ Controllers)中。

      如果事实确实如此,那么让这件事发挥作用的最佳方法是什么?

      非常感谢您精彩的PHPers!

      **更新**

      以下答案是解决方案..您可以使用非常简单的数据库包装器在此处查看更新的代码:https://github.com/JethroHazelhurst/psr-4-mvc

1 个答案:

答案 0 :(得分:1)

好的,所以我试试你的代码......我不会评论你的代码,我会提供你的答案:

到类Controller,Core\Controller.php你需要添加受保护的属性模型,并在loadModel方法中将你的新模型保存到这个属性

class Controller
{
    protected $model;

    public function __construct()
    {
        $this->view = new View;
    }



    public function loadModel($name)
    {
        $path = '../App/Models/' . $name . '_Model.php';
        if (file_exists($path)) {

            require $path;

            $modelName = '\App\Models\Sherpas_Model';

            $model = new $modelName;
            $this->model = $model;
        }
    }
}

如果您愿意,我可以对您的存储库执行一些合并请求,以进行一些可以帮助您的修改