SkillAgentSearch skills...

Phpframework

基于mvc设计模式的php框架,单入口的设计,底层组件化的操作,IoC控制实现低耦合。代码简约冗余度小,可读性强,功能稳定可依赖。:rocket:

Install / Use

/learn @fantiq/Phpframework
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<html> <head> <meta http-equiv='content-type' content='text/html;charset=utf-8;'> <title></title> <link rel="stylesheet" type="text/css" href="../vertu/stylesheets/init.css"> </head> <body> <div class='container'> <div class='row' style='margin-top: 10px;'> <div class='col-5 panel' id='side-list-box' style=''> <a class='item on' href='#overview'>概览</a> <a class='item' href='#project'>项目</a> <a class='item' href='#config'>配置文件</a> <a class='item' href='#parse'>路由解析规则</a> <a class='item' href='#controller'>控制器</a> <a class='item' href='#database'>模型/数据库</a> <a class='item' href='#template'>模版</a> <a class='item' href='#components'>组件</a> <a class='item' href='#extend'>扩展</a> </div> <div class='col-18 offset-1'> <a name="overview"></a> <div class='content'> <h1>概览</h1> <h4>1、MVC</h4> 主流的设计模式,分离界面与逻辑,高效的协作开发。 <h4>2、模块化</h4> 采用模块形式组织控制器。解决大型项目文件多、难管理的难题,避免后期迭代文件增多导致代码管理混乱的场面。小项目同样可以采用简单的但模块化的架构组织。 <h4>3、组件式</h4> 框架所有功能都是以组件形式工作,您可以根据自己的需求对各个组件进行改进升华,以适应自己的开发规则,同时可以添加自己的功能组件到框架中,过程简单易用。 <h4>4、易使用</h4> 在控制器以及模型中可以自动的加载所有组件,省去配置、加载等繁琐的操作,一切都是如此简单<span class='tag-def'>$this->组件名</span> <h4>5、高效率</h4> 框架根据php语言的特性,在特定部分采用单例的设计模式以节省内存的使用。采用控制反转(IoC)的设计模式实例化类,以降低模块之间的耦合度。 <h4>6、数据库</h4> 数据库提供了三种操作形式。1 直接执行sql,2 通过连贯操作组合sql语句,3 ORM操作数据库,简单快捷。 <h4>7、安全性</h4> 1、用户发送的数据全部进行初步检测,并且销毁全局数组,防止一句话脚本的攻击<br> 2、提供数据过滤,清除非打印字符,文件名不合法,XSS字符串。让网站免受跨站攻击<br> 3、防止sql注入,数据库在执行前都会对sql字符串进行合法性检测<br> 4、提供数据格式验证组件,对用户提交的数据类型进行检测,防止数据表字段溢出 5、提供验证码以及表单CSRF防御机制,以应对互联网的'洪水'攻击 </div> <a name="project"></a> <!-- 项目 --> <div class='content'> <h1>项目</h1> <h4>创建项目文件夹</h4> 我们创建自己的项目文件夹叫做 <span class='tag-def'>App</span>,然后在文件夹里面创建我们项目需要的各个文件<br> <ul class='folder-lists'> <li><i class='icon-folder-open'></i> App</li> <li class='deep-1'><i class='icon-folder-open'></i> controllers<span class='r'>放置控制器类</span></li> <li class='deep-1'><i class='icon-folder-open'></i> models <span class='r'>放置模型类</span></li> <li class='deep-1'><i class='icon-folder-open'></i> config <span class='r'>放置配置文件</span></li> <li class='deep-1'><i class='icon-folder-open'></i> view <span class='r'>放置模版文件</span></li> <li class='deep-1'><i class='icon-file'></i> index.php <span class='r'>入口文件</span></li> </ul> 其他文件夹用户可自行创建,建议您将项目文件(控制器、模型类、配置文件)与可访问的文件(入口文件、图片、css、js)分开存放,并且设置不同的读写权限。 <h4>入口文件</h4> 入口文件内容仅仅需要下面的三行代码 <pre class='code'> &lt;?php define('APP_PATH', dirname(__DIR__)); // 指定项目文件夹 include dirname(__DIR__).'/src/App.php'; // 加载框架入口文件 App::run(); // 执行框架 </pre> <h4>配置</h4> 设置你的配置文件 参照这里 <a href='#config'>配置文件</a> </div> <a name="config"></a> <div class='content'> <h1>配置</h1> <h4>配置文件</h4> 下面是配置文件夹的内容: <ul class='folder-lists'> <li><i class='icon-folder-open'></i> config</li> <li class='deep-1'><i class='icon-file'></i> configs.php<span class='r'>核心配置文件</span></li> <li class='deep-1'><i class='icon-file'></i> rules.php<span class='r'>表单自动验证定义的规则</span></li> <li class='deep-1'><i class='icon-file'></i> hooks.php<span class='r'>定义的钩子程序</span></li> <li class='deep-1'><i class='icon-file'></i> datas.php<span class='r'>自定义的配置参数</span></li> </ul> 具体请参阅源代码中configs.php文件的注释 <h4>主配置文件</h4> <pre class='code'> &lt;?php return [ // 全局的应用程序配置项 'application'=>[ 'id'=>'app', // 应用程序的id,项目的命名空间会用到 'timezone'=>'RPC', // 设置时区 'hooks'=>['file'=>'config/hooks.php','class'=>'Hooks'], // 指定钩子程序的位置 ], // 路由配置 // 'router'=>[ // 0 自动识别url // 1 ?m=Admin&c=Access&a=login&arg1=1.... // 2 Admin/Access/login/arg1/arg2... // 3 ?r=Admin/Access/login/arg1/arg2... // 4 'urlmode'=>0, 'defaultController'=>'Index', // 默认控制器 'defaultAction'=>'index', // 默认方法 'modules'=>['Api/WeiXin','Admin'], // 存在的模块名 'regex'=>[ // 正则匹配url规则 'pattern'=>'Index', ], ], // 数据库配置 'database'=>[ // 'dsn'=>'pdo-mysql://root@127.0.0.1/test', 'dsn'=>'mysql://root@127.0.0.1/test', // dsn形式 'scheme'=>'pdo-mysql', // 数据库类型(pdo类型的要以 pdo-模型 的形式指定) 'host'=>'127.0.0.1', // 地址 'port'=>3306, // 端口 'dbname'=>'test', // 数据库名称 'user'=>'root', // 帐号 'passwd'=>'321321', // 密码 'charset'=>'utf8', // 数据表编码 'prefix'=>'' // 数据表前缀 ], // 内存缓存 'cache'=>[ 'dsn'=>'memcache://127.0.0.1:11211', // dsn字符串形式定义 'scheme'=>'memcache', // 缓存类型 'host'=>'127.0.0.1', // 地址 'port'=>11211, // 端口 ], // session 'session'=>[ 'auto_start'=>false, // 自动加载 'passwd'=>'321321', // 连接store的密码 // 'dsn'=>'pdo-mysql://root:@127.0.0.1:3306/session/sess_tab', 'dsn'=>'memcache://127.0.0.1:11211', // 字符串形式 'scheme'=>'pdo-mysql', // 存储session数据库的模型 'host'=>'127.0.0.1', // 地址 'port'=>3306, // 端口号 'user'=>'root', // 用户名 'dbname'=>'session', // 存储session的数据库名称 'tbname'=>'sess_tab', // 存储session的数据表名称 'charset'=>'utf8', // 编码方式 'prefix'=>'', // 表前缀 'sess_name'=>'__SESSIONID__', 'sess_expire'=>3600*24, // 默认session过期时间 'alive_time'=>3600, // 用户活跃时间间隔 这个时间内没有任何操作视为下线 'cookie_path'=>'/', // cookie 路径 'cookie_domain'=>'', // cookie 域名 ], // 模版配置 'view'=>[ 'drive'=>'template', // 模板引擎 'skin'=>'default', // 默认皮肤 'tpl_ext'=>'php', // 模版文件后缀 'form_hash_name'=>'__hash__', // 表单hash字段名 'form_hash_keys'=>'fantasy', // 表单hash的key ], ///////////// // 加载用户数据 // ///////////// 'datas'=>include 'datas.php', 'alias'=>[], ]; </pre> <h4>钩子程序</h4> 默认的钩子程序是在 项目文件夹/config/hooks.php,你也可以在配置文件中指定其他的文件作为钩子程序。 <table class='table'> <tr class='title'> <th>#</th> <th>方法名</th> <th>作用</th> </tr> <tr> <td>1</td> <td>preSystem</td> <td>框架初始化之后调用执行</td> </tr> <tr> <td>2</td> <td>preRoute</td> <td>在路由解析url之前调用</td> </tr> <tr> <td>3</td> <td>preController</td> <td>在url解析之后,调用执行指定的控制器之前调用</td> </tr> <tr> <td>4</td> <td>preResponse</td> <td>在发送内容到用户客户端之前调用</td> </tr> <tr> <td>5</td> <td>endSystem</td> <td>整个交互过程完成之后执行</td> </tr> </table> 钩子程序中的类继承了Base.class 你在钩子程序中是可以调用所有绑定过的组件的,但是你不能修改钩子程序类中的方法名。 <pre class='code'> &lt;?php use framework\base\Base; class Hooks extends Base{ public function __construct(){ $this->preSystem(); } // 框架开始执行之前 初始化之前 public function preSystem(){} // 路由开始解析之前 public function preRoute(){ // echo 'hello'; } // 路由解析之后 调用用户控制器之前 public function preController(){ // echo "你请求的控制器是:".$this->dispatch->getControllerName()."<br>"; // echo "你请求的控制器方法是:".$this->dispatch->getActionName()."<br>"; } //发送内容到用户浏览器之前 public function preResponse(){} 框架结束 public function endSystem(){} } </pre> </div> <a name="parse"></a> <div class='content'> <h1>路由解析规则</h1> 框架支持多种的url风格 <ul> <li><i class='icon-check'></i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?m=模块名&c=控制器名&a=方法&args....</li> <li><i class='icon-check'></i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /模块名/控制器名/方法/args....</li> <li><i class='icon-check'></i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?r=模块名/控制器名/方法/args....</li> </ul><br> 模块名是为了指明你的控制器所在的文件夹目录,未指定则指定是 <span class='tag-def'>项目/controllers/</span> 这个目录,指定的话需要你事先在配置文件中 <span class='tag-def'>['router']['modules'] => [模块1,模块2,模块3]</span> 声明。指定模块名的话,框架所调用的控制器文件路径就是 <span class='tag-def'>项目/controllers/模块名/</span> 这个目录了。<br> 比如我们需要访问一个控制器,这个控制器文件所在目录路径 App/controllers/Pay/Taobao/CashController.php 如下图: <ul class='folder-lists'> <li><i class='icon-folder-open'></i> App</li> <li class='deep-1'><i class='icon-folder-open'></i> controllers</li> <li class='deep-2'><i class='icon-folder-open'></i> Pay <span class='r'>嵌套的模块</span></li> <li class='deep-3'><i class='icon-folder-open'></i> Taobao <span class='r'>嵌套的模块</span></li> <li class='deep-4'><i class='icon-file'></i> CashController.php <span class='r'>控制器类文件</span></li> <li class='deep-1'><i class='icon-folder-close'></i> models</li> <li class='deep-1'><i class='icon-folder-close'></i> config</li> </ul> 我们可以知道,要访问的控制器 CashController.php 在文件夹 controllers/Pay/Taobao 下,而 Pay/Taobao 则是这个控制器的模块名。URL中的参数部分应该是这样的 /Pay_Taobao/Cash/index Pay_Taobao 会被框架自动转义成 Pay/Taobao ,URL中的模块名 控制器名都会被自动转义,规则如下 <table class='table'> <tr class='title'> <td style='width:60px;'>URL部分</td> <td>原来的</td> <td>转义后</td> <td>转义规则</td> </tr> <tr> <td>模块名</td> <td>foo</td> <td>Foo</td> <td style='text-align:left;'>在没有 '-' '_' 字符串时,将模块名字符串首字母大写</td> </tr> <tr> <td>模块名</td> <td>foo_bar</td> <td>Foo/Bar</td> <td style='text-align:left;'>对于中间有下划线的,会依据下划线分割字符串,再将每个字符串首字母大写然后用 '/' 将字符串拼接</td> </tr> <tr> <td>模块名</td> <td>foo-bar</td> <td>FooBar</td> <td style='text-align:left;'>对于中间有横线的,会依据横线分割字符串,再将每个字符串首字母大写然后直接将字符串拼接</td> </tr> <tr> <td>控制器</td> <td>bar</td> <td>Bar</td> <td style='text-align:left;'>在没有 '-' 字符串时,将控制器的首字母大写。(所以在类以及类文件的命名规则都要首字母大写)</td> </tr> <tr> <td>控制器</td> <td>foo-bar</td> <td>FooBar</td> <td style='text-align:left;'>对于中间有横线的,会依据横线分割字符串,再将每个字符串首字母大写然后直接将字符串拼接</td> </tr> </table> </div> <a name="controller"></a> <div class='content'> <h1>控制器</h1> <h4>命名规则</h4> 我们采用流行的驼峰命名法对文件名、类名进行命名规范<br> 控制器文件名首字母要大写且要连接上字符串Controller,后缀为php。比如我们的控制器名称为Index,则文件名为 IndexController.php。若我们要定义的控制器名称是两个单词(customer 、analysis)组成的 则文件名应该是 CustomerAnalysisController.php 。值得注意的是 <span class='tag-warn'>文件名要和类名一致,包括大小写</span>。 <h4>命名空间</h4> 我们采用命名空间对用户的类进行管理,这样您就不必担心类命名
View on GitHub
GitHub Stars32
CategoryDevelopment
Updated3y ago
Forks12

Languages

PHP

Security Score

60/100

Audited on Aug 8, 2022

No findings