使用命名空间自动加载,难以理解范围和继承
Autoloading using Namespaces, trouble understanding scope and inheritence
背景
我正在尝试从头开始构建我自己的个人 MVC 框架以用于我自己的教育......为了帮助解决这个问题,我已经将框架剥离到一个极其简化的水平。
这里是存储库:https://github.com/JethroHazelhurst/psr-4-mvc
我正在使用 PSR-4 标准自动加载 classes,因此我的命名空间遵循我的目录结构。
我目前有什么
这是我的目录结构
在我的索引页面上,我有我的自动加载器并正在实例化一个 Core\Router class。
<?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 class 我有两个函数,第一个:
- 实例化 \App\Controllers\Everest 控制器。
- 调用父 'Master' 控制器中的 loadModel() 函数
第二个:
- 在实例化的 'Everest' 控制器中调用一个动作 (about())
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 控制器中 class 我有一个父构造函数和一个方法。
<?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');
}
}
在所有其他控制器继承的我的 'Master Controller' 中,我实例化了一个新的主控 'View' class。这个主控制器就是'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;
}
}
}
问题和错误
我很难理解对象和 classes 如何在框架内交互,甚至提出一个问题对我来说也很困难。
我遇到了这个错误
问题
为什么会出现此错误?
我个人认为这是因为我的所有控制器与其父控制器 (Core) 位于不同的命名空间 (App\Controllers) 中。
如果事实确实如此,那么让这个东西正常工作的最佳方法是什么?
非常感谢你们这些优秀的 PHPer!
** 更新 **
下面的答案是解决方案。您可以在此处使用非常简单的数据库包装器查看更新后的代码:https://github.com/JethroHazelhurst/psr-4-mvc
好的,我试试你的代码...我不会评论你的代码,我会提供你的答案:
到 class 控制器,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;
}
}
}
如果你愿意,我可以对你的存储库进行一些合并请求,以进行一些修改,这对你有帮助
背景
我正在尝试从头开始构建我自己的个人 MVC 框架以用于我自己的教育......为了帮助解决这个问题,我已经将框架剥离到一个极其简化的水平。
这里是存储库:https://github.com/JethroHazelhurst/psr-4-mvc
我正在使用 PSR-4 标准自动加载 classes,因此我的命名空间遵循我的目录结构。
我目前有什么
这是我的目录结构
在我的索引页面上,我有我的自动加载器并正在实例化一个 Core\Router class。
<?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 class 我有两个函数,第一个:
- 实例化 \App\Controllers\Everest 控制器。
- 调用父 'Master' 控制器中的 loadModel() 函数
第二个:
- 在实例化的 'Everest' 控制器中调用一个动作 (about())
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 控制器中 class 我有一个父构造函数和一个方法。
<?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');
}
}
在所有其他控制器继承的我的 'Master Controller' 中,我实例化了一个新的主控 'View' class。这个主控制器就是'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;
}
}
}
问题和错误
我很难理解对象和 classes 如何在框架内交互,甚至提出一个问题对我来说也很困难。
我遇到了这个错误
问题
为什么会出现此错误?
我个人认为这是因为我的所有控制器与其父控制器 (Core) 位于不同的命名空间 (App\Controllers) 中。
如果事实确实如此,那么让这个东西正常工作的最佳方法是什么?
非常感谢你们这些优秀的 PHPer!
** 更新 **
下面的答案是解决方案。您可以在此处使用非常简单的数据库包装器查看更新后的代码:https://github.com/JethroHazelhurst/psr-4-mvc
好的,我试试你的代码...我不会评论你的代码,我会提供你的答案:
到 class 控制器,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;
}
}
}
如果你愿意,我可以对你的存储库进行一些合并请求,以进行一些修改,这对你有帮助