大师网-带你快速走向大师之路 解决你在学习过程中的疑惑,带你快速进入大师之门。节省时间,提升效率

使用composer搭建自己的项目!【一】

[前言]

以往使用php写原生的语法会发现,很繁杂,如果多个项目需要的人力物力就会巨大,composer包管理就解放我们的生产力,让专业的做专业的事,让全球开发者共同开发,那么项目的功能就只要想拼接积木一般,一点点拼凑起来!。

[前期准备]

我们开始准备最关键的composer! 由于我的环境只有mac并没有windows所以虽然我不能很好解决大家windows安装composer的问题,但是遇到问题可以留言,也可以发送问题到我的邮箱:wujiawie@kalv1n.com.现在我们开始吧!

由于GFW的原因,composer安装可能遇到很慢或者根本无法下载的情况,这里我推荐使用composer中文网.

安装教程在:composer安装教程 我们推荐使用全局安装而不是局部,这样我们就可以省略切换到php目录的这个步骤加快我们的效率!

composer --version

只要保证之后上面命令后不报错我们可以说我们前期的准备已经基本完成了!


我们创建apache虚拟机指向项目目录的public文件夹,让其能访问index.php目录
我们先创建一个项目KAFrame,并在黑窗口(cmd、terminal)切换到项目目录并执行composer init初始化composer!
如果你是使用phpstorm也可以用 command+shift+x (mac)打开terminal 执行,windows-》 ctrl+shift+x 也可以调出。
执行成功后后发现在项目目录多了一个composer.json的文件
在执行composer install 就会生成了一个vendor目录并在里面增加了若干个文件,并在public中创建index.php 入口文件。

我们app里的Entity就是实体的意思就是数据模型,我们在这里的数据模型不区分前台与后台。

<?php
/**
 *
 * index.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午2:32
 */
require '../vendor/autoload.php';

引入composer自动加载文件
在bootstrap创建app.php文件并创建公有静态run方法,注意命名空间为文件夹!:

<?php
/**
 *
 * App.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午2:46
 */
namespace bootstrap;
class App
{
    public static function run(){

    }
}

修改composer.json,增加autoload项,注意composer.json只能用双引号!

{
    "require": {

    },
    "autoload": {
        "psr-4": {
            "App\\\":"app/",
            "bootstrap\\\":"bootstrap/"
        }

    }
}

增加了autoload项 并增加psr-4自动加载规范,这里不详细讲psr-4自动加载规范,请自行百度。 并在psr-4增加 命名空间:目录 对应关系
并在控制台执行 composer dump-autoload 让其读取自动加载生效!(关键!关键!关键!)
然后在public/index.php 增加一行 bootstrap\App::run() 静态调用run方法,然后试着访问框架目录,如无报错,即项目已经生效了!
我们现在来完成路由

[路由]

这里我们路由使用fastrouter——fast-roter的github。github的简介使用命令:

composer require nikic/fast-route

加载fast-router!
等待命令执行成功后。我们在app.php增加定义路径方法(记得以后每定义一个方法必须在run方法中调用!)

public static function denfDir()
    {
        define('ROOT_PATH', dirname(__DIR__) . '/');
        define('CONF_PATH', ROOT_PATH . 'conf/');
        define('RESOURCE', ROOT_PATH . 'resource/');
        define('CACHE', ROOT_PATH . 'caching/');
    }

定义getUrl方法(参数路径对应关系方法!),记得还要在router创建一个web.php!

public static function getUrl(){
    $dispatcher = \FastRoute\simpleDispatcher(function (\FastRoute\RouteCollector $r) {
        include ROOT_PATH . 'router/web.php';
    });
    /** 下面都是基础实现的方法 在fast-router有**/
    // 获取传输类型以及.com后的参数
    $httpMethod = $_SERVER['REQUEST_METHOD'];
    $uri = $_SERVER['REQUEST_URI'];
    // Strip query string (?foo=bar) and decode URI
    if (false !== $pos = strpos($uri, '?')) {
        $uri = substr($uri, 0, $pos);
    }
    $uri = rawurldecode($uri);

    $routeInfo = $dispatcher->dispatch($httpMethod, $uri);
    switch ($routeInfo[0]) {
        case \FastRoute\Dispatcher::NOT_FOUND:
            // ... 404 Not Found
            break;
        case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
            $allowedMethods = $routeInfo[1];
            // ... 405 Method Not Allowed
            break;
        case \FastRoute\Dispatcher::FOUND:
            $handler = $routeInfo[1];
            $vars = $routeInfo[2];
            // ... call $handler with $vars
            break;
    }
    /** 上面都是基础实现的方法 在fast-router有**/
    //把对应的参数与控制器的关系放在静态变量方便分发
    self::$routeInfo = $routeInfo;
    
}

