「12步」制做 Laravel 插件 (一)

在Laravel 开发过程当中,用了不少诸如:laravel-admin,Guzzle,Intervention Image 等优秀的插件,看他们的 star 不少,获得不少人的关注,就想着本身能不能写个有价值的插件,共享给你们使用。php

今天就让咱们来讲说如何建立一个简单的插件:「数字转中文大写金额」css

具体只须要如下「12」个步骤:html

1. 建立 Laravel 5.5 项目

// 下载最新 Laravel

composer global require "laravel/installer"

// 建立项目
Laravel new packagelearning
复制代码

2. 建立插件文件夹

在 Laravel 项目 vendor 文件夹放的是各类第三方插件,咱们随便看看,能够发现这些插件基本遵循下面的文件目录格式:laravel

如,monolog 插件,目录结构为 [VENDOR or CREATOR] / [PACKAGE NAME],并且 src 文件夹基本用于保存插件源代码,还有一个 composer.json 用于配置插件基本信息和引入其它第三方插件等信息。json

咱们在 packagelearning 项目建立 packages 文件夹:api

3. 建立 composer.json

咱们能够利用「composer」命令来初始化 composer.json 文件:bash

输入插件的基本信息后:服务器

4. PSR-4 autoload namespace mapping

在 composer.json 加入 autoload 配置:app

5. 建立 Service Providers

正如 Laravel 官网所说:composer

Service providers are the connection points between your package and Laravel. A service provider is responsible for binding things into Laravel's service container and informing Laravel where to load package resources such as views, configuration, and localization files.

因此咱们须要建立一个 Service Provider 来告诉 Laravel 使用该插件是,什么 Controller 被执行了,Routes 和 Views 在哪加载等等。

// 在 Laravel项目根目录执行命令

php artisan make:provider Num2nmbServiceProvider
复制代码

再将 Num2nmbServiceProvider.php 文件移动到插件 src 文件夹下,并修改namespace 名为:Fanly\Num2nmb

这也正如官网的说明同样,service provider 主要包括两个方法:register 和 boot方法。

A service provider extends the Illuminate\Support\ServiceProvider class and contains two methods: register and boot. The base ServiceProvider class is located in the illuminate/support Composer package, which you should add to your own package's dependencies. To learn more about the structure and purpose of service providers, check out their documentation.

有了 Service Provider,咱们能够先加入到 config/app.php 中。

接下来让咱们跟常规开发同样,建立功能的 Controller,Route 和 View。

6. 建立 Controller

从网上 copy 了一段「数字金额转中文大写金额」功能,直接上代码:

<?php
/**
 * Created by PhpStorm.
 * User: ye
 * Date: 2018/1/10
 * Time: 下午9:49
 */

namespace Fanly\Num2nmb;


use App\Http\Controllers\Controller;

class Num2nmbController extends Controller {

    public function index($num) {
        $nmb = $this->num2nmb($num);
        return view('num2nmb::nmb', compact('nmb'));
    }

    private function num2nmb($num) {
        $c1 = "零壹贰叁肆伍陆柒捌玖";
        $c2 = "分角元拾佰仟万拾佰仟亿";

        //精确到分后面就不要了,因此只留两个小数位
        $num = round($num, 2);
        //将数字转化为整数
        $num = $num * 100;

        if (strlen($num) > 10) {
            return "金额太大,请检查";
        }
        $i = 0;
        $c = "";
        while(1) {
            if ($i == 0) {
                //获取最后一位数字
                $n = substr($num, strlen($num) - 1, 1);
            } else {
                $n = $num % 10;
            }    //每次将最后一位数字转化为中文
            $p1 = substr($c1, 3 * $n, 3);
            $p2 = substr($c2, 3 * $i, 3);
            if ($n != '0' || ($n == '0' && ($p2 == '亿' || $p2 == '万' || $p2 == '元'))) {
                $c = $p1 . $p2 . $c;
            } else {
                $c = $p1 . $c;
            }
            $i = $i + 1;
            //去掉数字最后一位了
            $num = $num / 10;
            $num = (int) $num;
            //结束循环
            if ($num == 0) {
                break;
            }
        }
        $j = 0;
        $slen = strlen($c);
        while ($j < $slen) {
            //utf8一个汉字至关3个字符
            $m = substr($c, $j, 6);
            //处理数字中不少0的状况,每次循环去掉一个汉字“零”
            if ($m == '零元' || $m == '零万' || $m == '零亿' || $m == '零零') {
                $left = substr($c, 0, $j);
                $right = substr($c, $j + 3);
                $c = $left . $right;
                $j = $j - 3;
                $slen = $slen - 3;
            }
            $j = $j + 3;
        }

        //这个是为了去掉相似23.0中最后一个“零”字
        if (substr($c, strlen($c) - 3, 3) == '零') {
            $c = substr($c, 0, strlen($c) - 3);
        }

        //将处理的汉字加上“整”
        if (empty($c)) {
            return "零元整";
        } else {
            return $c . "整";
        }
    }
}
复制代码

