0
点赞
收藏
分享

微信扫一扫

PHP MVC框架开发(上)

高子歌 2022-11-21 阅读 165


实践学习php,thinkphp,Redis,vue,uni-app等技术,推荐开源电商系统likeshop,可以借鉴思路,可去版权免费商用,gitee下载地址:
​​​点击进项目地址​​

文章目录

  • ​​定义入口文件​​
  • ​​完成自动加载​​
  • ​​路由类​​
  • ​​.htaccess​​
  • ​​explode​​
  • ​​trim​​
  • ​​array_slice​​
  • ​​实现​​
  • ​​控制器​​
  • ​​加载控制器​​
  • ​​数据库​​
  • ​​初始化连接​​
  • ​​数据查询函数​​
  • ​​视图​​
  • ​​extract​​
  • ​​其他类​​
  • ​​配置类​​
  • ​​日志类​​

定义入口文件

  • 定义常量
  • 引入库函数
  • 引入核心模块

PHP MVC框架开发(上)_数组

完成自动加载

入口文件 index.php

<?php

// door file

// define system const
define('LSPHP', __DIR__ . "/");
define('APP', __DIR__ . "/app");
define('CORE', __DIR__ . "/core");


//define debug
define('APP_DEBUG',true);

if (APP_DEBUG) {
ini_set('display_errors', 'On');
} else {
ini_set('display_errors','Off');
}


// include core func file
include CORE . '/common/function.php';
// test
// p("1234");


// include core class file
include CORE . "/lsphp.php";
// test
// \core\lsphp::run();


// 实现类加载,注册加载函数
spl_autoload_register('\core\lsphp::load');

\core\lsphp::run();

自动加载 lsphp.php

<?php

namespace core;

class lsphp
{

public static $classMap = [];

public static function run()
{
$route = new \core\route();
}

// 实现自动加载
public static function load($class)
{
if (isset(self::$classMap[$class])) {
return true;
} else {
$filepath=str_replace('\\','/',$class);
$filepath=LSPHP.$filepath.'.php';
if(is_file($filepath))
{
require $filepath;
self::$classMap=$filepath;
}else{
return false;
}
}
}
}

route.php

<?php
namespace core;

class route
{
public function __construct()
{
echo 'route';
}
}

路由类

.htaccess

.htaccess 文件是 apache 服务器中的一个配置文件,她负责相关目录下的网站配置,通过 htaccess 文件,可以实现:

  • 网页301重定向
  • 自定义404错误页面
  • 改变文件扩展名
  • 允许/阻止特定的用户或者目录的访问
  • 禁止目录列表
  • 配置默认文档等功能

<IfModule mod_rewrite.c>
# 打开Rerite功能
RewriteEngine On

# 如果请求的是真实存在的文件或目录,直接访问
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# 如果访问的文件或目录不是真事存在,分发请求至 index.php
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

explode

explode — 使用一个字符串分割另一个字符串

explode ( string $delimiter , string $string [, int $limit ] ) : array

此函数返回由字符串组成的数组,每个元素都是 ​​string​​​ 的一个子串,它们被字符串 ​​delimiter​​ 作为边界点分割出来

和 python 的 split 函数功能相同

trim

trim — 去除字符串首尾处的空白字符(或者其他字符)

trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] ) : string

此函数返回字符串 ​​str​​ 去除首尾空白字符后的结果。如果不指定第二个参数,trim() 将去除这些字符:

  • " " (ASCII 32 (0x20)),普通空格符
  • “\t” (ASCII 9 (0x09)),制表符
  • “\n” (ASCII 10 (0x0A)),换行符
  • “\r” (ASCII 13 (0x0D)),回车符
  • “\0” (ASCII 0 (0x00)),空字节符
  • “\x0B” (ASCII 11 (0x0B)),垂直制表符

和 python 的 strip 函数功能相同

array_slice

array_slice — 从数组中取出一段

array_slice ( array ​​$array​​​ , int ​​$offset​​​ [, int ​​$length​​​ = ​NULL​​ [, bool ​​$preserve_keys​​ = false ]] ) : array

