【问题标题】:PHP - Proper way to extend classPHP - 扩展类的正确方法
【发布时间】:2012-05-28 01:20:11
【问题描述】:

我目前正在研究一个迷你“框架”,但遇到了一些困难。我正在尝试这样做是为了加强我对大多数 MVC 中使用的基本概念的理解(至少从我所见)。所以,是的,我明白使用框架可能更容易,而且我所做的一切都不是理想的。我只是想了解更多。

所以我目前正在处理 2 个文件。

FrontController.php

<?php   
class FrontController {
    public function __construct() {
        $this->go(); // RUNS GO FUNCTION UPON LOADING
    }

    public function go() {          
        $url = $_SERVER['REQUEST_URI']; // GRABS URL
        $action = explode("/", $url); // SPLITS UP URL INTO SECTIONS

        $object = ucfirst($action[2]) . "Controller"; // SETS 2ND SECTION OF URL TO UPPERCASE AND IDENTIFIES THE CONTROLLER
        $file = APP_DIR . "/" . $object . ".php"; // IDENTIFIES THE FILE THAT WILL BE USED

        if(!is_file($file)){ // DETERMINES IF FILE EXISTS
            $this->fail(); // IF NOT, FAILS
        } else {
            require_once $file; // IF EXISTS, PULLS IT IN
            $method = ucfirst($action[3]); // THE 3RD SECTION OF THE URL IS THE METHOD
            $controller = new $object(); // CREATE INSTANCE OF THE IDENTIFIED OBJECT

            if(!method_exists($controller, $method)){ // DETERMINES IF METHOD EXISTS IN THE CLASS
                $this->fail(); // IF NOT, FAILS
            }

            $controller->$method(); // RUN METHOD
            exit(0);
        }
    }

    public function fail() {
        echo "<h1>Failure</h1>"; // FAILURE MESSAGE
    }
}

/application/BaseController.php

<?php   
class BaseController {
    public function __construct() {
        $this->session();
    }

    public function session() {
        session_start();
        $_SESSION['is_logged_in'] = 1;
        echo "hi";
    }
}

所以我想做的是用 FrontController 扩展 BaseController。我认为扩展 BaseController 可以让我向整个应用程序添加通用功能。问题是我不确定如何正确执行此操作。我知道我需要以某种方式将 BaseController.php '要求'到 FrontController.php 中,但我见过很多不同的方法,我想知道哪种方法最正确。

我尝试过的只是添加 'require_once("/application/BaseController.php");'到 FrontController.php 的顶部,然后扩展 FrontController 类,但这不起作用(空白页),从我读过的内容来看,这不是最好的方法。

我阅读了 __autoload() 但我不明白如何有效地使用它。我只是把它放在我的 FrontController.php 文件的顶部,然后扩展我的类吗?

所以,总而言之,我想用我的 BaseController 扩展我的 FrontController 类(以及其他未来的类,如有必要)。我只是想要一些关于如何有效完成这项任务的建议。甚至有可能我的想法是倒退的,如果是这样,请告诉我!!

【问题讨论】:

    标签: php oop class extend


    【解决方案1】:

    你扩展类如:

    <?php
    class FrontController extends BaseController {
     ..code...
    }
    
    
    ?>
    

    __autoload 是一种自动加载类的神奇方法。因此,您可以将其添加到您的 FrontController 作为示例,并根据需要加载您的控制器。在此处阅读有关自动加载类的信息:

    http://php.net/manual/en/language.oop5.autoload.php

    此外,利用 PHP 中的 SPL,这将有助于更好地定义您的应用程序。

    【讨论】:

    • 那么这会超出 FrontController.php 文件中的实际类吗?这不会使它对我的需求毫无用处吗?它只会用于这个单一的实例。我不确定如何实现它以便可以重复使用。
    • 无论哪个类处理路由,您都可以在其中添加自动加载。不过,您的 go 方法似乎已经在这样做了。 __autoload 只是一个辅助方法,很像 _set 和 _get。它们自动化了开发人员多年来手动处理的问题。
    • 我会查看 CodeIgniter 之类的框架,看看它们如何处理加载类。
    • 我还应该注意,框架通常使用加载类,您的控制器会启动该类。然后所有子类也可以访问该加载类以使用。
    • 我想这回答了我的问题,但我仍然觉得有些事情对我来说是未知的。这没有什么可以帮助的,我感谢你的努力。谢谢。
    【解决方案2】:

    为了更好地构建您的框架和您未来的项目,我建议您使用一些技巧和最佳实践。

    • 命名空间:为了更好地组织代码和类
    • 自动加载:以智能方式自动加载您的类

    命名空间http://php.net/manual/en/language.namespaces.php和自动加载http://php.net/manual/en/language.oop5.autoload.php可以在官方文档中查看。

    为了更好的理解你可以看看这里

    1. 定义和注册自动加载函数

      function autoload($class) {
          preg_match('/^(.+)?([^\\\\]+)$/U', ltrim( $class, '\\' ), $match ) );
          require str_replace( '\\', '/', $match[ 1 ] ). str_replace( [ '\\', '_' ], '/', $match[ 2 ] ). '.php';
      }
      
      spl_autoload_register('autoload');
      
    2. 在应用程序周围使用命名空间

    基本控制器

        <?php namespace App\Controller;
    
        class BaseController { ... }
    

    前端控制器

        <?php namespace App\Controller;
        use App\Controller\BaseController as BaseController;
    
        class FrontController extends BaseController { ... }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 2023-04-01
      • 1970-01-01
      • 2013-06-14
      • 2011-05-28
      • 1970-01-01
      • 2011-11-13
      相关资源
      最近更新 更多