命名空间
当没有命名空间的时候写的代码都相当于在同一个命名空间之下,是不能出现重复的命名类和相同名称的方法.
当没有命名空间时
创建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
自动加载
通过命名空间的示例可以看出每当使用一个类的时候都需要使用require
或include
引入文件才能使用.当文件依赖多个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规范
- 命名空间必须与绝对路径一致.
- 类名首字母大写
- 除入口文件,其他php必须只有一个类
- php类文件必须自动载入
- 单一入口
登录控制器
创建登录控制器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();
汝之秀,吾何时能及?⌇●﹏●⌇
真还是有点牛逼的.ヾ(≧∇≦*)ゝ
差得远呢