亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

手把手寫框架案例

原創(chuàng) 2019-02-18 16:49:24 469
摘要:本章通過手把手寫框架的學習,對MVC的模式有了進一步的認識,通過實踐,可以通過手寫框架實現(xiàn)數(shù)據(jù)的增刪改查。項目結(jié)構(gòu)如下:本次框架主要包含三大目錄及其他文件:基類目錄。該目錄命名為pong。pong目錄下面包含core目錄、基類文件、配置文件、路由文件,其中,core目錄包含了controller、view、model三個基類。自己的應用項目。項目放在app目錄下,app目錄下設admin目錄、ho

本章通過手把手寫框架的學習,對MVC的模式有了進一步的認識,通過實踐,可以通過手寫框架實現(xiàn)數(shù)據(jù)的增刪改查。項目結(jié)構(gòu)如下:

QQ截圖20190218163914.jpg

本次框架主要包含三大目錄及其他文件:

基類目錄。該目錄命名為pong。pong目錄下面包含core目錄、基類文件、配置文件、路由文件,其中,core目錄包含了controller、view、model三個基類。

自己的應用項目。項目放在app目錄下,app目錄下設admin目錄、home目錄、Model目錄,admin目錄主要用于存放后臺管理頁面的數(shù)據(jù),里面包含controller和view兩個文件夾,分別存放具體頁面對應的控制器文件和視圖文件。home目錄與admin目錄的架構(gòu)類型類似,主要用于存放前臺的文件。Model目錄,主要用于存放系統(tǒng)公用的model類,因為model類是可以給前臺和后臺公用,所以獨立到一個文件夾中。

模板框架目錄。該目錄主要是通過composer下載的模板框架和數(shù)據(jù)庫框架。

.htaccess文件。該文件主要用于頁面的重定向。

composer.json和composer.lock文件。這兩個文件主要是通過composer獲取框架后自動生成的文件,其中composer.lock存放了框架的基礎配置,如框架版本。

Index.php文件。該文件為入口文件,通過.htaccess文件配置的重定向,默認訪問域名時,即進入該文件。

框架源碼:

入口文件index.php

<?php
/**
 * 入口文件
 */

//導入模板框架
require __DIR__.'/vendor/autoload.php';

//導入基礎類
require  __DIR__.'/pong/Base.php';

//獲取配置文件信息
$config=require __DIR__.'/pong/Config.php';

//定義根目錄路徑
define('ROOT_PATH',__DIR__.'/');

//獲取查詢字符串
$queryStr=$_SERVER["QUERY_STRING"];

//啟動框架
(new \pong\Base($config,$queryStr))->run();

基礎類Base.php:

<?php
/**
 * 基類
 */

namespace pong;


class Base
{
    //配置數(shù)組
    protected  $config=[];
    //查詢字符串
    protected  $queryStr=[];

    public  function  __construct($config,$queryStr='')
    {
        $this->config=$config;
        $this->queryStr=$queryStr;
    }

    //設置調(diào)試狀態(tài)
    public function setDebug()
    {
        //如果調(diào)試模式為true,則開啟調(diào)試模式,否則關閉調(diào)試模式
        if ($this->config['app']['debug']) {
            error_reporting(E_ALL);
            ini_set('display_errors','On');
        } else {
            ini_set('display_errors','Off');
            ini_set('log_errors', 'On');
        }
    }

    //設置自動加載器
    public  function  loader($class)
    {
        //把參數(shù)格式進行轉(zhuǎn)換
        $path = ROOT_PATH . str_replace('\\','/',$class) . '.php';
        //判斷文件是否存在
        if(!file_exists($path))
        {
            header('Location:/');//返回根目錄
        }

        //加載文件
        require_once $path;
    }

    //啟動框架
    public  function  run()
    {
        //設置調(diào)試模式
        $this->setDebug();

        //自動加載
        spl_autoload_register([$this,'loader']);

        //請求分發(fā)
        $route=new Route($this->config['route']);
        echo $route->parse($this->queryStr)->dispatch();
    }
}

