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

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

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

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

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

Step 1: 安装 Laravel 5.6

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

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”文件夹中运行以下命令

composer init

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

{
    "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)

"autoload": {
        "classmap": [
    ...
        ],
        "psr-4": {
            "App\\": "app/",
            "Wisdmlabs\\Todolist\\": "packages/wisdmlabs/todolist/src/"
        }
    },

这里要注意一下,”Wisdmlabs\Todolist\”中的大小写一定要跟后面使用的保持一致,否则会出现错误!!!

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

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

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

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”中向服务提供者提供服务。

'providers' => [
        /*
         * Application Service Providers...
         */
         ...
        App\Providers\RouteServiceProvider::class,
        Wisdmlabs\Todolist\TodolistServiceProvider::class,
    ],

Step 6: 创建迁移(Migration)

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

php artisan make:migration create_task_table --create=tasks

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

composer dump-autoload

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

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

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

<?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命令:

php artisan make:model Task 

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

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

<?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命令来创建控制器:

php artisan make:controller TaskController

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

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

<?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”。定义我们将在包中使用的路由。

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

Step 10: 创建视图(Views)

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

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

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

<!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下添加以下内容:

@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:更新服务提供者以加载包

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

<?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命令发布视图:

php artisan vendor:publish

会出现如下选项:

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 回车,提示:

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” 中添加包的依赖项

{
    "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/

如未注明,均为原创,转载请注明来自Peak Xin's Blog

No Comments »