7. 建立 View

这个很简单了,从 welcome.blade.php 直接 copy 过来,放在 src/views/nmb.blade.php:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel</title>

    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <style>
        html, body {
            background-color: #fff;
            color: #636b6f;
            font-family: 'Raleway', sans-serif;
            font-weight: 100;
            height: 100vh;
            margin: 0;
        }

        .full-height {
            height: 100vh;
        }

        .flex-center {
            align-items: center;
            display: flex;
            justify-content: center;
        }

        .position-ref {
            position: relative;
        }

        .top-right {
            position: absolute;
            right: 10px;
            top: 18px;
        }

        .content {
            text-align: center;
        }

        .title {
            font-size: 84px;
        }

        .links > a {
            color: #636b6f;
            padding: 0 25px;
            font-size: 12px;
            font-weight: 600;
            letter-spacing: .1rem;
            text-decoration: none;
            text-transform: uppercase;
        }

        .m-b-md {
            margin-bottom: 30px;
        }
    </style>
</head>
<body>
<div class="flex-center position-ref full-height">
    <div class="content">
        <div class="title m-b-md">
            {{ $nmb }}
        </div>
        <div class="links">
            <a href="https://laravel.com/docs">fanly</a>
        </div>
    </div>
</div>
</body>
</html>
复制代码

8. 添加 Route

在 src目录下,建立 routes.php 文件

Route::get('num2nmb/{num}', 'Fanly\Num2nmb\Num2nmbController@index');
复制代码

9. 配置 Service Provider

有了 controller、view 和路由,直接在 Num2nmbServiceProvider 配置相关信息便可:

在 boot 函数中,加入代码:

$this->loadViewsFrom(__DIR__.'/views', 'num2nmb');
复制代码

在 register 函数加入代码:

10. 测试

如图:

11. Publishing the Views

最后,view 层是高度自定义层,因此有必要将 views 试图 publish 到项目中,咱们就能够改动显示效果,而不至于去变化插件中 views 的代码了,并且这自己也是不容许的。

能够在 boot 函数中加入代码:

$this->publishes([
            __DIR__.'/views' => base_path('resources/views/num2nmb'),
        ]);
复制代码

最后,执行命令:

12. 使用「包自动发现」

Laravel 5.5 增长了一个新的功能 「Package Auto Discovery」。这个功能使得 Laravel 能更容易地对包进行安装和启用的管理。

包的开发者能够在 composer.json 文件中添加一个新的部分,用来告诉框架应该注册哪些服务提供器或者它们的外观。

咱们能够试试这个功能,在插件的 composer.json 中加入以下代码:

"extra": {
        "laravel": {
            "providers": [
                "Barryvdh\\Debugbar\\ServiceProvider"
            ]
        }
    }
复制代码

注: 有关「Package Auto Discovery」功能的说明和使用,能够参考:

1. 深刻了解 Laravel 5.5 Package Auto Discovery zhuanlan.zhihu.com/p/27518011

2. Laravel 5.5 支持包自动发现(新功能早知道)laravel-china.org/articles/49…

3. Laravel Package Auto-Discovery laravel-news.com/package-aut…

4. Package Auto-Discovery In Laravel 5.5 medium.com/@taylorotwe…

总结

下一步,咱们须要将作好的插件包提交服务器,供其余人使用。

「未完待续」


coding01 期待您继续关注

qrcode
相关文章
相关标签/搜索