Laravel 5.3框架-多项目公用框架-架构设计方案

PHP 专栏收录该内容
1 篇文章 0 订阅

前言

该文章内容仅限于互相探讨与学习。希望为普及LaravelPHP编程思想出一份力!

正题

由于最近一些朋友在使用laravel框架的时候碰到了一个非必须解决的问题,可能也是有存在一部分强迫症的原因吧。

具体需求是这样的。

Laravel框架是基于Composer设计的,项目所依赖的文件非常的多,同时在web根目录下会有着一箩筐的文件,单单vendor文件夹里有着5000+的文件。看起来不美观的同时,每一次新建一个项目,都必须重新导入laravel框架放在根目录下。对于项目的建立管理也是不方便的。于是朋友们提出了一个需求,希望laravel的框架独立,多项目共用框架,目录结构干净等等。

虽然这个需求多多少少是偏离了laravel本身的设计思路和结构,但是用过CodeIgniter,ThinkPHP的开发者一定还是受不了这样的结构方式吧。有种一进门就眼花缭乱的感觉。(当然,题外话。用了那么多的PHP框架,个人还是觉得TP框架更适合新手,成本更低,更加适合创业型公司。同时,看了ThinkPHP7新的结构,特别期待它的完善)

虽然我在两年前碰过laravel,但是那时候并非比较主流的框架,就随便看了看。所以,我用laravel最新的5.3做个结构改变的方案供大家学习。有什么不对的地方可以留言,欢迎探讨。

我也在业余时间帮朋友把Laravel框架重新进行了调整,以适应他们的需求。

有兴趣的朋友可以去github下载来看看。

https://github.com/lynk-coder/lynk-public-laravel/

教程

那么我们先看看最终改成的目录结构会变成什么样子:



这么做的目的,是将我们可爱的laravel框架彻底分割出去,同时根据自己的需求去切换自己项目所需求的框架。那么我们开始进行一步步的修改和调整。

首先我们要保证PHP在5.6及以上的版本。

我们先从项目基本结构先改,然后再修改框架。

1、<project>/public/index.php

我们在public文件夹里,把index.php进行一些修改。

我们在代码里面加入一些内容,这三段代码放在最开头的位置

define('APPLICATION_WEB_ROOT',__DIR__."/../"); 
define('LARAVEL_FRAMEWORK_DIR',APPLICATION_WEB_ROOT.'/../framework/laravel5.3');
require APPLICATION_WEB_ROOT.'/../vendor/autoload.php';


其次,我们将原来的

require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';

改成

require LARAVEL_FRAMEWORK_DIR.'/bootstrap/autoload.php';
$app = require_once LARAVEL_FRAMEWORK_DIR.'/bootstrap/app.php';

这样,我们的index.php改好了。


2、我们在< project >的同级目录下,新建framework,在framework下面建立laravel5.3目录,将bootstrap,vendor(框架文件),.env移动到laravel5.3目录里面,同时新建目录common


 

3、我们在< project >下面建立目录vendor,将config,database,resources,storage移动到vendor目录下面。



4、修改framwork/laravel5.3/vendor/laravel/framework/src/Illuminate/Foundation/Application.php的内容。这个文件是项目初始化用的,其中包含大多数路径信息。

在文件头部定义一个受保护的变量。

/**
 * 自定义web目录变量
 *
 * @var string
 */
protected $webPath;


在文件方法中定义getter和setter

/**
 * 设置web目录路径
 *
 * @param $webPath
 * @return $this
 */
public function setWebPath($webPath)
{
    $this->webPath = rtrim($webPath, '\/');

    return $this;
}

/**
 * 获取web目录路径
 * @return string
 */
public function webPath()
{
    return $this->webPath;
}


将__construct方法改成

public function __construct($webPath = null,$basePath=null)
{
    $this->registerBaseBindings();

    $this->registerBaseServiceProviders();

    $this->registerCoreContainerAliases();
    if ($webPath) {
        $this->setWebPath($webPath);
    }

    if ($basePath) {
        $this->setBasePath($basePath);
    }
}


将方法bindPathsInContainer改成

protected function bindPathsInContainer()
{
    $this->instance('path', $this->path());
    $this->instance('path.base', $this->basePath());
    $this->instance('path.lang', $this->langPath());
    $this->instance('path.config', $this->configPath());
    $this->instance('path.public', $this->publicPath());
    $this->instance('path.storage', $this->storagePath());
    $this->instance('path.database', $this->databasePath());
    $this->instance('path.bootstrap', $this->bootstrapPath());
    $this->instance('path.web', $this->webPath());
}


