PHP splbean,PHP_easymvc: PHP_easymvc 是 基于composer 搭建自己的mvc练习,本人是个小白。参考easyswoole(传送门) 和thinkphp5(传送门...

mymvc

项目介绍

基于composer 搭建自己的mvc练习,本人是个小白。参考easyswoole(传送门) 和thinkphp5(传送门)通过composer来练习搭建自己的mvc框架,没有考虑性能,都是凭感觉弄得。有什么建议可以发送给邮箱327907762@qq.com

命名规范

类库、函数文件统一以.php为后缀;

类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;

类名和类文件名保持一致,统一采用驼峰法命名(首字母大写);

1、入口文件

用户发起的请求都会经过应用的入口文件,通常是 public/index.php文件。当然,你也可以更改或者增加新的入口文件。

通常入口文件的代码都比较简单,一个普通的入口文件代码如下:

// 应用入口文件

define(__ROOT__, __DIR__ . '/');

define(__CONFIG__, __DIR__ . '/Data/Config/');

define(__EXECL_READER__, __ROOT__ . "/App/System/Component/Execl/Reader/");

require_once 'vendor/autoload.php';

use App\System\App;

App::run()->send();

一般入口文件以定义一些常量为主;

2、引导文件

self::init (); // 初始化加载配置

self::registerWhoops ();// 注册whoops来捕捉框架的异常

self::checkPhpVersion ();// 检测php版本

self::initCommon ();// 初始化公共信息

self::registerDi ();// 注册Di的依赖

self::registerRoute ();// 注册路由 // 清空实例化的

路由

通过fastRoute开发的路由,并且支持fastRoute所有方式,并且项目支持无限路由。该类允许您直接将其投入项目并立即开始使用。模块/控制器/操作这是默认的分发请求机制,系统会根据URL或者路由地址来判断当前请求的模块、控制器和操作名,并自动调用相应的访问控制器类,执行操作对应的方法。

简单的路由重写

class Router extends RouterInterface

{

function register(RouteCollector $routeCollector)

{

// TODO: Implement register() method.

// 路由拦截若未执行end,请求还会继续进入系统自带的控制器路由匹配

$routeCollector->get('/register', '/Api/Common/register');

// /loginIndex/1.html

$routeCollector->get('/loginIndex/{id:\d+}', '/Api/Login/index');

// /loginIndex/1/jll.html

$routeCollector->get('/loginIndex/{id:\d+}/{name:\d+}', '/Api/Login/index');

$routeCollector->get('/checkIsLogin', '/Api/Common/checkIsLogin');

$routeCollector->get('/getFriendRequests', '/Api/Friend/getFriendRequests');

$routeCollector->get('/dealFriendRequest', '/Api/Friend/dealFriendRequest');

$routeCollector->get('/getFriendList', '/Api/Friend/getFriendList');

// 测试URL /a

$routeCollector->get('/a', function (Request $request, Response $response) {

$response->write('this is write by router with not end ');

$response->response();

});

// 测试URL /a2

$routeCollector->get('/a2', function (Request $request, Response $response) {

$response->write('this is write by router2 with end ');

$response->response();

});

$routeCollector->post('/a3', function (Request $request, Response $response) {

$response->write('this is write by router2 with end ');

$response->response();

});

// /user/1/index.html

$routeCollector->get('/user/{id:\d+}', function (Request $request, Response $response, $id) {

$response->write("this is router user ,your id is {$id}");

$response->response();

});

}

public function getMethodNotAllowCallBack()

{

/*

* //需要处理逻用回调函数

* return function () {

* echo 111;

* };

*/

return null;

}

}

错误机制

错误捕捉通过Whoops插件

Whoops 是一个PHP库能够很容易处理错误和进行代码调试。该库提供了基于堆栈的错误处理,并提供一个好看的错误界面

数据库

MysqliDb -- Simple MySQLi wrapper and object mapper with prepared statements

基于easyswoole的spl库可以像java一样封装自己的bean

f06b6f4451098c42791497249ef6c647.png

namespace App\Model\Setting;

use App\System\Component\Spl\SplBean;

class SettingBean extends SplBean

{

protected $key;

protected $value;

/**

* @return the $key

*/

public function getKey()

{

return $this->key;

}

/**

* @return the $value

*/

public function getValue()

{

return $this->value;

}

/**

* @param field_type $key

*/

public function setKey($key)

{

$this->key = $key;

}

/**

* @param field_type $value

*/

public function setValue($value)

{

$this->value = $value;

}

}

模板解析

Twig是一个灵活、高效并且安全的PHP模板引擎。

如果你使用过Smarty、Django或者Jinja这类基于文本的模板引擎的话,那么你会觉得Twig是很自然而然的事情。Twig严格遵守了PHP的信念,同时增加了在模板环境中很有用的函数,这些做法使得Twig不论是对设计师还是开发人员,都是非常友好的。

Twig的主要特征有:

高效:Twig将模板编译成了优化了的PHP文件,与原生的PHP代码比较而言,性能损耗非常小。

安全:Twig使用沙箱(sandbox)模式去运行模板中不被信任的代码。这使得我们可以选择Twig作为那些允许用户修改模板的应用的模板引擎。

灵活:Twig具有灵活的语法分析器和语法解析器,它允许开发人员定义自己的标签(tags)和过滤器(filters),并且创建自己的领域特定语言(DSL,domain specific language)。

模仿easyswoole遵循psr7的Response和Request类,在路由的之前通过DI容器注入,DI容器采用easyswoole的代码很好用。

依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)。

