0

我正在尝试创建一个小框架。我目前正忙于我的调度程序对象,我无法从逻辑上制定关于调度程序应如何绑定控制器并请求视图/操作的最佳实践。

到目前为止一切正常,我可以创建带有动作的页面控制器并执行 echo "test123";完美返回,我只是对如何构建视图以及如何让视图访问控制器中分配的变量感到有点困惑。我添加了一些评论,我觉得我可能会采取错误的方法。

一些让我烦恼的项目: - 我不太认为我在 require_once() 和在 dispatch() 方法中创建对象实例方面采取了正确的方法,但我不确定哪个其他选项会起作用。- 我试图确保用户通过请求的 url、引用的 url 或最后的默认控制器/操作获得某种输出,以便我可以在网站的模板中显示简化的错误消息,但我也觉得我可能在重复工作,有什么想法吗?- 我看不到如何绑定视图控制器(它将输出 HTML)。我将在哪里分配控制器中生成的变量或值?

注意事项:

  • 调度程序不扩展任何其他类。
  • 选定的页面控制器将扩展主控制器,而主控制器反过来又扩展到核心控制器。我认为核心控制器将捆绑我想在应用程序之间共享的所有其他类,如数据库类等,但我不确定这是否有意义。

任何关于如何改进我的调度员的想法将不胜感激!

 public function dispatch($user_request) {
    // Receive the user requested controller/action in an array:
    $this->requested_array = $user_request;
    $request_validated = false;
    // Ensure the master controller is available or break gracefully:
    if(!include(CONTROLLERS_DIR."master".CONTROLLER_SUFFIX.".php")) {
        output_message("Unable to load the master controller.", true);
        return false;
    }

    // Verify if the requested controller is available and that it is indeed a class:
    if(file_exists(CONTROLLERS_DIR.$this->requested_array['controller'].CONTROLLER_SUFFIX.".php")) {
        require_once(CONTROLLERS_DIR.$this->requested_array['controller'].CONTROLLER_SUFFIX.".php");
        if(class_exists($this->requested_array['controller'])) {
            // Create object of requested controller:
            $requested_controller_object = new $this->requested_array['controller']();
            // Verify that the requested action/method exists in the controller:
            if(method_exists($requested_controller_object, $this->requested_array['action'])) {
                $request_validated = true;
            }
        }

    } else {
        $this->dispatcher_errors[] = "Unable to locate the requested controller.";
    }

    if($request_validated != true) {
        // Rollback will check if the page has a successful referrer (same application) and assign the previous pages controller/action properties to this request:
        if($this->rollback() != true) {
            // Check if the default controller exists and if it is a class:
            if(file_exists(CONTROLLERS_DIR.$this->default_request_array['controller'].CONTROLLER_SUFFIX.".php")) {
                require_once(CONTROLLERS_DIR.$this->default_request_array['controller'].CONTROLLER_SUFFIX.".php");
                if(class_exists($this->default_request_array['controller'])) {
                    $requested_controller_object = new $this->default_request_array['controller']();
                    if(!method_exists($requested_controller_object, $this->default_request_array['action'])) {
                        // Verify if the default action exists in the default controller:
                        output_message("Unable to load the default action.", true);
                        return false;
                    }
                }
            } else {
                output_message("Unable to load the default controller.", true);
                return false;
            }
        } else {
            require_once(CONTROLLERS_DIR.$this->requested_array['controller'].CONTROLLER_SUFFIX.".php");
            $requested_controller_object = new $this->requested_array['controller']();
        }   
    // All systems go, create session variables to save this as the referring url:
    $this->process_referring_url();
    $requested_controller_object->{$this->requested_array['action']}();
    /*
     *  Layout happens here, but how? Should I extend my views class with dispatcher or do I create a views object? 
     * If so, how do I make sure my views will be able to get access to assigned variables from my controllers? 
     * Also, a method like $this->assign("variable_name",$value), in which class do I need to add this method as
     * it feels out of place in the dispatcher and the controller does not have access to the views object.
     */

    }
    return true;
}
4

1 回答 1

0

不久前,我开始为自己的教育目的构建一个小型 php 框架。它最终受到 zend 框架的严重影响。也许看看一些已建立的想法框架。我对您发布的内容的 2c:

我不太认为我对 require_once() 采取了正确的方法并在 dispatch() 方法中创建对象实例

您可以使用 spl_autoload_register 注册一个自动加载函数来自动加载您的类并避免在调度程序中显式调用 require 。我认为在调度程序中实例化你的对象很好。

我看不到如何绑定视图控制器(它将输出 HTML)。我将在哪里分配控制器中生成的变量或值?

我的控制器的构造函数接受了一个包含所有 http 请求变量的请求对象、一个用于填充响应的操作的响应对象(无论是 HTML、Json 等)以及一个包含会话信息和任何其他配置数据的会话对象. 如果您有一个单独的视图控制器或需要多个控制器,您可以将控制器排队并在一个循环中分派,将带有所有必需变量的公共请求对象传递给它们。尽管每个请求只有一个控制器,但我保持简单。

任何关于如何改进我的调度员的想法将不胜感激!

您可以考虑使用在调度之前检查的控制器/操作白名单和黑名单,以便您更好地控制哪些请求得到满足。

于 2012-12-23T04:25:44.897 回答