如何在Laravel(5.6版本)中创建包(package)

良好软件设计的一个标志是代码的模块化和可维护性。在Laravel中,将几段代码分组到一个可以重用的逻辑模块中称为“包(package)”。

今天,我们来看看如何从头开始在Laravel 5.6中创建我们自己的包。别让这件事动摇你。创建一个包并不像看起来那么复杂。这里有几个简单的步骤,您可以使用它们创建自己的包。

当然,没有创建通用包的诀窍,因此作为一个示例,让我们尝试创建一个“To Do List”包。

在这个示例的过程中,我们将介绍迁移(migrations)、路由(routes)、视图(views)和对其他包的依赖关系等概念。

准备好开始了吗?我们开始吧!

Step 1: 安装 Laravel 5.6

安装最新的Laravel版本或指定版本。为此,请转到项目目录并运行以下命令:

1
composer create-project --prefer-dist laravel/laravel .

详细的Laravel文档还介绍了其他选项。

Step 2: 创建文件夹结构

接下来,我们继续在项目目录中创建一个packages文件夹。命名包的约定如下[创建者或供应商]/[包名]

例如,“laravel/framework”包的供应商是“laravel”,包名是“framework”。
另一个流行的包是“laravelcollective/html”包,这里的供应商是“laravelcollective”,包名是“html”。

类似地,让我们将包命名为“wisdmlabs/todolist”。在“packages”文件夹中创建如下文件夹:

  • packages
    • wisdmlabs
      • todolist

我们需要在package文件夹下创建一个“src”文件夹。

  • packages
    • wisdmlabs
      • todolist
        • src

Step 3: 创建 Composer 文件

每个包都应该有一个“composer.json”文件,它将包含所有包及其依赖项。在“todolist”文件夹中运行以下命令

1
composer init

系统将提示您了解有关该包的详细信息。您可以通过按enter键跳过,它将接受默认值。您可以在稍后在“composer.json”文件中更改此信息。

1
2
3
4
5
6
7
8
9
10
11
{
"name": "wisdmlabs/todolist",
"description": "You can create the to-do-list of your task.",
"authors": [
{
"name": "John Doe",
"email": "john.doe@wisdmlabs.com"
}
],
"minimum-stability": "dev"
}

Step 4: 从主要 Composer.JSON 文件加载这个包

现在,这个“composer.json”文件用于当前根目录每个Laravel应用。我们需求我们的包对应用程序可见。

在autoload > psr-4”添加我们的包的命名空间(namespace)

1
2
3
4
5
6
7
8
9
"autoload": {
"classmap": [
...
],
"psr-4": {
"App\\": "app/",
"Wisdmlabs\\Todolist\\": "packages/wisdmlabs/todolist/src/"
}
},
这里要注意一下,”Wisdmlabs\Todolist\“中的大小写一定要跟后面使用的保持一致,否则会出现错误!!!

Step 5: 为包创建服务提供者

服务提供者是我们的包的访问点。该类维护与包相关的所有信息,如视图(views)、迁移(migration)和路由(routes)加载的位置。您可以在官方的Laravel文档中了解更多关于服务提供商的信息。

让我们使用artisan命令创建一个服务提供者。运行以下命令:

1
php artisan make:provider TodolistServiceProvider

它将生成一个文件“TodolistServiceProvider.php”。可以在“app/Providers”目录下找到。现在把文件移到我们的包中,即在packages/wisdmlabs/todolist/scr文件夹中。不要忘记将文件的名称空间更改为“wisdmlabs\todolist”。

  • packages
    • wisdmlabs
      • todolist
        • src
          • TodolistServiceProvider.php

在该文件中,您将注意到两个函数boot()和register()。boot()函数用于初始化某些路由或添加事件侦听器。register()函数用于将我们的包绑定到app容器内的类。

但是在引导或注册包之前,我们需要在文件“config/app.php”中向服务提供者提供服务。

