在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:mzphp2开源软件地址:https://gitee.com/mz/mzphp2开源软件介绍:gitbook 在线文档: https://djunny.gitbooks.io/mzphp/content/index.html enphp 在线加密: 更新历史[2016.12.30]新增:
修复:
优化:
[2016.1.27] 新增:
修复:
优化:
性能评测既然大家都对性能这么有疑问,那么我拿 Hello World 来做一个简单的评测: 如何评测性能? XDEBUG 后能产生一个 profile通过 wincachegrind 能直观看到框架每一行的性能损耗。 测试环境 Windows 虚拟机,i7 2核 + 1G内存。PHP 最基础环境。 测试框架
测试结果 为了最佳性能,会让三个框架连续运行 20 次,然后输出 XDEBUG 的 profile: 最终的 profile 文件大小对比: 结果对比 mzphp 的 profile line-by-line结果: TP 的 profile line-by-line结果: CI 的 profile line-by-line结果: mzphp 的 profile overall结果: TP 的 profile overall结果: CI 的 profile overall结果: mzphp 跑热后,项目加载以及页面运行的时间为 1.6ms CI 跑热后,项目加载以及页面运行的时间为 2.7ms 而 TP 跑热后,页面运行时间为:5.5ms 具体的 profile 数据,大家可以下载自行查看(window 下使用 wincachegrind 查看): 传送地址:profile下载 序很久以来,楼主开发站点无数,一直希望能有一个枚,日开数站的 PHP 框架出现。 mzphp 介绍PHP 开发框架 mzphp,拥有特点:
mzphp 做为一直追求高效、简单、快速开发的 PHP 框架,希望大家多多支持。 mzphp 运行的环境
如果需要 php 在 cli (命令行) 下运行,而您的操作系统是 windows。 请在系统 -> 环境变量 -> PATH -> 添加你的 php.exe 所在路径 拉取 mzphp 代码
完后,可更新子项目例子:
生成第一个项目假我们需要建立的项目名称为:hello_world 请在项目目录建立一个hello_world(与 mzphp 目录同级) 复制 tools 目录下的 create_project.php 到 hello_world 目录。 提供两种方法生成项目结构:
cd hello_worldphp create_project.php 访问生成的 index.php,可看到 mzphp Framework 字样,即访问成功. mzphp 目录文件
项目目录文件
配置项目参数打开项目 conf/conf.{env}.php 可按照注释编辑对应的参数。 {env}代表运行环境,由 $_SERVER['ENV'] 来控制 (默认为 debug)。 在 nginx 中,您可以通过添加:
来切换线上、线下环境。 附上一些小的参数修改
调试方法index.php 中,你可以直接设置 define('DEBUG', 1) 永久打开 debug 也可以修改 hello_world_debug 这个字符串来告之项目当 url 中包含该字符时,自动开启 debug。 debug 开启时,右下角将出现一个浮动的运行时间展示,点击开来可以看到具体页面运行的信息。 注意 mzphp 框架为了减少磁盘 I/O,提高加载性能,会在项目第一次运行时,
mzphp 控制器在项目 control 目录中建立一个 user_control.class.php 同时,在该文件中定义一个 user_control 继承 base_control <?php!defined('FRAMEWORK_PATH') && exit('Accesss Deined');class user_control extends base_control { public function on_index(){ // define user $user = 'djunny'; // assign variables VI::assign('user', $user); // default template path is view/user_index.htm $this->show(); }} $this->show 调用显示模板, 可以自动识别为 view/user_index.htm, 即 {$control}_{$action}.htm 假如,view/user_index.htm 如下: hello {$user} 使用 index.php?c=user-index 可访问到 user_control 的 on_index 方法,显示结果: hello djunny 同时,使用命令行下: php index.php user index 也能在命令行下看到同样的结果 小建议:
mzphp DAO 数据层第一步:配置 conf 文件中的 db。 第二步:创建 user 表: CREATE TABLE `user` ( `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '', PRIMARY KEY (`uid`)) DEFAULT CHARSET=utf8 COMMENT='user' 第三步,model 层有二种调用方法。 第一种,不定义 model,直接使用 <?php!defined('FRAMEWORK_PATH') && exit('Accesss Deined');class user_control extends base_control { public function on_index(){ // SELECT * FROM user WHERE id =1 $user = DB::T('user')->get(1); // ... }} 此方法用于简单的 DAO 层调用。 第二种,在项目 model 目录中,新建一个 user.class.php 定义 user 继承自 base_model, <?php!defined('FRAMEWORK_PATH') && exit('Accesss Deined');class user extends base_model { function __construct() { parent::__construct('user', 'id'); }}?> 在控制器中使用 <?php!defined('FRAMEWORK_PATH') && exit('Accesss Deined');class user_control extends base_control { public function on_index(){ // SELECT * FROM user WHERE id =1 $user = $this->user->get(1); // ... }} mzphp 中,控制器会自动加载并初始化对应的 model 层。 另外:
// add table prefix$table = DB::table('user');// build SQL$sql = sprintf("SELECT * FROM %s WHERE id=%d", $table, 1);// get query and return first row$first_row = DB::query($sql, 1);// get query $query = DB::query($sql);while($val = DB::fetch($query)){ log::info($val);}// select method// get first row from user where id =1$user = DB::select('user', array('id'=>1), ' id ASC', 0);// get all user array$user_list = DB::select('user');// get user count$user_count = DB::select('user', 0, 0, -2); mzphp 模板引擎 - 基础语法
模板中动态渲染内容,基本上由以上语法组成。
<!--{if 1==2}--><html></html><!--{/if}-->
<form {if 1==2}method="post"{/if}>
mzphp 模板引擎 - 子模板说明: 加载一个子模板。(子模板最多支持三层嵌套) 语法: <!--{template header.htm}--> mzphp 模板引擎 - 逻辑判断说明: if else 逻辑判断 语法: <!--{if $a == $b && $b == 1}--> a = b AND b = $b<!--{elseif $b == 2 || $a == 3}--> b = $b OR a = $a<!--{elseif $a == 1}--> a = 1<!--{else}--> a != 1<!--{/if}--> mzphp 模板引擎 - 循环说明: 循环输出列表,可嵌套输出 语法: <!--{loop $categories $index $cate}--> categories[$index]= {$cate['name']}<!--{/loop}--> mzphp 模板引擎 - eval 标签说明: 执行 php 代码。 语法: <!--{eval $a = 1;$b = array( 'a' => 1, 'b' => 2,);}--><!--{eval echo $my_var;}--><!--{eval $my_arr = array(1, 2, 3);}--><!--{eval print_r($my_arr);}--><!--{eval exit();}--> mzphp 模板引擎 - 方法调用标签说明: 调用的方法并输出返回的内容。(方法必须以返回值) 语法: {date('Y-m-d')}{substr('123', 1)}{print_r(array(1), 1)}{spider::html2txt('<html></html>')} mzphp 模板引擎 - 静态文件语法: <!--{static source_file target_file is_compress}--> 说明: source_file 文件后缀为 scss 或者 js 时,会调用对应的编译类对文件进行编译和生成,生成的文件路径:static/{$target_file} is_compress 参数可以为 0 或 1(默认 1),为 1 时,source_file 压缩,反之而不压缩。 在 debug 开启后,每次访问页面,都会生成一遍静态文件。在代码 push 的时候,需要产生的所有静态文件提交(线上不会再编译静态资源) 规范
静态文件寻找先后顺序
关于 css sprite 当 source_file 以 * 结尾时, 识别为 css sprite 模式,程序将会对 source_file 目录中的所有文件进行合并,读取所有图片的 size ,生成对应的 scss 文件和合并的 png 文件:
实例 <!--{static scss/png/* scss/sprite}--><!--{static scss/test.scss scss/_a.css}--><!--{static js/test1.js js/_a.js}--><!--{static js/test2.js js/_a.js 0}--><!--{static js/test3.js js/_a.js 1}--> 在以上例子中,系统做了以下处理: 1.先合并 scss/png/ 中所有图片为: scss/sprite.png,同时生成坐标 scss 文件:scss/sprite.scss 2.scss/test.scss 中调用 @import 'sprite'; 然后用 scss 语法来继承对应的 icon 或 图片即可,例(图片路径中.会变成-,更具体可以先成生一次后,打开生成后的sprite.scss看看): .find{ @extend .loading-png;} 3.开启合并文件 js/_a.js ,并将 js/test1.js 写入。 4.读取 js/test2.js,写入 js/_a.js 尾部。 5.读取 js/test3.js,并压缩,写入 js/_a.js 6. 替换成 空 7. 替换成 < link rel="stylesheet" href="scss/_a.css"> 8. 替换成 < script src="js/_a.js"></ script> 9. 均替换成空 mzphp 地址重写地址重写规则: .htaccess Options RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d#control + actionRewriteRule ^(\w+)(?:[/\-_\|\.,])(\w+)(?:[/\-_\|\.,])(.*)$ index.php\?c=$1-$2&rewrite=$3 [L]#control RewriteRule ^(\w+)(?:[/\-_\|\.,])(.+)$ index.php\?c=$1&rewrite=$2 [L] apache httpd.ini [ISAPI_Rewrite]RepeatLimit 32RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d#control + actionRewriteRule ^(\w+)(?:[/\-_\|\.,])(\w+)(?:[/\-_\|\.,])(.*)$ index.php\?c=$1-$2&rewrite=$3 [L]#control RewriteRule ^(\w+)(?:[/\-_\|\.,])(.+)$ index.php\?c=$1&rewrite=$2 [L] nginx.conf #control + actionrewrite ^(\w+)(?:[/\-_\|\.,])(\w+)(?:[/\-_\|\.,])(.*)$ index.php?c=$1-$2&rewrite=$3 last;#control rewrite ^(\w+)(?:[/\-_\|\.,])(.+)$ index.php?c=$1&rewrite=$2 last; iis 7 <?xml version="1.0" encoding="UTF-8"?><configuration> <system.webServer> <rewrite> <rules> <rule name="mzphp_1" stopProcessing="true"> <match url="(\w+)(?:[/\-_\|\.,])(\w+)(?:[/\-_\|\.,])(.*)$" /> <action type="Rewrite" url="index.php?c={R:1}-{R:2}&rewrite={R:3}" appendQueryString="true" /> </rule> <rule name="mzphp_2" stopProcessing="true"> <match url="(\w+)(?:[/\-_\|\.,])(.+)$" /> <action type="Rewrite" url="index.php?c={R:1}&rewrite={R:2}" appendQueryString="true" /> </rule> </rules> </rewrite> </system.webServer></configuration> mzphp 自定义 URL1.非地址重写链接: index.php?c=control-action&var=... 2.系统地址重写(该地址中的 / 分隔符和 [.html] 均可在conf文件中配置): /control/action/param1/param1value/param2/param2value...[.html] conf/conf.[env].php 配置文件: //url rewrite params 'rewrite_info' => array( 'comma' => '/', // options: / \ - _ | . , 'ext' => '.html',// for example : .htm ), 使用系统地址重写时,您可以使用url方法,来生成url: function url($control, $action, $params = array()) ; 例: echo url('index', 'index', array('id'=>1));echo url('index-index', array('id'=>1));echo url('index-index', 'id=1&time=2015'); 3.自定义地址重写: index.php?c=control-action&rewrite=param1/param1value... 例如,我们需要使用:/help/123/ 来映射 index.php?c=article-help&id=123 可以在 urlrewrite 重写文件中配置(以 .htaccess 语法为例): RewriteRule ^(help)/(\d+)/?$ index.php\?c=article-$1&rewrite=id/$2 [L] 注:本例中 rewrite 参数传入的分割符(/),视 rewrite_info 中的 comma 而定。 钩子方法 HOOK通过钩子方法,能在系统任何代码处调用在 hook 中注册的方法。 可用于插件或者扩展功能实现。 运行 hook function hook($name) {} 输出 hook 输入 hook 一般在模板中直接调用比较多 function out_hook($returns, $implode = '') {} 钩子使用例子在项目根目录的 index.php 中 ,定义存放钩子类的目录(例子中定义为项目根目录的 hook目录) define('HOOK_PATH', ROOT_PATH.'hook/'); 在对应目录下,创建一个 hook 目录 。 hook 目录下建立一个 hook_xxx.php,内容如下: class hook_xxx { static function func($abc = ''){ return '<a>'; }} TIP:hook_xxx.php 和 PHP 文件 class hook_xxx 必须一致。 此时,清理 tmp 目录(如果没有开启 DEBUG 模式则需要每次修改 hook 文件后操作)后, 在任意代码地方调用: hook('func'); 也支持参数传入: hook('func', 'abc'); 即调用对应 hook 到所有类包含的 func 静态方法。 TIP:并不是每个方法都会被 hook,记住,hook_xxx 类中带 _ (下划线)开头的静态方法是无法调用的。 TIP:同理,您可以将不想公开的方法用 _ (下划线)开头,防止 hook cache 到过多的方法,这样既可以优化 hook 扫描时的性能,又可以避免外部访问到。 hook 方法 返回结果类型为:Array 因为在 hook 目录中,存在的同样静态方法的类会有多个,调用时每个方法都会去调用一遍,所以会以数组形式返回。 循环输出或者在模板中可用 {out_hook(hook('func'), '<Br>')} 即可。 小技能 hook 可以按文件名顺序来排序,加排序的方法: 1.hook_xxx.php 2.hook_aaa.php 3.hook_ccc.php 数字越大,越优先加载, TIP:插件排序,非特殊情况建议不要使用~ TIP: 如果调用 hook 途中,需要中止加载其它类的调用。 请在方法中返回: return array( // 通知 hook 系统不需要再运行其它 hook 类里的方法了 'HOOK' => HOOK_STOP, // 返回的结果 'return' => 'xxxxx',); EnPHP 加密工具的说明EnPHP 工具的路径:tools/enphp_project.php EnPHP 是一款可以加密混淆 PHP 5-7 的工具,现内置于 mzphp Framework 中。EnPHP 经多方测试已经支持加密混淆 99% 以上的 PHP 代码,欢迎测试反馈。 使用方法:
P.S. 重要的事情说三遍:备份!备份!备份!请在加密前备份好您的源码文件,通过 EnPHP 加密的文件均无法恢复!否则请不要使用。 P.S.S. 您也可以将 enphp 类与 spider 类拷出去单独使用。 enphp 在线加密地址: 更多实例敬请期待。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论