实践学习php,thinkphp,Redis,vue,uni-app等技术,推荐开源电商系统likeshop,可以借鉴思路,可去版权免费商用,gitee下载地址:
点击进项目地址
定义入口文件
- 定义常量
- 引入库函数
- 引入核心模块
完成自动加载
入口文件 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);
}
}
控制器
加载控制器
定义好控制器文件
# 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!");
}
}
......
数据库
新建数据库,表
初始化连接
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操作
视图
extract
(PHP 4, PHP 5, PHP 7)
extract — 从数组中将变量导入到当前的符号表
extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int
本函数用来将变量从数组中导入到当前的符号表中
检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突
就是把一个键值对作为一个变量,键名为变量名,键值为变量值
# 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>
效果如下
其他类
配置类
为了实现代码简介,将代码按功能进行划分,将配置文件单独存放,也方便修改
两个配置文件作为示例
# 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 目录下生成文件
}
}
$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)]