新人入坛小分享:超简化的自定义PHP小框架
写PHP后台服务的同学可能会接触到symfony、ThinkPHP、Laravel、Yii等框架,框架出现的缘由大概是前人做项目做的比较多,对于需求中常出现的功能予以封装,制定一些规则,在此框架下,使用者可以快速的搭建出自己的应用,不过,不同的框架其重量不一,学习曲线也不一样,而且对框架使用一段时间后,大多数人都会想深入源码去探究一番,那么,以下的代码希望给有需要的同学给予一些提示。需求:实现类似http://site/module/action?params的url规则的小框架
1 框架的文件结构
|----index.php
|---config.php
|---myapp/
|---utils/
|----thirdLibs/
2 代码
2.1 index.php
<?php
if (array_key_exists("DOCUMENT_ROOT", $_SERVER)) {
require_once($_SERVER["DOCUMENT_ROOT"] . '/config.php');
} else {
require_once(dirname(__FILE__) . '/config.php');
}
$req_uri = $_SERVER["REQUEST_URI"];
$req_path = $_SERVER["PATH_INFO"];
/* 预处理路径 */
$path_segs = array();
$tmp_path_segs = explode("/", $req_path);
foreach ($tmp_path_segs AS $k => $v) {
if ($v != "") {
$path_segs[] = $v;
}
}
$cls_name = "";
$method_name = "";
/* 路由解析 */
$path_len = count($path_segs);
if ($path_len == 0) {
$cls_name = "Home";
$method_name = "index";
} else if ($path_len == 1) {
$cls_name = $path_segs;
$method_name = "index";
} else if ($path_len == 2) {
$cls_name = $path_segs;
$method_name = $path_segs;
} else {
die("未能识别的路径");
}
$cls_name = ucwords($cls_name);
$req_method = $_SERVER["REQUEST_METHOD"];
if ($req_method == "POST") {
$post_data = file_get_contents("php://input");
$content_type = $_SERVER["CONTENT_TYPE"];
if ($content_type == "application/json") {
/* 特别处理json上传的情况 */
$post_json_obj = json_decode($post_data, true);
$_POST = array();
foreach ($post_json_obj AS $k => $v) {
$_POST[$k] = $v;
}
//var_dump($_POST);
}
}
/* 加载对应的类和方法 */
require_once(APP_PATH . '/' . $cls_name . ".class.php");
$ref_cls = new ReflectionClass($cls_name);
$instance = $ref_cls->newInstance();
$cls_method = $ref_cls->getmethod($method_name);
$cls_method->invokeArgs($instance, array());
?>
2.2 config.php
date_default_timezone_set("PRC");
/* 设置项目路径,方便后面使用 */
if (array_key_exists("DOCUMENT_ROOT", $_SERVER)) {
define("PROJ_PATH", $_SERVER["DOCUMENT_ROOT"]);
} else {
define("PROJ_PATH", dirname(__FILE__));
}
/* 定义小功能部件的路径,即开发时你自己封装的一些功能函数或类 */
define("UTILS_PATH", PROJ_PATH . "/utils");
/* 定义第三方库的路径 */
define("THIRDLIBS_PATH", PROJ_PATH . "/thirdLibs");
/* 定义app的名称*/
define("APP_NAME", "myApp");
/* 设置app的路径*/
define("APP_PATH", PROJ_PATH . "/" . APP_NAME);
/* 加载app的配置 */
require_once(APP_PATH . '/config.php');
3 配置
3.1 nginx
按照路由规则,可以按照以下配置到文件中,例如myApp.conf(搜索参考ThinkPHP的nginx配置)
log_formatmyapp.com'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
server {
listen 8088;
server_name myapp.com;
ssi on;
autoindex off;
ssi_silent_errors on;
ssi_types text/shtml;
charset utf-8;
root /data/www/myapp;
index index.php index.html index.htm default.html default.htm default.php;
location / {
try_files $uri @rewrite;
}
location @rewrite {
set $static 0;
if ($uri ~ \.(css|js|jpg|jpeg|png|gif|ico|woff|eot|svg|css\.map|min\.map)$) {
set $static 1;
}
if ($static = 0) {
rewrite ^/(.*)$ /index.php/$1 last;
break;
}
}
location ~ /backend/.*\.php$ {
deny all;
}
location ~ ^(.+\.php)(.*)$ {
fastcgi_index index.php;
include fastcgi_params;
set $path_info "";
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SERVER_NAME $host;
fastcgi_pass 10.51.127.68:9000;
server_name_in_redirect off;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
root /data/www/bijiashufang;
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
access_log/data/logs/wwwlogs/bijiashufang.com.logbijiashufang.com;
}
3.2 php-fpm
略,网上搜索即可找到。
4 测试使用
在myapp目录下增加文件Home.php.class,
class Home {
public function __construct() {}
public function index() {
echo "你正在访问的是Home类index方法";
}
}
在浏览器上访问http://myapp.com,看是否正确
5 总结
例子比较简单,据我的理解(可能不完全正确),写框架的大致思路是这样的,然后还有加入一些功能可插拔设计、缓存加速、登录/cookie等流程的集成等,框架逐渐变重,变复杂,如果设计的比较好,接口完整稳定,那么很多功能组件就可以替代性的使用。
由于在破解方面比较小白,暂且贡献点编程上的思路,欢迎交流,谢谢! 虽然不怎么了解,还是很感动
页:
[1]