Wallogit.com
                    
                    2017 © Pedro Peláez
                    
                    
                    
                    
                
                
            
c89框架系统
项目提交composer的packagist
项目提交至github
github注册账号
创建一个项目
, (*1)
安装composer, (*2)
composer init 初始化项目composer init初始化之后会自动声场vendor目录以及composer.json文件
|--app(开发者写代码的地方) | |--home(前台模块) | | |--controller(控制器类) | | |--view(视图) |--houdunwang(系统核心) | |--core | |--model | |--view |--public(入口、静态资源) | |--static(静态资源) | |--view(公共模板文件) |--system(配置) | |--config (配置项) | |--model (处理业务的各种模型类)
MVC M---model V--view C--controller###3.创建框架的启动类houdunwang\core\Boot.php类`类名和文件名首字母大写`<?php //命名空间 namespace houdunwang\core; class Boot { public static function run () { echo 'run'; } }
<?php
namespace houdunwang\core;
class Boot
{
    public static function run ()
    {
        //错误处理
        self::handler();
        //初始化框架
        self::init();
        //执行应用
        self::appRun ();
    }
    public static function handler(){
        $whoops = new \Whoops\Run;
        $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
        $whoops->register();
    }
    public static function init()
    {
        session_id () || session_start ();
        date_default_timezone_set ('PRC');
    }
    public static function appRun ()
    {
        if ( isset( $_GET[ 's' ] ) ) {
            $info = explode ('/',$_GET['s']);
            $info[1] = ucfirst ($info[1]);
            $class = "\app\\{$info[0]}\controller\\{$info[1]}";
            $action = $info[2];
            define ('MODULE',strtolower ($info[0]));
            define ('CONTROLLER',lcfirst ($info[1]));
            define ('ACTION',$info[2]);
        } else {
            $class = "\app\home\controller\Entry";
            $action = "index";
            define ('MODULE','home');
            define ('CONTROLLER','entry');
            define ('ACTION',$action);
        }
        echo call_user_func_array ( [ new $class , $action ] , [] );
        exit;
    }
}
<?php require_once '../vendor/autoload.php'; \houdunwang\core\Boot::run ();
这个时候报错:, (*3)
Fatal error: Class 'houdunwang\core\Boot' not found in /Applications/MAMP/htdocs/frame/public/index.php on line 3
因为类加载使用时需满足:include加载文件和导入命名空间
继续往下解决这个问题, (*4)
修改composer.json文件。注意autoload该项需自己增加, (*5)
{
    "name": "chaorenwubin/frame",
    "description": "后盾网php框架系统",
    "type": "project",
    "licence":"MIT",
    "authors": [
        {
            "name": "武斌",
            "email": "wubin.mail@foxmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload":{
        "files":[],
        "psr-4":{
           "houdunwang\\":"houdunwang\\",
           "app\\":"app\\"
        }
    }
}
PSR-4, (*6)
1.是制定的代码规范,简称PSR,是代码开发的事实标准 2.PSR-4使代码更加规范,能够满足面向package的自动加载,它规范了如何从文件路径自动加载类,同时规范了自动加载文件的位置 3.如果是: "houdunwang\\":"houdunwang\\",当实例化\houdunwang\core\Boot类时,会加载houdunwang/core/Boot.php 4.如果是: "houdunwang\\":"hdphp\\",当实例化\houdunwang\core\Boot类时,hdphp/core/Boot.php 5.如果是: "houdunwang\\":"",当实例化\houdunwang\core\Boot类时,Boot.php 5.反斜线是转义
生成composer自动载入文件,在Terminal中进入项目跟目录执行:, (*7)
composer dump
这时,访问项目入口public文件输出run, (*8)
引入助手函数, (*9)
1.将以前我们写的helper.php文件放入system/helper.php
2.修改composer.json文件中autoload项的files
"autoload":{
        "files":[
            "system/helper.php"
        ],
        "psr-4":{
           "houdunwang\\":"houdunwang\\",
           "app\\":"app\\"
        }
}
3.在Teminal终端执行composer dump
appRun方法具体代码, (*10)
public static function appRun ()
    {
        if(isset($_GET['s'])){
            //通过?s=模块/控制器/方法(?s=home/entry/index)进行访问
            //接受get参数s,并将其转为数组
            $info = explode ('/',$_GET['s']);
            //dd($info);
            $info[1] = ucfirst ($info[1]);
            //dd($info);
            $c = "app\\{$info[0]}\controller\\{$info[1]}";
            $a  = $info[2];
            define ('MODULE',strtolower ($info[0]));
            define ('CONTROLLER',strtolower ($c));
            define ('ACTION',$a);
        }else{
            $c = "\app\home\controller\\entry";//控制器类
            $a = 'index';//方法
            define ('MODULE','home');
            define ('CONTROLLER','entry');
            define ('ACTION',$a);
        }
        return call_user_func_array ([new $c,$a],[]);
    }
在app/home/controller中创建Entry.php, (*11)
<?php
namespace app\home\controller;
class Entry
{
    public function index(){
        echo 'Welcome';
    }
}
通过地址栏访问public或public/index.php或public/index.php?s=home/entry/index
也可通过尝试其他地址访问,如:public/index.php?s=home/entry/store
浏览器正常输出Welcome, (*12)
public/view放入message.php模板文件
, (*13)
自己参考代码
在 core 目录中创建Controller.php,并让app\home\controller\Entry.php及以后类继承Controller, (*14)
<?php
namespace houdunwang\core;
class Controller
{
    private $url;
    protected function message($msg){
        include './view/message.php';
        exit;
    }
    protected function setRedirect($url = ''){
        if($url){
            $this->url = "location.href='$url'";
        }else{
            $this->url = "window.history.back()";
        }
        return $this
    }
}
app/controller/Entry.php,中增加store方法进行测试,增加store方法进行测试
通过地址栏访问store方法:public/index.php?s=home/entry/store
可看到提示页面,3秒之后自动跳转, (*15)
<?php
namespace app\home\controller;
use houdunwang\core\Controller;
class Entry extends Controller
{
    public function index(){
        echo 'Welcome';
    }
    public function store(){
        $this->setRedirect ('?s=home/entry/index')->message ('添加成功');
    }
}
在core/view目录中建立View.php和Base.php
View.php, (*16)
<?php
namespace houdunwang\view;
class View
{
    public function __call ( $name , $arguments )
    {
        // TODO: Implement __call() method.
        return self::parseAction ( $name , $arguments );
    }
    public static function __callStatic ( $name , $arguments )
    {
        // TODO: Implement __callStatic() method.
        return self::parseAction ( $name , $arguments );
    }
    public static function parseAction ( $name , $arguments )
    {
        return call_user_func_array ( [ new Base , $name ] , $arguments );
    }
}
Base.php, (*17)
<?php
namespace houdunwang\view;
class Base
{
    private $file;
    private $data;
    public function make ()
    {
        $this->file = "../app/" . MODULE . '/view/' . CONTROLLER . '/' . ACTION . '.php';
        return $this;         
    }
    public function with ( $var )
    {
        $this->data = $var;
        return $this;
    }
    //当输出对象的时候出发,比如说echo $obj->make();
    public function __toString ()
    {
        // TODO: Implement __toString() method.
        extract ($this->data);
        include $this->file;
        return '';
    }
}
数据库配置项文件system/config/database.php, (*18)
<?php
return [
    'driver'=>'mysql',
    'host'     => '127.0.0.1',
    'user'     => 'root',
    'password' => 'root',
    'dbname'     => '',
];
system/helper.php助手函数中增加加载配置项的c函数, (*19)
function c ( $path )
    {
        $info   = explode ( '.' , $path );
        $config = include "../system/config/" . $info[ 0 ] . '.php';
        return isset( $config[ $info[ 1 ] ] ) ? $config[ $info[ 1 ] ] : null;
    }
houdunwang/model/Model.php, (*20)
<?php
namespace houdunwang\model;
class Model
{
    /**
     * @param $name
     * @param $arguments
     */
    public function __call ( $name , $arguments )
    {
        // TODO: Implement __call() method.
        return self::parseAction ( $name , $arguments );
    }
    /**
     * @param $name
     * @param $arguments
     */
    public static function __callStatic ( $name , $arguments )
    {
        // TODO: Implement __callStatic() method.
        return self::parseAction ( $name , $arguments );
    }
    /**
     * @param $name
     * @param $arguments
     *
     * @return mixed
     */
    public static function parseAction ( $name , $arguments )
    {
        $class = get_called_class ();
        return call_user_func_array ( [ new Base($class) , $name ] , $arguments );
    }
}
base.php, (*21)
<?php
namespace houdunwang\model;
use PDO;
use PDOException;
use Exception;
/**
 * 模型基础类
 * Class Base
 *
 * @package houdunwang\model
 */
class Base
{
    protected $pdo;
    public function __construct ( $class )
    {
        //1.链接数据库
        $this->connect ();
        //$class打印结果:system\model\Article
        $class       = explode ( '\\' , $class );
        $this->table = strtolower ( $class[ 2 ] );
    }
    private function connect ()
    {
        $dsn      = c ( 'database.driver' ) . ":host=" . c ( 'database.host' ) . ";dbname=" . c ( 'database.dbname' );
        $user     = c ( 'database.user' );
        $password = c ( 'database.password' );
        try {
            $this->pdo = new PDO( $dsn , $user , $password );//链接数据库
            $this->pdo->query ( 'SET NAMES UTF8' );//设置字符集
            //设置错误属性
            $this->pdo->setAttribute ( PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION );
        } catch ( PDOException $e ) {
            //输出错误
            exit( $e->getMessage () );
        }
    }
    /**
     * 执行有结果集的查询
     *
     * @param $sql  查询的sql语句
     *
     * @return mixed  查询结果结
     */
    public function query ( $sql )
    {
        try {
            $res = $this->pdo->query ( $sql );
            return $res->fetchAll ( PDO::FETCH_ASSOC );
        } catch ( PDOException $e ) {
            throw new Exception( "sql:{$sql} | " . $e->getMessage () );
        }
    }
    public function exec ( $sql )
    {
        try {
            $affectedRows = $this->pdo->exec ( $sql );
            if ( $lastInsertId = $this->pdo->lastInsertId () ) {
                //返回自增id
                return $lastInsertId;
            } else {//否则返回受影响的条数
                return $affectedRows;
            }
        } catch ( PDOException $e ) {
            throw new Exception( "sql:{$sql} | " . $e->getMessage () );
        }
    }
}
需要在system/model建立Article.php进行协助测试测试,Article.php名字不是固定的, (*22)
<?php
namespace system\model;
use houdunwang\model\Model;
class Article extends Model
{
}
在Entry.php中进行测试,注意system中的类不会自动进行加载,需要修改composer.json配置项, (*23)
"autoload":{
        "files":[
            "system/helper.php"
        ],
        "psr-4":{
            "houdunwang\\":"houdunwang",
            "app\\":"app\\",
            "system\\":"system\\"
        }
    }
然后执行, (*24)
composer dump
composer的packagist(https://packagist.org/)搜索:whoop
选择第一个:filp/whoops
进入到项目根目录执行:, (*25)
composer require filp/whoops
在houdunwang/core/Boot.php中加入, (*26)
$whoops = new \Whoops\Run; $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); $whoops->register();
推送上到composer仓库之后即可以下载了, (*27)
composer create-project chaorenwubin/frame frame dev-master --prefer-dist