配置基類config.php

<?php
/**
 * 配置文件
 */

return [
    //應用配置
    'app'=>[
        //調(diào)試開關
        'debug'=>true
    ],

    //路由配置
    'route'=>[
        //默認模塊
        'module'=>'admin',

        //默認控制器
        'controller'=>'Index',

        //默認操作
        'action'=>'index'
    ],

    'db'=>[
        // 數(shù)據(jù)庫類型
        'database_type' => 'mysql',

        // 默認數(shù)據(jù)庫名稱
        'database_name' => 'test',

        // 默認主機名
        'server' => '127.0.0.1',

        // 默認用戶名
        'username' => 'root',

        // 用戶密碼
        'password' => 'root',

        // 編碼
        'charset' => 'utf8',

        //端口
        'port' => 3306,
    ]
];

路由基類Route.php:

<?php
/**路由類*/

namespace pong;


class Route
{
    protected $route=[];
    protected $passInfo=[];
    protected $params=[];

    public function __construct($route)
    {
        $this->route=$route;
    }

    /**
     * @param string $queryStr  鏈接參數(shù)
     * @return $this            當前類的實例
     */
    public  function  parse($queryStr='')
    {
        //去除字符串左右的/,并將參數(shù)全部轉(zhuǎn)為小寫
        $queryStr=strtolower(trim($queryStr,'/'));
        //通過/把字符串轉(zhuǎn)成數(shù)組
        $queryArr=explode('/',$queryStr);
        //數(shù)組過濾掉空字符
        $queryArr=array_filter($queryArr,function($value){
            return trim($value)!='';
        },ARRAY_FILTER_USE_BOTH);

        //判斷數(shù)組中有幾個參數(shù)
        switch (count($queryArr))
        {
            case 0:
                $this->passInfo = $this->route;
                break;
            case 1:
                $this->passInfo['module']=$queryArr[0];
                break;
            case 2:
                $this->passInfo['module']=$queryArr[0];
                $this->passInfo['controller']=$queryArr[1];
                break;
            case 3:
                $this->passInfo['module']=$queryArr[0];
                $this->passInfo['controller']=$queryArr[1];
                $this->passInfo['action']=$queryArr[2];
                break;
            default:
                $this->passInfo['module']=$queryArr[0];
                $this->passInfo['controller']=$queryArr[1];
                $this->passInfo['action']=$queryArr[2];

                //從第四個元素開始遍歷,即過濾掉路由的信息
                for($i=3;$i<count($queryArr);$i+=2)
                {
                    if(isset($queryArr[$i+1]))
                    {
                        $this->params[$queryArr[$i]]=$queryArr[$i+1];
                    }
                }
                break;
        }

        //返回當前對象
        return $this;
    }

    public function  dispatch()
    {

        //模塊名
        $module = $this->passInfo['module'];
        //控制器名
        $controller='\app\\' .$module . '\controller\\' .  ucfirst($this->passInfo['controller']) ;
        //操作
        $action= $this->passInfo['action'];


//        echo $controller , '               ' , $action;
//        return;

        //如果找不到,重新返回根目錄
        if(!method_exists($controller,$action))
        {
            header('location:/');
        }

        return call_user_func_array([new $controller,$action],$this->params);

    }
}

//測試
//$config=require __DIR__.'/Config.php';
//$route=new Route($config['route']);
////測試請求分發(fā)
//require __DIR__ . '/../app/admin/controller/Index.php';
//print_r($route->parse($_SERVER['QUERY_STRING'])->dispatch()) ;

控制器基類Controller.php

<?php
/**控制器基類*/

namespace pong\core;


class Controller
{
    protected  $view=null;

    public  function  __construct()
    {
        $this->view=new namespace\View();

        $this->config();
    }