array_slice() 返回根据 ​​offset​​​ 和 ​​length​​​ 参数所指定的 ​​array​​ 数组中的一段序列

<?php
$input = array("a", "b", "c", "d", "e");

$output = array_slice($input, 2); // returns "c", "d", and "e"
$output = array_slice($input, -2, 1); // returns "d"
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"

实现

实现类似于 think PHP 那样的效果,将 url 中的参数分别取出

index.php/模块/控制器/操作/参数/值
#index.php 作为入口文件,所以后端要将传来的 url 进行分割取值

因为没有设置路由映射,我的网站 url 为:

http://localhost/demo/develop/index.php

# $_SERVER['REQUEST_URI'] = "/demo/develop/index.php"

数组下标从 0 开始

# route.php

<?php

namespace core\lib;

class route
{
// 默认控制器和操作
public $ctrl = "index";
public $action = "index";
public $param = [];

public function __construct()
{
if (isset($_SERVER['REQUEST_URI'])) {
$pathString = $_SERVER['REQUEST_URI'];
$path_arr = explode('/', trim($pathString, '/'));
// $path_arr='/demo/develop/index.php/index/index/param/222'
}

if (isset($path_arr[2]) && ($path_arr[2]) == "index.php") {
$path_arr = array_slice($path_arr, 3, count($path_arr) - 2);
p($path_arr);
// $path_arr='index/index/param/222'
}

if (isset($path_arr[0])) {
// 取控制器
if (isset($path_arr[0])) {
$this->ctrl = $path_arr[0];
}
}

// 取操作
if (isset($path_arr[1])) ;
{
$this->action = $path_arr[1];
}

// 取参数,因为参数是在数组下标 2 开始
$i = 2;
$count = count($path_arr);
while ($i < $count) {
if (isset($path_arr[$i + 1])) {
$this->param[$path_arr[$i]] = $path_arr[$i + 1];
}
$i=$i+2;
}

p($this->ctrl);
p($this->action);
p($this->param);
}
}

PHP MVC框架开发(上)_php_02

控制器

加载控制器

定义好控制器文件

PHP MVC框架开发(上)_mvc_03

# indexController.php<?php

namespace app\controller;

class IndexController
{
public function index()
{
echo 'hello index';
}
}

在 lsphp.php 文件中去定义加载功能

......    
public static function run()
{
$route = new \core\lib\route();

// 加载控制器
$ctrl = $route->ctrl;
$action = $route->action;

$controllerFile = APP . "/controller/" . $ctrl . "Controller.php";
$controllerClass="\\app\\controller\\".$ctrl."Controller";
// 命名空间 \\ $ctrl(index)Controller

if (is_file($controllerFile)) {
require $controllerFile;
$controller = new $controllerClass;
$controller->$action();

} else {
throw new \Exception("controller not found!");
}
}
......

PHP MVC框架开发(上)_php_04

数据库

新建数据库,表

PHP MVC框架开发(上)_软件框架_05

初始化连接

PHP MVC框架开发(上)_mvc_06

db.php

使用 pdo 来实现,数据库配置连接

<?php

namespace core\common;

class db extends \PDO
{
public function __construct()
{
$dsn = 'mysql:host=localhost;dbname=lsphp';
$username = 'root';
$password = 'root';
try {
parent::__construct($dsn, $username, $password);
} catch (\Exception $e) {
echo $e->getMessage();
}
}
}

数据查询函数

# indexController.php  
......
public function query()
{
$db = new \core\common\db();
$sql = "select * from ls_user";
$data = $db->query($sql);
p($data);
p($data->fetchAll());
}
......

index控制器 query操作

PHP MVC框架开发(上)_php_07

视图

extract

(PHP 4, PHP 5, PHP 7)

extract — 从数组中将变量导入到当前的符号表

extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int

本函数用来将变量从数组中导入到当前的符号表中

检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突

就是把一个键值对作为一个变量,键名为变量名,键值为变量值

PHP MVC框架开发(上)_加载_08

# render.php

<?php

namespace core;

