使用Composer从零开发一个简单的web框架(04)-控制器

上一章已经获取到了控制器和方法,这一章运行控制器及对应的方法

控制器基类

新建core/Controller.php,内容如下

<?php
namespace core;


class Controller {
    public function __construct($method) {
        $method = $method ?: DEFAULT_METHOD; //如果没有方法则使用默认方法
        define('METHOD', $method);
        $this->{$method}(); //执行控制器类方法
    }
}

应用程序添加控制器

编辑 app/home/controller/Hello.php,内容如下

<?php
namespace app\home\controller;

use core\Controller;


class Hello extends Controller {
    public function index() {
        echo 'Hello.index()';
    }

    public function world() {
        echo 'Hello.world()';
    }
}

新建app/home/controller/Index.php,内容如下

<?php
namespace app\home\controller;

use core\Controller;


class Index extends Controller {
    public function index() {
        echo 'Index.index()';
    }

    public function hi() {
        echo 'Index.hi()';
    }
}

路由绑定控制器

编辑core/App.php文件,修改start函数

// 控制器类文件名大写
$controllerFile = ucfirst($controller);
$module = "app\\{$app}\\controller\\{$controllerFile}";
new $module($method);

测试

浏览器访问 phpweb.com/home/hello/world 或控制台运行 php public/index.php home/hello/world,输出

Hello.world()

浏览器访问 phpweb.com/home/hello 或控制台运行 php public/index.php home/hello,输出

Hello.index()

浏览器访问 phpweb.com/home 或控制台运行 php public/index.php home,输出

Index.index()

浏览器访问 phpweb.com/home/hi 或控制台运行 php public/index.php home/hi,输出

Index.hi()

控制器方法不存在处理

我们需要处理一种情况,当控制器存在,但它的方法不存在时,比如浏览器访问 phpweb.com/home/hello/hi 或控制台运行 php public/index.php home/hello/hi,会输出下面这样的错误信息

Error: Call to undefined method app\home\controller\Hello::hi() in file D:\apps\wamp\www\phpweb\core\Controller.php on line 9
Stack trace:
  1. Error->() D:\apps\wamp\www\phpweb\core\Controller.php:9
  2. core\Controller->__construct() D:\apps\wamp\www\phpweb\core\App.php:95
  3. core\App->start() D:\apps\wamp\www\phpweb\core\App.php:11
  4. core\App->__construct() D:\apps\wamp\www\phpweb\public\index.php:27

这种情况可以当做是正常处理,不存在就报错,也可以调用控制器的index方法,当index方法不存在时再输出错误信息

编辑core/Controller.php,添加__call魔法函数

public function __call($method, $arg) {
    if (DEFAULT_METHOD == $method) {
        header('HTTP/1.1 404 Not Found');
        trigger_error("ERROR! Can't find {$method} in " . get_class($this), E_USER_ERROR);
    } else {
        define('METHOD', DEFAULT_METHOD);
        $this->{DEFAULT_METHOD}();
    }
}

再次浏览器访问 phpweb.com/home/hello/hi 或控制台运行 php public/index.php home/hello/hi,输出

Hello.index()

编辑app/home/controller/Hello.php,删除或注释掉index方法

//    public function index() {
//        echo 'Hello.index()';
//    }

再次浏览器访问 phpweb.com/home/hello/hi 或控制台运行 php public/index.php home/hello/hi,这时会输出我们自定义的错误信息了

Whoops\Exception\ErrorException: ERROR! Can't find index in app\home\controller\Hello in file D:\apps\wamp\www\phpweb\core\Controller.php on line 15
Stack trace:
  1. Whoops\Exception\ErrorException->() D:\apps\wamp\www\phpweb\core\Controller.php:15
  2. trigger_error() D:\apps\wamp\www\phpweb\core\Controller.php:15
  3. core\Controller->__call() D:\apps\wamp\www\phpweb\core\Controller.php:18
  4. core\Controller->__call() D:\apps\wamp\www\phpweb\core\Controller.php:9
  5. core\Controller->__construct() D:\apps\wamp\www\phpweb\core\App.php:95
  6. core\App->start() D:\apps\wamp\www\phpweb\core\App.php:11
  7. core\App->__construct() D:\apps\wamp\www\phpweb\public\index.php:27
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 6

你好,我这边测试 home/hello 方法,是显示:index.index()。

这能区分是 home/hello/index() 还是 home/index/hello() 方法吗?

4个月前 评论
mirahs (楼主) 4个月前
wfdaj (作者) 3个月前
$filename   = PATH_APP . $app . '/controller/' . $controller . '.php';

这里的 $controller 需要首字母大写。ucfirst()

3个月前 评论
mirahs (楼主) 3个月前
mirahs (楼主) 3个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!