    //配置方法
    public  function  config()
    {
        //設置后臺模板目錄的命名空間
        $this->view->addFolder('admin', ROOT_PATH.'/app/admin/view');

        //設置后臺模板目錄的命名空間
        $this->view->addFolder('home', ROOT_PATH.'/app/home/view');
    }


    //模板賦值
    public function assign($name, $value)
    {
        $this->data[$name] = $value;
    }

    //渲染模板
    public function fetch($file)
    {
        //1.將容器中的關聯(lián)數(shù)據(jù)轉(zhuǎn)為變量:鍵名->變量名,元素值->變量值,返回變量個數(shù)
        extract($this->data);

        //2. 將模板加載到當前控制器方法對應的腳本本
        require $file;
    }
}

視圖基類view.php

<?php
/*視圖基類**/

namespace pong\core;


use League\Plates\Engine;

class View extends  Engine
{
    public  function __construct($directory = null, $fileExtension = 'php')
    {
        parent::__construct($directory, $fileExtension);
    }
}

模型基類Controller.php

<?php
/**模型基類*/

namespace pong\core;


use Medoo\Medoo;

class Model extends Medoo
{
    public function  __construct($option=null)
    {

        $config=require __DIR__.'/../Config.php';

        $option=$config['db'];

        parent::__construct($option);
    }
}

樣式文件style.css

table {
    border-collapse: collapse;
    width: 60%;
    text-align: center;
    margin: 30px auto;
}

table, th, td {
    border: 1px solid black;
}

table tr th {
    background-color: lightblue
}

table tr:hover {
    background-color: antiquewhite;
    color: green;
}

table caption {
    font-size: 1.5em;
    font-weight: bolder;
    margin-bottom: 10px;
}

a {
    text-decoration-line: none;
    color: green;
}

table tr td:last-child a:last-child {
    color: red;
}

p {
    text-align: center;
}

form {
    text-align: center
}

以下為項目主目錄app文件:

admin/controller/Index.php

<?php

namespace app\admin\controller;


use app\model\User;
use pong\core\Controller;

class Index extends Controller
{
    public function  __construct()
    {
        parent::__construct();
    }

    public  function  test()
    {
        $name='1pong';

        $this->assign('name',$name);

        $this->fetch(__DIR__ . '/../view/index/test.php');
    }

    //管理員登錄
    public function login()
    {

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            //驗證用戶
            $res = (new User)->get('admin', ['name'],[
                'AND' => [
                    'email' => $_POST['email'],
                    'psword' => $_POST['psword'],
                ]
            ]);

            if (empty($res)) {
                echo "<script>alert('郵箱或密碼不正確');location.href='/';</script>";
            } else {

                $_SESSION['name'] = $res['name'];
                echo "<script>alert('登陸成功');location.href='/';</script>";
            }
        }
    }


    //管理員退出登錄
    public function logout()
    {
        session_destroy();
        echo "<script>alert('退出成功');location.href='/';</script>";
    }

    public  function  index()
    {
//        exit('aaa');

        $rows=(new User())->select('user',['uid','name','phone','weight','height','add_time'],[
            //搜索條件
            'name[~]'=> isset($_POST['name']) ? $_POST['name'] : null
        ]);

        //print_r($rows);

        return $this->view->render('admin::index/index',[
            'rows'=>$rows,
            'title'=>'用戶管理',
            'loginUrl' => '/admin/index/login',
            'logoutUrl' => '/admin/index/logout',
            'indexUrl' => '/admin/index/index',
            'insUrl' => '/admin/index/insert',
            'editUrl' => '/admin/index/edit',
            'delUrl' => '/admin/index/delete',
        ]);

    }

    //添加數(shù)據(jù)
    public function insert()
    {
        return $this->view->render('admin::index/insert', [
            'title' => '添加用戶',
            'url' => '/admin/index/add'
        ]);
    }

    //執(zhí)行添加操作
    public function add()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            //執(zhí)行添加操作
            (new User())->insert('user', [
                'name'=>$_POST['name'],
                'phone'=>$_POST['phone'],
                'weight'=>$_POST['weight'],
                'height'=>$_POST['height'],
                'add_time'=>time(),
            ]);

            echo "<script>alert('添加成功');location.href='/';</script>";
        }
    }


    //填充需編輯的數(shù)據(jù)
    public function edit($id='')
    {
        $row = (new User())->get('user',['uid','name','phone','weight','height'],['uid'=>$id]);

        return $this->view->render('admin::index/edit', [
            'title' => '編輯用戶',
            'url' => '/admin/index/save',
            'row' => $row,
        ]);
    }

    //保存操作
    public function save($id)
    {
        //判斷請求類型,post提交的才執(zhí)行
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {

            //執(zhí)行更新操作
            (new User())->update('user', [
                'name' => $_POST['name'],
                'phone' => $_POST['phone'],
                'weight'=>$_POST['weight'],
                'height'=>$_POST['height'],
            ], ['uid' => $id]);

            //提示用戶信息
            echo "<script>alert('更新成功');location.href='/';</script>";
        }
    }


    //執(zhí)行刪除操作
    public function delete($uid)
    {
        //執(zhí)行刪除操作
        (new User())->delete('user',['uid'=>$uid]);

        //提示用戶信息
        echo "<script>alert('刪除成功');location.href='/';</script>";
    }


}