将方法path改成

public function path()
{
    return $this->webPath.DIRECTORY_SEPARATOR.'app';
}

将方法 configPath改成

public function configPath()
{
    return $this->webPath.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'config';
}


将databasepath改成

public function databasePath()
{
    return $this->databasePath ?: $this->webPath.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'database';
}

将langPath改成

public function langPath()
{
    return $this->webPath.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'lang';
}

将publicPath改成

public function publicPath()
{
    return $this->webPath.DIRECTORY_SEPARATOR.'public';
}

将storagePath改成

public function storagePath()
{
    return $this->storagePath ?: $this->webPath.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'storage';
}

将getNamespace改成

public function getNamespace()
{
    if (! is_null($this->namespace)) {
        return $this->namespace;
    }

    $composer = json_decode(file_get_contents(web_path('composer.json')), true);

    foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) {
        foreach ((array) $path as $pathChoice) {
            if (realpath(app_path()) == realpath(web_path().'/'.$pathChoice)) {
                return $this->namespace = $namespace;
            }
        }
    }

    throw new RuntimeException('Unable to detect application namespace.');
}


这时候我们的Application.php改好了。


5、修改framwork/laravel5.3/vendor/laravel/framework/src/Illuminate/Foundation/helper.php

新增方法

if (! function_exists('web_path')) {
    /**
     * Get the path to the base of the install.
     *
     * @param  string  $path
     * @return string
     */
    function web_path($path = '')
    {
        return app()->webPath().($path ? DIRECTORY_SEPARATOR.$path : $path);
    }
}


6、对framwork/laravel5.3/bootstrap/app.php进行修改


$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

改成
if(!defined('APPLICATION_WEB_ROOT')){
    exit("未定义 ‘APPLICATION_WEB_ROOT’ 常量");
}
$app = new Illuminate\Foundation\Application(
    realpath(APPLICATION_WEB_ROOT),
    realpath(__DIR__."/../")
);

7、framwork/laravel5.3/bootstrap/autoload.php文件不需要修改,因为已经指向了对应的框架加载的目录


8、修改framwork/laravel5.3/vendor/laravel/framework/src/Illuminate/Auth/Console/MakeAuthCommand.php


public function fire()
{
    $this->createDirectories();

    $this->exportViews();

    if (! $this->option('views')) {
        file_put_contents(
            app_path('Http/Controllers/HomeController.php'),
            $this->compileControllerStub()
        );
        file_put_contents(
            base_path('routes/web.php'),
            file_get_contents(__DIR__.'/stubs/make/routes.stub'),
            FILE_APPEND
        );
    }
    $this->info('Authentication scaffolding generated successfully.');
}

改为

public function fire()
{
    $this->createDirectories();

    $this->exportViews();

    if (! $this->option('views')) {
        file_put_contents(
            app_path('Http/Controllers/HomeController.php'),
            $this->compileControllerStub()
        );
        file_put_contents(
            web_path('routes/web.php'),
            file_get_contents(__DIR__.'/stubs/make/routes.stub'),
            FILE_APPEND
        );
    }
    $this->info('Authentication scaffolding generated successfully.');
}


protected function createDirectories()
{
    if (! is_dir(base_path('resources/views/layouts'))) {
        mkdir(base _path('resources/views/layouts'), 0755, true);
    }

    if (! is_dir(base _path('resources/views/auth/passwords'))) {
        mkdir(base _path('resources/views/auth/passwords'), 0755, true);
    }
}


改为

protected function createDirectories()
{
    if (! is_dir(web_path('resources/views/layouts'))) {
        mkdir(web_path('resources/views/layouts'), 0755, true);
    }

    if (! is_dir(web_path('resources/views/auth/passwords'))) {
        mkdir(web_path('resources/views/auth/passwords'), 0755, true);
    }
}


protected function exportViews()
{
    foreach ($this->views as $key => $value) {
        copy(
            __DIR__.'/stubs/make/views/'.$key,
            base_path('resources/views/'.$value)
        );
    }
}

改为

protected function exportViews()
{
    foreach ($this->views as $key => $value) {
        copy(
            __DIR__.'/stubs/make/views/'.$key,
            web_path('resources/views/'.$value)
        );
    }
}



