命名空间

  当没有命名空间的时候写的代码都相当于在同一个命名空间之下,是不能出现重复的命名类和相同名称的方法.

当没有命名空间时

创建Test1.php

<?php

function Angel()
{
    echo 'test_1' . PHP_EOL;
}

创建Test2.php

<?php

function Angel()
{
    echo 'test_2' . PHP_EOL;
}

创建新Test.php

<?php

require 'Test1.php';
require 'Test2.php';
// 执行文件出现重复方法名报错
PHP Fatal error:  Cannot redeclare Angel() (previously declared in /Users/qvbilam/Sites/test/DesignMode/Test1.php:5) in /Users/qvbilam/Sites/test/DesignMode/Test2.php on line 6

Fatal error: Cannot redeclare Angel() (previously declared in /Users/qvbilam/Sites/test/DesignMode/Test1.php:5) in /Users/qvbilam/Sites/test/DesignMode/Test2.php on line 6

使用命名空间后

修改Test1.php

<?php

namespace Test1;

function Angel()
{
    echo 'test_1' . PHP_EOL;
}

修改Test2.php

<?php

namespace Test2;
  
function Angel()
{
    echo 'test_2' . PHP_EOL;
}

使用

  在使用命名空间后要想使用类下面的方法只需要带上命名空间\方法名.

<?php

require 'Test1.php';
require 'Test2.php';

Test1\Angel();
Test2\Angel();
// 执行文件输出
test_1
test_2

自动加载

  通过命名空间的示例可以看出每当使用一个类的时候都需要使用requireinclude引入文件才能使用.当文件依赖多个php类时需要写很多的引入文件.对于管理和维护不是很方便,所以需要自动加载的功能.

  在php5.3之前使用的__autoload()的方式自动加载.而在5.3之后官方提供了新的方法spl_autoload_register()来替代.在7.2后废弃__autoload().使用如下

修改Test1.php

<?php


class Test1
{
    static function Angel()
    {
        echo 'test_1' . PHP_EOL;
    }
}

修改Test2.php

<?php


class Test2
{
    static function Angel()
    {
        echo 'test_2' . PHP_EOL;
    }
}

修改Test.php

<?php
  
spl_autoload_register('MyAutolad');
function MyAutolad($class)
{
    require './' . $class . '.php';
}

Test1::Angel();
Test2::Angel();
// 输出
test_1
test_2

创建框架

PSR-0规范

  1. 命名空间必须与绝对路径一致.
  2. 类名首字母大写
  3. 除入口文件,其他php必须只有一个类
  4. php类文件必须自动载入
  5. 单一入口

登录控制器

  创建登录控制器App/Controller/User/Login.php

<?php

namespace App\Controller\User;
 
class Login
{
    static function success()
    {
        echo '登录成功' . PHP_EOL;
    }
}

自动加载

  创建Tools\Autoloader.php

<?php


namespace Tools;

class Autoloader
{
    static function autoload($class)
    {
        var_dump($class);
    }
}

创建入口文件

  在项目根目录下创建Index.php

<?php

define('QVBILAM_ROOT',__DIR__);

include QVBILAM_ROOT . '/Tools/Autoloader.php';

spl_autoload_register('\\Tools\\Autoloader::autoload');

App\Controller\User\Login::success();
// 执行文件查看autoload打印结果(忽略报错信息)
string(25) "App\Controller\User\Login"
// 输出结果与之前创建的命名空间一样.

完善自动加载

  修改Tools\Autoloader.php.在引入文件需要注意$class打印的是命名空间用的是\,而在引入文件的时候需要将\转换成/.

<?php

namespace Tools;

class Autoloader
{
    static function autoload($class)
    {
        // var_dump($class);
       include QVBILAM_ROOT . '/' . str_replace('\\','/',$class) . '.php';
    }
}

执行index.php

// 输出
登录成功

完善

  将目录配上虚拟域名qvbilam.dev.通过浏览器访问同样能获得结果,现在想通过/控制器名/类名/方法名访问就能自动找到相对应的方法并执行.

核心文件

  创建Tools/Core.php文件.

<?php

namespace Tools;

use function GuzzleHttp\default_user_agent;

class Core
{
    /*
     * 访问方式 /控制器/类/方法
     * https://qvbilam.dev/user/login/success
     * */
    static function run()
    {
        // 去掉开头和结尾的 斜线
        $uri = trim($_SERVER['REQUEST_URI'], '/');
        // 按照斜线将字符串升级为数组. arr[0] = 控制器,arr[1] = 类名,arr[2] = 方法
        $uriArr = explode('/', $uri);
        switch(count($uriArr)){
            case 0:
                // 默认请求
                $uriArr = ['index','index','index'];
                return false;
            case 1:
                header('HTTP/1.1 404 Not Found');
                return false;
            case 2:
                // 追加默认控制器
                array_unshift($uriArr,'index');
                break;
            case 3:
                break;
            default:
                header('HTTP/1.1 404 Not Found');
                return false;

        }
        // 方法名
        $function = $uriArr[2];
        $class = 'App\\Controller\\' . ucwords($uriArr[0]) . '\\' . ucwords($uriArr[1]);
        // 当类不存在返回4040
        if(!class_exists($class)){
            header('HTTP/1.1 400 Bad Request');
            return false;
        }
        // 实例化类
        $obj = new $class;
        // 当方法不存在返回404
        if (!method_exists($obj, $function)) {
            header('HTTP/1.1 400 Bad Request');
            return false;
        }
        // 执行请求方法
        $obj->$function();
    }
}

修改入口文件

<?php

define('QVBILAM_ROOT',__DIR__);

include QVBILAM_ROOT . '/Tools/Autoloader.php';

spl_autoload_register('\\Tools\\Autoloader::autoload');

// App\Controller\User\Login::success();

\Tools\Core::run();

测试

image-20200305015534963.png

image-20200305015601278.png

Last modification:March 7th, 2020 at 12:05 am