一、composer的介绍和laravel的关系
laravel开发模式就是一种组件化的开发模式,把整个框架拆分为不同的单独的零件,每一个零件实际上就是一个单独的组件,每一个组件你都可以在composer的资源包中查中到
然后可以在 https://packagist.org 查找到这个组件
composer工作原理
它主要由三个部分组成:命令行工具、包仓库、代码库:
packagist:
它是官方仓库,也就是我们平常说的composer源,它的作用是存储这些包的信息,版本,代码来源,依赖,作者,主页等信息,官网是 https://packagist.ord/ 你也可以将自己的包发布在上面,这样composer工具就能搜索与安装你的包。
Repository:
代码仓库,Packagist支持公开私有的仓库,通常是Github作为代码仓库,当然也可以是BitBucket 或则 gitlab
Vendor directory:
我们的composer依赖包都统一安装在项目的vendor目录下,其中还有vendor/composer目录用于存储依赖包的一些基本信息,比如命名空间等。
composer目录结构:
vendor/
├── .editorconfig # 编辑器配置文件,比如缩进大小、换行模式等
├── .gitattributes # git 配置文件,可以设计导出时忽略文件等
├── .gitignore # git 忽略文件配置列表
├── .php_cs # PHP-CS-Fixer 配置文件
├── README.md
├── composer.json
├── phpunit.xml.dist
├── src # 源代码核心目录
│ └── .gitkeep
└── tests # 用于存放单元测试或者功能测试的测试用例代码,与 src 组织规则基本一致
└── .gitkeep
引入第三方写好的组件,构建composer包工具
# 引入第三方构建好的composer包
composer global require "overtrue/package-builder" -- prefer-source
#构建composer自定义组件目录
package-builder build [目标目录名]
3 开发laravel简化版的单元测试组件 - 构建
3.1:构建项目
package-builder build andrew/zjunit-laravel # 注意必须使用正斜杠
Name of package (example: foo/bar): andrew/zjuint-laravel
Namespace of package [Andrew\ZjuintLaravel]: Andrew\ZJunitLaravel
Description of package: A simplified version of the laravel framework unit test
Author name of package [L1_Zi]: Andrew
Author email of package [L1_ZiYuan@163.com]:
License of package [MIT]:
Do you want to test this package ? [Y/n]: n
Do you want to use php-cs-fixer format your code ? [Y/n]:n
# 引入第三方构建好的composer包
$ composer global require "overtrue/package-builder" --prefer-source
# 构建composer 组件项目
$ package-builder build [目标目录名]
以上命令相当于 composer init 只是比composer init 目录比较全面
构建成功后的目录
这个组件是要开发一个测试单元测试,而需要几个功能最为重要的基于laravel来看就是需要视图和路由,如果对于没有开发过组件的小伙伴来说,可以参考别人是怎么操作怎么写。
先简单做一个测试,访问到创建的组件
而里面的命名空间则是 你组件目录中 composer.jsoin中的autoload - psr-4 的值
在此创建成功后,必须在目录中 使用 composer update 加载composer vendor资源
composer update 成功后,目录中会多出一个vendor目录存在
然后再创建一个随意的入口文件,测试刚刚创建的控制器
必须引入vendor里面的autoload.php加载文件,然后use 导入测试控制器的命名空间,再测试,如果没有出现任何问题,则是调用成功
正式进入自定义环节(所有创建都必须引入 composer.json中的命名空间)
把基本的目录结构搭建好
需要 src\Http\Controllers\ZJunitControler.php
视图:src\resources\view\index,blade.php
路由 src\Http\routes.php
src 里面专门存放php逻辑代码,而resources 存放的是视图资源
首先先创建好几个目录结构
1. 创建控制器(注意:要继承laravel的父类控制器)
<?php
namespace Andrew\ZJunitLarave\Http\Controllers;
/**
* 而这里是laravel中的组件,也要继承laravel的控制器
*/
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
class ZJunitController extends Controller
{
/**
* 渲染页面
* @return mixed
*/
public function index()
{
// 而 qjunit则是服务提供者类中引入 视图时的别名
return view('qjunit::index');
}
/**
* 提交测试的方法
* @param Request $request
* @return string
*/
public function store(Request $request)
{
$namespace = $request->input('namespace');
$className = $request->input('className');
$action = $request->input('action');
$param = $request->input('param');
$class = ($className == "") ? $namespace : $namespace.'\\'.$className;
// 要提换的值 需要的结果
$class = str_replace("/", "\\", $class);
$object = new $class();
$param = ($param == "") ? [] : explode('|', $param) ;
$data = call_user_func_array([$object, $action], $param);
return (is_array($data)) ? json_encode($data) : dd($data);
}
}
创建resources\view\index.blade.php视图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>不区分大小写(可以自行完善)</h1>
<br>
<form class="" action="{{route('qjunit.store')}}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
命名空间:<input type="text" value='' style="width:300px" name='namespace' placeholder="如:app\index\controller 或app\index\controller\Index">可以写全,然后下面类名不用些 <br>
类名:<input type="text" name='className' placeholder="如:index ">命名空间全可以不用写<br>
测试方法名:<input type="text" name='action' placeholder="index"><br>
传递参数以 | 分割:<input type="text" placeholder="如: 1|2|3" name='param'><br>
<input type="submit" name="" value="测试"/>
</form>
</body>
</html>
创建路由
<?php
Route::get('zjunit', 'ZJunitController@index');
那么这里有一个问题,怎么跟laravel继承绑定在一起呢
实际上像Laravel的这些组件都是通过laravel的服务容器进行加载的,然后启动laravel时候执行laravel的这些服务容器的boot方法加载路由以及视图(也就是,放在laravel服务提供者中,laravel启动就自动帮我们加载服务)
首先先将测定组件绑定到需要laravel的框架中
配置包路径,注意,这里 `../junit-laravel` 为相对路径,不要弄错了
$ composer config repositories.shineyork path ../../junit-laravel
创建成功后,会再laravel中的composer.json 添加一个值指向到测试组件中
再引入测试composer组件
# 安装扩展包
$ composer require shineyork/junit-laravel:dev-master
这个是用于本地测试,如果没有加这个加载扩张包的话会报错,因为再包仓库中找不到该资源,所以加上是为了测试使用,发布成功后,就可以不用加
请注意:请输入你的组件名称进行引入
引入成功后,会再laravel目录中出现你的组件
组件添加服务提供者(让laravel使用我们自定义的组件)
<?php
namespace Andrew\ZJunitLaravel;
/**
* 需要继承laravel的服务提供者类,模仿laravel其他的服务提供者类使用
*/
use Illuminate\Support\ServiceProvider;
class ZJunitServiceProvice extends ServiceProvider
{
public function register()
{
}
/**
* 当laravel启动时,自动执行的方法
*/
public function boot()
{
}
}
然后再需要引入组件的laravel的config\app.php 文件中添加这个服务提供者
测试一下,再boot方法中写一个测试代码,检测laravel启动时是否已经执行
/**
* 当laravel启动时,自动执行的方法
*/
public function boot()
{
echo '我是自定义组件';
}
如上所见,是已经成功。
然而,我们再boot方法中,引入路由以及视图的渲染
laravel/telescope 模仿这个组件的使用路由以及视图的方式,(这个只是一个测试组件)
<?php
namespace Andrew\WJunitLaravel;
/**
* 需要继承laravel的服务提供者类,模仿laravel其他的服务提供者类使用
*/
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;
class WJunitServiceProvice extends ServiceProvider
{
public function register()
{
}
/**
* 当laravel启动时,自动执行的方法
*/
public function boot()
{
$this->registerRoutes();
// 引入视图
$this->loadViewsFrom(
__DIR__.'../../resources/views', 'wjunit'
);
}
/**
* Register the package routes.
* 注册包路由
* @return void
*/
private function registerRoutes()
{
Route::group($this->routeConfiguration(), function () {
$this->loadRoutesFrom(__DIR__.'/Http/routes.php');
});
}
/**
* Get the Telescope route group configuration array.
* 获取望远镜路由组配置阵列
* @return array
*/
private function routeConfiguration()
{
return [
// 域名
// 'domain' => config('telescope.domain', null),
// 命名空间
'namespace' => 'Andrew\WJunitLaravel\Http\Controllers',
// 后缀
'prefix' => 'wjunit',
// 中间件
'middleware' => 'web',
];
}
}
所有再测试组件中编辑的代码都会自动同步到laravel中的测试组件中去
然后使用 php artisan route:list 路由使用
+--------+----------+---------------+--------------+--------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+---------------+--------------+--------------------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | wjunit/wjunit | | Andrew\WJunitLaravel\Http\Controllers\WJunitController@index | web |
| | POST | wjunit/wjunit | wjunit.store | Andrew\WJunitLaravel\Http\Controllers\WJunitController@index | web |
+--------+----------+---------------+--------------+--------------------------------------------------------------+--------------+
最后测试
使用 路由访问:http://laravel58.cn/index.php/wjunit/wjunit 出现如下,则证明成功