9、修改<project>/app/Console/Kernel.php

protected function commands()
{
    require base_path('routes/console.php');
}

改为

protected function commands()
{
    require web_path('routes/console.php');
}

10、修改<project>/app/Providers/RouteServiceProviders.php

protected function mapWebRoutes()
{
    Route::group([
        'middleware' => 'web',
        'namespace' => $this->namespace,
    ], function ($router) {
        require base_path('routes/web.php');
    });
}



改为

protected function mapWebRoutes()
{
    Route::group([
        'middleware' => 'web',
        'namespace' => $this->namespace,
    ], function ($router) {
        require web_path('routes/web.php');
    });
}


protected function mapApiRoutes()
{
    Route::group([
        'middleware' => 'api',
        'namespace' => $this->namespace,
        'prefix' => 'api',
    ], function ($router) {
        require base_path('routes/api.php');
    });
}

改成

protected function mapApiRoutes()
{
    Route::group([
        'middleware' => 'api',
        'namespace' => $this->namespace,
        'prefix' => 'api',
    ], function ($router) {
        require web_path('routes/api.php');
    });
}


11、修改<project>/vendor/config/view.php

'paths' => [
    realpath(base_path('/resources/views')),
]

改成

'paths' => [
    realpath(web_path('vendor/resources/views')),
]


以上的11部操作只是纯粹的对文件的内容进行了修改,接下来我们来一个最核心的修改,composer!!!!


1、我们要在<project>目录下新建文件composer.json

       加入如下内容 :

{
    "name": "lynk-public-laravel",
    "description": "public laravel framework project",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.3.*",
        "guzzlehttp/guzzle": "^6.2",
        "firebase/php-jwt": "^4.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.0",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "vendor/database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "classmap": [
        ]
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}


2、我们在framework/laravel5.3目录下新建文件composer.json

加入如下内容:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.3.*",
        "guzzlehttp/guzzle": "^6.2",
        "firebase/php-jwt": "^4.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.0",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
        ],
        "psr-4": {
        }
    },
    "autoload-dev": {
        "classmap": [
        ]
    },
    "scripts": {
        "post-root-package-install": [
        ],
        "post-create-project-cmd": [
        ],
        "post-install-cmd": [
        ],
        "post-update-cmd": [
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}



3、我们在<project>目录下执行:

composer dumpautoload

重新编译项目的注入文件

4、我们在framework/laravel5.3目录下执行:

composer dumpautoload –o

重新编译框架的注入文件


以上四部基本完成了改变lavavel框架特性的方法,但是还没完,我们最重要的artisan还没有调整呢!

我们将artisan移动到<project>目录下。然后修改artisan文件。

1、在文件开发加上三句语句

define('APPLICATION_WEB_ROOT',__DIR__);
define('LARAVEL_FRAMEWORK_DIR',APPLICATION_WEB_ROOT.'/../framework/laravel5.3');
require APPLICATION_WEB_ROOT.'/vendor/autoload.php';

2、将之前的内容改为

require LARAVEL_FRAMEWORK_DIR.'/bootstrap/autoload.php';
$app = require_once LARAVEL_FRAMEWORK_DIR.'/bootstrap/app.php';

之后,我们就可以使用artisan了




扩展


最后,可能有些人需要在框架里面写入一些公用方法。

这时候我们可以在framework/laravel5.3/下面建立一个common文件夹,





然后我们修改framework/laravel5.3/composer.json文件

"autoload": {
    "classmap": [
    ],
    "psr-4": {
    }
},

改为

"autoload": {
    "classmap": [
    ],
    "psr-4": {
        "Common\\": "common/"
    }
},


到framework/laravel5.3/目录下执行

composer dumpautoload -o 

重新编译注入文件。

这时候,我们将framework/laravel5.3/common注入到了整个框架之中,自行定义好common里的文件的命名空间,就可以直接使用我们自己的自定义方法了。当然,common文件夹里的所有文件都可以被注入到项目,跟文件名无关。

假如,你的common文件夹有 func1.php,func2.php,func3.php三个文件,那么这些文件都会被自动注入到项目中的。

 

 

以上内容就是对我们laravel框架的修改方法。将laravel打造成公用的框架,同时相对原始的版本会更加简洁和干净。


如有疑问可以下方留言哦~
















  • 0
    点赞
  • 2
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值