admin/controller/View/index.php:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="/static/css/style.css">
    <title><?=$this->e($title); ?></title>
</head>
<body>

<?php session_start();?>

<?php isset($_SESSION['name'])?$_SESSION['name']:'' ?>

<?php if(isset($_SESSION['name']) && $_SESSION['name'] =='admin'): ?>
 <p>歡迎: <?=$this->e($_SESSION['name'])?> &nbsp; | &nbsp; <a href="<?=$this->e($logoutUrl)?>">退出</a> </p>
<?php else: ?>

 <form action="<?=$this->e($loginUrl)?>" method="post">
 郵箱: <input type="email" name="email" required>
 密碼: <input type="password" name="psword" required>
        <button>登錄</button>
    </form>

<?php endif; ?>

<table>
    <caption>日本女明星展示表
        <?php if(isset($_SESSION['name']) && $_SESSION['name'] =='admin'): ?>
 <small><a href="<?=$this->e($insUrl)?>">添加</a></small>
 <?php endif; ?>
 </caption>

    <tr><th>ID</th><th>姓名</th><th>手機號</th><th>胸圍</th><th>身高</th><th>注冊時間</th>
 <?php if(isset($_SESSION['name']) && $_SESSION['name'] =='admin'): ?>
 <th>操作</th>
 <?php endif; ?>
 </tr>

 <?php foreach ($rows as $row) : ?>
 <tr>
            <td><?=$this->escape($row['uid'])?></td>
            <td><?php echo $this->escape($row['name']); ?></td>
            <td><?php echo $this->e($row['phone']); ?></td>
            <td><?php echo $this->e($row['weight']); ?></td>
            <td><?=$this->e($row['height'])?></td>
            <td><?=$this->e(date('Y-m-d H:i:s',$row['add_time']))?></td>

 <?php if(isset($_SESSION['name']) && $_SESSION['name'] =='admin'): ?>
 <td><a href="<?=$this->e($editUrl)?>/uid/<?=$this->e($row['uid'])?>">編輯</a>&nbsp; | &nbsp;
 <a href="javascirpt:;" onclick="del(<?=$this->e($row['uid'])?>);return false">刪除</a>
                </td>
 <?php endif; ?>

 </tr>
 <?php endforeach; ?>
</table>

<!--    搜索功能-->
<form action="<?=$this->e($indexUrl)?>" method="post">
 女星名稱: <input type="text" name="name" placeholder="輸入女星關鍵字">
    <button>搜索</button>
</form>