这个时候我们试着在域名后传一个/user 这个时候发现会报404错误,为什么?

由于我们还插一个关键,就是改写路由

增加 .htaccess 路由改写文件内容:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

这个时候我们再访问 : 并打印getUrl中的self::$routeInfo会发现还是为0=》0 为什么?

由于我们上面有一行是include router里面的web.php 就是需要在web.php中建立参数与控制器对应关系。

我们现在在router/web.php增加对应关系。

<?php
/**
 *
 * web.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午3:11
 */
//Param1 : 传值方式: GET/POST 大写
//Param2 : 参数:  / 斜杠就是没有参数(默认参数)
//Param3 : 命名空间+控制器@方法名:  这里我们后面会在dispath方法中定义默认在App/Controller、所以可以省略一部分命名空间
$r->addRoute('GET', '/', 'Back/view/IndexController@showIndex');

//这个时候再打印getUrl中的self::$routeInfo,结果:
//php
//array(3) { [0]=> int(1) [1]=> string(35) "Back/view/IndexController@showIndex" [2]=> array(0) { } }

这里我们暂停一下,我们发现默认的php报错很丑,于是composer 有位大神开发出好看的报错的Error扩展包——whoops!
根据其github的简介加载

composer require filp/whoops

并加载一个 读取配置的包:——config

composer require hassankhan/config

并在根目录创建一个类库libs,我由于时间关系封装了一个读取配置文件的类:Conf

<?php
/**
 *
 * Conf.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午3:56
 */
namespace libs;
use Noodlehaus\Config;

class Conf
{
    public static function all(){
        $conf=new Config(CONF_PATH);
        return $conf->all();
    }
    public static function get($conf_key){
        $conf=new Config(CONF_PATH);
        return $conf->get($conf_key);
    }

我们在conf创建app.php创建我们第一个配置项:

<?php
/**
 *
 * app.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午3:54
 */
return [
//我们在开发所以是true,开发模式
    'debug'=>true,
];

这样我们可以在app.php定义一个whoops_error方法并调用:

public static function whoops_error()
{
    //  whoops报错插件
    //根据app.php中的debug判断是否报错
    $bool = Conf::get('debug');
    if ($bool) {
        $whoops = new \Whoops\Run;
        $errorTitle = '框架出错了!';
        $option = new \Whoops\Handler\PrettyPageHandler();
        $option->setPageTitle($errorTitle);
        $whoops->pushHandler($option);
        $whoops->register();
        ini_set('display_error', 'On');
    } else {
        ini_set('display_error', 'Off');
    }

}

我们会发现报错libs\Conf 不存在?其实是libs并不在自动加载的行列,老方法,在composer。json加入libs加载项并执行 composer dump-autoload:

{
    "require": {
        "nikic/fast-route": "^1.2",
        "filp/whoops": "^2.1",
        "hassankhan/config": "^0.11.2"
    },
    "autoload": {
        "psr-4": {
            "App\\":"app/",
            "bootstrap\\":"bootstrap/",
            "libs\\":"libs/"
        }

    }
}

这个时候我们还不知道这个报错有没有用?

我们测试下,在run里面whoops_error后写一个echo aaa; 未定义变量看结果

我们看到结果比以前好看多了,这个时候我们whoop_error 成功了!不过致命错误是无法走这个的哦!

我们继续路由,上面我们定义了错误,读取了配置文件,获取到url ,做了三件事。

现在我们拿到了参数与控制器方法的对应关系,现在我们需要根据参数new控制器以及调用方法

/**
 *  分发路由
 */
public static function Route()
{

    if (self::$routeInfo[0] !=0){
        //把方法、控制器根据@符号炸开
        $routerMessage = explode('@', self::$routeInfo[1]);
        //由于我们控制都是在app/的Controller里面我们这里为什么可以大写由于自动加载做了对应关系
        $controller = 'App\\Controller\\' . $routerMessage[0];
        $controller = str_replace('/','\\',$controller);
        $action = $routerMessage[1];
        $obj = new $controller;
        $obj->$action();
    }else{
        throw new ErrorException('路由错误!请检查路由是否正确!');
    }
}

app/Controller/Back/View/IndexControlelr.php

<?php
/**
 *
 * IndexController.php
 * User: kalvin
 * Date: 2018/2/5
 * Time: 下午4:22
 */

namespace App\\Controller\\Back\\View;


class IndexController
{
    public function showIndex()
    {
        
    }
}

这个时候我每次新增方法的时候记得在router/web.php 增添对应关系并新建控制器与方法!

如果觉得我的文章对你有帮助又或者喜欢,别忘了关注.喜欢加转发,当然如果可以打赏我一下奶茶钱也是可以的哦(#.#)