1
2
3
4
5
6
7
8
'providers' => [
/*
* Application Service Providers...
*/
...
App\Providers\RouteServiceProvider::class,
Wisdmlabs\Todolist\TodolistServiceProvider::class,
],

Step 6: 创建迁移(Migration)

接下来,我们首先需要使用以下artisan命令创建迁移(migration):

1
php artisan make:migration create_task_table --create=tasks

是不是提示了 Class 'Wisdmlabs\Todolist\TodolistServiceProvider' not found 这个错误?哈哈,要先执行性如下代码:

1
composer dump-autoload

在执行创建迁移命令,是不是成功了。

迁移被创建在这个位置database/migrations/*_create_task_table.php。我们将把这个迁移文件移到我们的包中packages/wisdmlabs/todolist/src/migrations/*_create_task_table.php

现在,我们可以修改这个迁移文件,为我们的表添加列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTaskTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tasks');
}
}

Step 7: 为表(Table)创建模型(Model)

完成上述操作后,我们将为表创建一个 eloquent 模型,以便使用 eloquent 的方法轻松地创建(create)、更新(update)和删除(delete)表中的数据。

运行以下artisan命令:

1
php artisan make:model Task

现在,移动“Task.php”文件从 app/Task.php 到我们的包文件夹 packages/wisdmlabs/todolist/src/Task.php。同样,不要忘记将文件的名称空间更改为“wisdmlabs\todolist”。

现在将必要的信息添加到模型(Task.php)中,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace wisdmlabs\todolist;

use Illuminate\Database\Eloquent\Model;

/**
* Model of the table tasks.
*/
class Task extends Model
{
protected $table = 'tasks';

protected $fillable = [
'name',
];
}

Step 8: 创建一个控制器(Controller)

让我们通过运行artisan命令来创建控制器:

1
php artisan make:controller TaskController

接下来,将控制器(TaskController)从 app/Http/Controllers/TaskController.php 移动到 packages/wisdmlabs/todolist/TaskController.php,并将名称空间更改为“wisdmlabs\todolist”。

我们的控制器将为我们的to-do-list包提供必要的方法。这是主文件,将包含所有逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php

namespace wisdmlabs\todolist;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Wisdmlabs\Todolist\Task;

class TaskController extends Controller
{
public function index()
{
return redirect()->route('task.create');
}

public function create()
{
$tasks = Task::all();
$submit = 'Add';
return view('wisdmlabs.todolist.list', compact('tasks', 'submit'));
}

public function store()
{
$input = Request::all();
Task::create($input);
return redirect()->route('task.create');
}

public function edit($id)
{
$tasks = Task::all();
$task = $tasks->find($id);
$submit = 'Update';
return view('wisdmlabs.todolist.list', compact('tasks', 'task', 'submit'));
}

public function update($id)
{
$input = Request::all();
$task = Task::findOrFail($id);
$task->update($input);
return redirect()->route('task.create');
}

public function destroy($id)
{
$task = Task::findOrFail($id);
$task->delete();
return redirect()->route('task.create');
}
}

Step 9: 创建路由文件(Routes)

在 “wisdmlabs/todolist/src” 文件夹中创建一个新文件,并命名为 “routes.php”。定义我们将在包中使用的路由。

1
2
<?php
Route::resource('/task', 'Wisdmlabs\Todolist\TaskController');

Step 10: 创建视图(Views)

要创建视图,我们必须在 “wisdmlabs/todolist/src/” 下创建一个 “views” 文件夹。现在,为该文件夹下的每个必需视图创建一个文件。

我们将创建两个视图: 1)app.blade——用于每个待办事项 和 2)列表。刀片-用于待办事项列表。

在app.blade.php下添加的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<title>TO DO List</title>
<link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

</head>
<body>

<div class="container">
@yield('content')
</div>

<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

</body>
</html>