class render
{
public $param = [];

// 传参数函数
public function assign($name, $value)
{
$this->param[$name] = $value;
}

// 控制传到那个视图中去
public function display($view)
{
$viewPath=APP."/view/".$view.".html";

if(is_file($viewPath))
{
extract($this->param);
include $viewPath;
}else{
echo "view is not found";
exit();
}
}
}

# indexController.php
<?php

namespace app\controller;

class IndexController extends \core\render
# 需要继承 render
{
public function render()
{
$this->assign("title","ocean");
$this->assign("content",'test');
$this->display("index");
}
}

# index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>

<h2>
<?php echo $title ?>
</h2>
<p>
<?php echo $content ?>
</p>
</body>
</html>

效果如下

PHP MVC框架开发(上)_数组_09

其他类

配置类

为了实现代码简介,将代码按功能进行划分,将配置文件单独存放,也方便修改

PHP MVC框架开发(上)_php_10

两个配置文件作为示例

# db_config.php
<?php
return array (
"dsn" => 'mysql:host=localhost;dbname=lsphp',
"username" => 'root',
"password" => 'root',
);

# route_config.php
<?php
return array(
"1"=>"one",
"2"=>"two",
"3"=>"three"
);

\core\conf.php 去加载配置类

# \core\conf.php
<?php
// 获取加载配置config信息的函数
namespace core;

class conf
{
# 获取一条信息
public static function get($name, $file)
{
$fileName = CONFIG . "/$file" . ".php";
if (is_file($fileName)) {
$conf = include $fileName;
if (isset($conf[$name])) {
return $conf[$name];
}else{
throw new \Exception("not found config name!");
}
} else {
throw new \Exception("not found file!");
}
}

# 获取全部信息
public static function all($file)
{
$fileName = CONFIG . "/$file" . ".php";
if (is_file($fileName)) {
$conf = include $fileName;
return $conf;
} else {
throw new \Exception("not found file!");
}
}
}

因为使用了 CONFIG 常量,需要提前定义好

# index.php
define("CONFIG",__DIR__."/config");

这样的话就可以把数据库配置文件单独存放在 config 文件里

以下调用数据

# \core\common\db.php
class db extends \PDO
{
public function __construct()
{
$db_config=\core\conf::all('db_config');
$dsn=$db_config['dsn'];
$username=$db_config['username'];
$password=$db_config['password'];
.....

# 单个调用
public function getroute(){
$route= \core\conf::get("1",'route_config');
p($route);

日志类

记录操作步骤

添加 LOG 常量

# index.php
header("Content-type:text/html;charset=utf-8");
// 因为要返回中文,如果有乱码设置header头

define('LOG', __DIR__ . "/log");

# \core\log.php 日志记录文件

<?php
namespace core;

class log
{
public function log($message)
{
ini_set('data.timezone', 'Asia/Beijing');
$log_dir = LOG . '/' . date('Ymd');
if (!is_dir($log_dir)) {
if (mkdir($log_dir)) {

} else {
throw new \Exception("log file create error");
}
}

$log_file = $log_dir . '/' . date('Hi');
// H 表示 24小时,i 表示 60分钟
if (!is_file($log_file)) {
if(!file_put_contents($log_file,$message.PHP_EOL,FILE_APPEND)){
// 文件名,文件内容.php换行(\n),写入方式:追加写入
}else{
throw new \Exception("log content write error");
}
}
}
}

调用

# indexController.php
public function log()
{
$log = new \core\log();
$log->log("this is a test log");
echo 'ok';
}

会在 log 目录下生成文件

PHP MVC框架开发(上)_php_11

}
}

$log_file = $log_dir . '/' . date('Hi');
// H 表示 24小时,i 表示 60分钟
if (!is_file($log_file)) {
if(!file_put_contents($log_file,$message.PHP_EOL,FILE_APPEND)){
// 文件名,文件内容.php换行(\n),写入方式:追加写入
}else{
throw new \Exception("log content write error");
}
}
}

}

调用

```php
# indexController.php
public function log()
{
$log = new \core\log();
$log->log("this is a test log");
echo 'ok';
}

会在 log 目录下生成文件

[外链图片转存中…(img-cRCaGCrT-1617458110476)]


举报

相关推荐

0 条评论