控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。

依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。

IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。

static function registerDi() {

$config = self::$config;

// 通过DI 注入数据库$db = Di::getInstance()->get('mysql');

Di::getInstance ()->set ( 'mysql', MysqliDb::class, Array (

'host' => $config ['database'] ['host'],

'username' => $config ['database'] ['username'],

'password' => $config ['database'] ['password'],

'db' => $config ['database'] ['db'],

'port' => $config ['database'] ['port'],

'charset' => $config ['database'] ['charset'],

'prefix' => $config ['database'] ['prefix']

) );

// 通过DI 注入数据库视图 $twig = Di::getInstance()->get('twig');

Di::getInstance ()->set ( 'twig', TwigView::class, Array (

'config' => $config ['view']

) );

}

很感谢easyswoole的博主

通过他的easyswoolemvc让我更好的理解和规范的写出良好的的代码。

这是mvc的控制层的抽象层的实现。所有的controller实现类都写在如下图

23dfdbfc5e11f39c85569353a6fd6a79.png

namespace App\System\Http\AbstractInterface;

use App\System\Http\Message\Status;

use App\System\Http\Request;

use App\System\Http\Response;

use App\System\Component\View\TwigView;

use App\System\Component\Di;

abstract class Controller

{

private $actionName;

private $request;

private $response;

abstract function index();

public function __construct(string $actionName, Request $request, Response $response)

{

$this->request = $request;

$this->response = $response;

$this->actionName = $actionName;

if ($actionName == '__hook') {

$this->response()->withStatus(Status::CODE_BAD_REQUEST);

} else {

$this->__hook($actionName);

}

}

protected function actionNotFound($action): void

{

$this->response()->withStatus(Status::CODE_NOT_FOUND);

}

protected function afterAction($actionName): void

{}

protected function onException(\Throwable $throwable, $actionName): void

{

throw $throwable;

}

protected function onRequest($action): ?bool

{

return true;

}

protected function getActionName(): string

{

return $this->actionName;

}

protected function resetAction(string $action): void

{

$this->actionName = $action;

}

protected function __hook(?string $actionName): void

{

if ($this->onRequest($actionName) !== false) {

$actionName = $this->actionName;

// 支持在子类控制器中以private,protected来修饰某个方法不可见

$ref = new \ReflectionClass(static::class);

if ($ref->hasMethod($actionName) && $ref->getMethod($actionName)->isPublic()) {

try {

$this->$actionName(); // 这里面会重复执行

$this->afterAction($actionName);

} catch (\Throwable $exception) {

$this->onException($exception, $actionName);

}

} else {

throw new \Exception(static::class . "中没有找到" . $actionName);

}

} else {

throw new \Exception("没有权限访问" . $actionName);

}

}

protected function request(): Request

{

return $this->request;

}

protected function response(): Response

{

return $this->response;

}

protected function writeJson($statusCode = 200, $result = null, $msg = null)

{

$data = Array(

"code" => $statusCode,

"result" => $result,

"msg" => $msg

);

$this->response()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));

$this->response()->withHeader('Content-type', 'application/json;charset=utf-8');

$this->response()->withStatus($statusCode);

}

protected function twig(): TwigView

{

return Di::getInstance()->get('twig');

}

/**

* * 浏览器友好的变量输出 * @param mixed $var 变量 * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串 * @param string $label 标签 默认为空 * @param boolean $strict 是否严谨 默认为true * @return void|string

*/

/**

* 浏览器友好的变量输出

*

* @param mixed $var

* 变量

* @param boolean $echo

* 是否输出 默认为True 如果为false 则返回输出字符串

* @param string $label

* 标签 默认为空

* @param boolean $strict

* 是否严谨 默认为true

* @return void|string

*/

protected function getNameSpace()

{

return self::class;

}

function __destruct()

{

$this->response->response();

}

}

控制器层的代码实现

namespace App\HttpController\Index;

use App\System\Http\AbstractInterface\Controller;

use App\Model\Setting\SettingModel;

class Index extends Controller {

public function index() {

$this->response()->withHeader('Content-type', 'text/html; charset=gbk;');

$this->response()->withHeader('X-Powered-By', 'PHP/6.0.0');

echo "

";

var_dump(1111);

echo "

";

$this->twig ()->assign ( "aaaa", "111" );

$this->twig ()->assign ( "navigation", [

"aaaaa",

"bbbbb",

"ccccc"

] );

$this->twig ()->assign ( "navigation2", (new SettingModel ())->getSettings () );

$re = $this->twig ()->getTempLate ( "index" );

$this->response ()->write ( $re );

}

protected function onRequest($action): ?bool {

return true;

}

protected function afterAction($actionName): void {

}

}

模拟POST与GET请求 httpcurl 支持文件上传等

HttpCurl::request('http://example.com/', 'post', array(

'user_uid' => 'root',

'user_pwd' => '123456'

));

高效的execl操作比传统的phpexecl要写,虽然没有phpexecl灵活。但是满足基本的execl操作

1568cd56221df4119090d7e8450a5841.png

剩下会更加丰富自己的mvc框架,在逐渐考虑性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值