在list.blade.php下添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@extends('wisdmlabs.todolist.app')
@section('content')
@if(isset($task))
<h3>Edit : </h3>
{!! Form::model($task, ['route' => ['task.update', $task->id], 'method' => 'patch']) !!}
@else
<h3>Add New Task : </h3>
{!! Form::open(['route' => 'task.store']) !!}
@endif
<div class="form-inline">
<div class="form-group">
{!! Form::text('name',null,['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::submit($submit, ['class' => 'btn btn-primary form-control']) !!}
</div>
</div>
{!! Form::close() !!}
<hr>
<h4>Tasks To Do : </h4>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach($tasks as $task)
<tr>
<td>{{ $task->name }}</td>
<td>
{!! Form::open(['route' => ['task.destroy', $task->id], 'method' => 'delete']) !!}
<div class='btn-group'>
<a href="{!! route('task.edit', [$task->id]) !!}" class='btn btn-default btn-xs'><i class="glyphicon glyphicon-edit"></i></a>
{!! Form::button('<i class="glyphicon glyphicon-trash"></i>', ['type' => 'submit', 'class' => 'btn btn-danger btn-xs', 'onclick' => "return confirm('Are you sure?')"]) !!}
</div>
{!! Form::close() !!}
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection

Step 11:更新服务提供者以加载包

我们已经到了倒数第二步——加载路由、迁移、视图等等。如果希望包的用户能够编辑视图,那么可以在服务提供者中发布视图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

namespace wisdmlabs\todolist;

use Illuminate\Support\ServiceProvider;

class TodolistServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/routes.php');
$this->loadMigrationsFrom(__DIR__.'/migrations');
$this->loadViewsFrom(__DIR__.'/views', 'todolist');
$this->publishes([
__DIR__.'/views' => base_path('resources/views/wisdmlabs/todolist'),
]);
}

/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->make('Wisdmlabs\Todolist\TaskController');
}
}

现在您可以通过artisan命令发布视图:

1
php artisan vendor:publish

会出现如下选项:

1
2
3
4
5
6
7
8
9
10
11
Which provider or tag's files would you like to publish?:
[0] Publish files from all providers and tags listed below
[1] Provider: Fideloper\Proxy\TrustedProxyServiceProvider
[2] Provider: Illuminate\Mail\MailServiceProvider
[3] Provider: Illuminate\Notifications\NotificationServiceProvider
[4] Provider: Illuminate\Pagination\PaginationServiceProvider
[5] Provider: Laravel\Tinker\TinkerServiceProvider
[6] Provider: wisdmlabs\todolist\TodolistServiceProvider
[7] Tag: laravel-mail
[8] Tag: laravel-notifications
[9] Tag: laravel-pagination

我们输入 6 回车,提示:

1
2
Copied Directory [\packages\wisdmlabs\todolist\src\views] To [\resources\views\wisdmlabs\todolist]
Publishing complete.

上面的命令将在views文件夹 “/resources/views/wissdmlabs/todolist/” 下创建包的文件夹。现在,用户可以更改屏幕的视图。

  • views
    • wisdmlabs
      • todolist
        • app.blade.php
        • list.blade.php

Step 12:更新编写器文件

在最后一步中,我们在包中包含了 “laravelcollective/html package”。为此,我们必须在我们的包 “composition .json” 中添加包的依赖项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"name": "wisdmlabs/todolist",
"description": "You can create the to-do-list of your task.",
"authors": [
{
"name": "John Doe",
"email": "john.doe@wisdmlabs.com"
}
],
"minimum-stability": "dev",
"require": {
"laravelcollective/html": "^5.5"
},
"extra": {
"laravel": {
"providers": [
"wisdmlabs\\todolist\\TodolistServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Wisdmlabs\\Todolist\\": "src/"
}
}
}

我们可以添加 extra 对象在 “composer.json”,它会加载我们的包,这样用户就不用添加我们的 package 在 “config/app” provider 数组中。包将自动加载。

转载 https://wisdmlabs.com/blog/create-package-laravel/

坚持原创技术分享,您的支持将鼓励我继续创作!