<!--刪除操作-->
<script>
 function del(uid) {
        if (confirm('是否刪除 id='+uid+' 的記錄?')) {
            location.href = '/admin/index/delete/uid/'+uid
        }
    }
</script>
</body>
</html>

admin/controller/View/edit.php:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><?=$this->e($title) ?></title>
</head>
<body>
<style>
 table {
        border:1px solid lightgrey;
 background-color: lightcyan;
 border-radius: 3%;
 box-shadow: 2px 2px 2px #888;
 padding: 20px;
 width: 300px;
 height: 250px;
 margin:30px auto;
 }

    table caption {
        font-size: 1.3em;
 margin-bottom: 10px;
 }

    table tr td:first-child {text-align: center}

    table tr td button {
        width: 100px;
 height: 30px;
 background-color: green;
 color: white;
 border: none;
 }
    table tr td button:hover {cursor: pointer;background-color: lightcoral}

</style>
<form action="<?=$this->e($url)?>/uid/<?=$this->e($row['uid'])?>" method="post">
    <table>
        <caption>編輯女明星</caption>
        <tr>
            <td><label for="name"></label>女星名稱:</td>
            <td><input type="text" name="name" id="name" value="<?=$this->e($row['name'])?>"></td>
        </tr>
        <tr>
            <td><label for="phone"></label>手機號:</td>
            <td><input type="text" name="phone" id="phone" value="<?=$this->e($row['phone'])?>"></td>
        </tr>
        <tr>
            <td><label for="weight"></label>胸圍:</td>
            <td><input type="text" name="weight" id="weight" value="<?=$this->e($row['weight'])?>"></td>
        </tr>
        <tr>
            <td><label for="height"></label>身高:</td>
            <td><input type="text" name="height" id="height" value="<?=$this->e($row['height'])?>" ></td>
        </tr>

        <tr>
            <td colspan="2" align="center"><button>提交</button></td>
        </tr>
    </table>
</form>
</body>
</html>

admin/controller/View/insert.php:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><?=$this->e($title) ?></title>
</head>
<body>
<style>
 table {
        border:1px solid lightgrey;
 background-color: lightcyan;
 border-radius: 3%;
 box-shadow: 2px 2px 2px #888;
 padding: 20px;
 width: 300px;
 height: 250px;
 margin:30px auto;
 }

    table caption {
        font-size: 1.3em;
 margin-bottom: 10px;
 }

    table tr td:first-child {text-align: center}

    table tr td button {
        width: 100px;
 height: 30px;
 background-color: green;
 color: white;
 border: none;
 }
    table tr td button:hover {cursor: pointer;background-color: lightcoral}

</style>
<form action="<?=$this->e($url)?>" method="post">
    <table>
        <caption>添加女明星</caption>
        <tr>
            <td><label for="name"></label>女星名稱:</td>
            <td><input type="text" name="name" id="name" required></td>
        </tr>
        <tr>
            <td><label for="phone"></label>手機號:</td>
            <td><input type="text" name="phone" id="phone"></td>
        </tr>
        <tr>
            <td><label for="weight"></label>胸圍:</td>
            <td><input type="text" name="weight" id="weight" ></td>
        </tr>
        <tr>
            <td><label for="height"></label>身高:</td>
            <td><input type="text" name="height" id="height"></td>
        </tr>
        <tr>
            <td colspan="2" align="center"><button>提交</button></td>
        </tr>
    </table>
</form>
</body>
</html>

效果如下:

QQ截圖20190218161149.jpg

批改老師:天蓬老師批改時間:2019-02-18 17:21:01
老師總結(jié):不論再大的項目, 都是由這些基本的功能組成, 理解了開發(fā)流程, 就好辦了, 這個小框架雖然不具備商業(yè)使用價值,但是用來學習框架開發(fā)入門,足夠了,如果你能完整的寫下來, 再不看教程的情況,自己獨立完成一遍, 那么你的原生php開發(fā)水平, 基本上可以勝任一個程序員的日常工作了

發(fā)布手記

熱門詞條