Laravel 创建自己的扩展包 package
Laravel 如何创建自己的扩展包 package
通过使用composer来完成对软件包的安装
第3步 设置动态加载composer库的依赖项
第3步 设置动态加载composer库的依赖项
在安装完laravel后, 根据个人需求来构建第三方扩展包, 通过本文内容, 我们将学会如何独立地构建一个专属于个人的laravel扩展包。
1. 创建我们自己的文件包目录
在项目的更目录中创建的 packages 文件夹,与 app 目录同级。
|-app
|-packages
|--- liuning
|----- my-first-laravel-package
|------- src
...
代码解读
如图:

创建目录很简单,接下来我们初始化 package 包。
2. composer 初始化 package 包
composer init
代码解读
composer.json 文件创建如下:
# packages/liuning/my-first-laravel-package/composer.json
{
"name": "liuning/my-first-laravel-package",
"description": "liuning's first laravel package",
"authors": [
{
"name": "liuning",
"email": "441380237@qq.com"
}
],
"require": {}
}
代码解读
请记住,在处理或配置项目时,请确保将 composer.json 文件中的 name 和 authors 等相关信息准确无误地填写
如果不选择使用 compose init 也可以直接部署至 packages/liuning/my-first-laravel-package 目录下。
至此已完成 package 包的初始化过程。
下一步的目标是使 Laravel 根目录中的 composer.json 自动生成并加载 liuning/my-first-laravel-package 包
3. 配置composer dump-autoload
位于Laravel项目根目录的composer.json文件上已配置为遵循PSR-4标准。
# / 项目跟目录
"autoload": {
"psr-4": {
"App\ ": "app/",
"LiuNing\ FirstLaravelPackage\ ": "packages/liuning/my-first-laravel-package/src"
}
},
代码解读
配置完成后,在 Laravel 根目录下的 compose.json 同一目录运行 composer dump-autoload
4. 添加服务容器
服务容器是主要的入口,我们用 artisan 创建一个服务容器。
php artisan make:provider LiuNingLaravelPackageServiceProvider
代码解读
在执行命令之后,在 app/Providers 目录下会创建一个文件。接着会将这个容器文件移动至 packages/liuning/my-first-laravel-package/src 目录。
此时的应用容器仍然使用 namespace App\Providers; 将其更改为 namespace LiuNing\FirstLaravelPackage; ,该命名空间采用 vendor/package_name 的结构即为 composer 系统自动配置的命名空间。无需对其他部分进行修改。

在为服务容器创建配置时,在 config/app.php 中的 providers 数组部分需要进行注册设置。
# app/config/app.php
'providers' => [
App\Providers\RouteServiceProvider::class,
// LiuNing Laravel Package Service Provider
LiuNing\FirstLaravelPackage\LiuNingLaravelPackageServiceProvider::class
],
代码解读
至此为止, 我们已成功创建并完成服务在应用中的注册. 下一步将是编写一些基础的路由规则以便以访问以下容器的内容.
5. 创建路由文件
在 packages/liuning/my-first-laravel-package/src 目录下创建 routes.php
# packages/liuning/my-first-laravel-package/src/routes.php
Route::get('hello', function(){
echo 'Hello from liuning the my-first-laravel-package package!';
});
代码解读
创建完路由后,需要在服务的 boot() 方法中包含进去。
# packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
public function boot()
{
$this->loadRoutesFrom(__DIR__ . '/routes.php');
}
代码解读
让后我们在浏览器中访问以下:

浏览器访问成功了!!!
小开心一下,接下来我们创建控制器。
6. 创建控制器
还是用 artisan 命令创建控制器:
php artisan make:controller HelloWorldController
代码解读
与创建服务文件的方式相同,在我的项目中也实现了将HelloWorldController迁移至packages/liuning/my-first-laravel-package/src/controllers路径的操作。为了便于所有控制器都能集中存放以便后续管理维护, 我新建了一个Controllers目录, 并对其中的控制器进行了重新命名, 同时增加了两个新的功能模块以满足开发需求. 在操作过程中, 特别需要注意以下几点: 首先, 必须确保Controller类在使用时再次引用use App\Http\Controllers\Controller; 同时, 这些Controller类还需要继承自App项目的父级控制器以保证功能的一致性.
# packages/Liuning/my-first-laravel-package/src/controllers/HelloWorldController.php
<?php
// namespace App\Http\Controllers;
namespace LiuNing\FirstLaravelPackage\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class HelloWorldController extends Controller
{
public function hello($name)
{
echo 'HelloWorldController hello ' . $name;
}
public function world($name)
{
echo 'HelloWorldController world ' . $name;
}
}
代码解读
控制器创建好之后,我们需要注册到服务器中:
# packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
public function register()
{
// register our controller
$this->app->make('LiuNing\FirstLaravelPackage\Controllers\HelloWorldController');
}
代码解读
最后呢我们在路由文件中添加两个路由:
# packages/liuning/my-first-laravel-package/src/routes.php
Route::get('hello-world/hello/{name}', 'LiuNing\FirstLaravelPackage\Controllers\HelloWorldController@hello');
Route::get('hello-world/world/{name}', 'LiuNing\FirstLaravelPackage\Controllers\HelloWorldController@world');
代码解读
分别访问一下:


然后我们想加载模板文件怎么操作呢,我们一起操作一下。
7. 添加模板
我们创建模板文件:

# packages/liuning/my-first-laravel-package/src/view/hello.blade.php
<!DOCTYPE html>
<html>
<head>
<title>HelloController hello.blade.php</title>
</head>
<body>
<h1>
Your Input : {{ $name }}
</h1>
</body>
</html>
代码解读
注册模板:
# packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
public function register()
{
//
// register our controller
$this->app->make('LiuNing\FirstLaravelPackage\Controllers\HelloWorldController');
$this->loadViewsFrom(__DIR__.'/views', 'liuning');
}
代码解读
在控制器中调用模板:
# packages/liuning/my-first-laravel-package/src/controllers/HelloWorldController.php
public function hello($name)
{
//echo 'HelloWorldController hello ' . $name;
return view('liuning::hello', compact('name'));
}
public function world($name)
{
// echo 'HelloWorldController world ' . $name;
return view('liuning::hello', compact('name'));
}
代码解读
再次访问如下:


至此,我们已经弄好自己的 laravel package 了。
恭喜你掌握了。
8. 发布静态文件
在第七步中,我们如何处理页面渲染?需要使用外部CSS文件
/* packages/liuning/my-first-laravel-package/src/public/css/style.css */
h1 {
color: #FF0000;
}
代码解读
模板中进行应用
如何使 style.css 文件得以实现?
只需将 style.css 文件放置于更目录下的 public 目录中即可。
具体来说,
liuning 服务配置如下:
#packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
public function boot()
{
// ...
// 把静态资源发布到laravel public/liuning目录下
$this->publishes([
__DIR__ . DIRECTORY_SEPARATOR . 'public' => public_path('liuning'),
], 'public');
// ...
}
代码解读
在 laravel 根目录下执行:
// --force 覆盖发布文件
php artisan vendor:publish --force
代码解读

找到对应的服务编号输入回车。

将文件发布到指定的目录了。此时看 public 目录下已生成响应的文件。

静态文件发布后记得在模板文件中引用静态资源
<!DOCTYPE html>
<html>
<head>
<title>HelloController hello.blade.php</title>
<!-- 引用静态资源 -->
<link rel="stylesheet" href="/liuning/css/style.css">
</head>
<body>
<h1>
Your Input : {{ $name }}
</h1>
<h2>
Config : {{ $package_name }}
</h2>
</body>
</html>
代码解读
我们在看一下页面:已经生效为红色字体。

(由于博文更新时间较长,域名有所改动忽略域名即可)
9. 发布配置文件
与发布静态文件一样
创建 config/liuning.php 文件,配置选项为包名称。
# packages/liuning/my-first-laravel-package/src/config/xingfupeng.php
return [
'package_name' => 'liuning_my_first_laravel_package'
];
代码解读
配置服务文件
#packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
public function boot()
{
// ...
// 发布配置文件到 laravel config/liuning.php
$this->publishes([
__DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'liuning.php' => config_path('liuning.php'),
], 'config');
// ...
}
代码解读
在 laravel 根目录下执行发布:
// --force 覆盖发布文件
php artisan vendor:publish --force
代码解读

已覆盖之前的发布文件
我们怎么调取呢?
我们在控制器调用配置文件,在模板中输出吧。
# packages/liuning/my-first-laravel-package/src/controllers/HelloWorldController.php
public function hello($name)
{
//echo 'HelloWorldController hello ' . $name;
$package_name = config('liuning.package_name','null');
return view('liuning::hello', compact('name','package_name'));
}
代码解读
# packages/liuning/my-first-laravel-package/src/view/hello.blade.php
<!DOCTYPE html>
<html>
<head>
<title>HelloController hello.blade.php</title>
</head>
<body>
<h1>
Your Input : {{ $name }}
</h1>
<h2>
Config : {{ $package_name }}
</h2>
</body>
</html>
代码解读
我们运行一下模板查看一下:我们配置的包名称已被正确读取。

10. 中间件
搭建中间件时,请借鉴现有的Laravel中间件,并对命名空间结构和类名布局进行优化调整即可实现目标。
# packages/liuning/my-first-laravel-package/src/Middleware/ApiAuthMiddleware.php
<?php
namespace LiuNing\FirstLaravelPackage\Middleware;
use Closure;
class ApiAuthMiddleware
{
/** * Handle an incoming request.
* * @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// $status true/false 当满足条件时会进入 if 操作,否则按照 laravel 预定的执行。
$status = true;
if ($status) {
return 'api中间件验证不通过';
}
return $next($request);
}
}
代码解读
中间件创建完了我们想要的结果就是在路由中直接使用。
# packages/liuning/my-first-laravel-package/src/routes.php
Route::middleware(['liuning.api'])->group(function ($router) {
$router->get('liuning/api', function () {
return 'api success';
});
});
代码解读
我们访问一下:

在当前状态下, 该中间件无法被识别. 我们如何将上述中间件成功地注册到Laravel应用程序中?
配置服务文件:
1、添加中间件的重命名方法
2、boot 方法中调用添加中间件
#packages/liuning/my-first-laravel-package/src/LiuNingLaravelPackageServiceProvider.php
// boot 方法中添加如下代码
public function boot()
{
// ...
$this->addMiddlewareAlias('liuning.api', ApiAuthMiddleware::class);
// ...
}
# 添加中间件的别名方法
protected function addMiddlewareAlias($name, $class)
{
$router = $this->app['router'];
if (method_exists($router, 'aliasMiddleware')) {
return $router->aliasMiddleware($name, $class);
}
return $router->middleware($name, $class);
}
代码解读
我们在访问一下:

把中间件中的 $status = true 改为 false 再访问:

目前我们已经熟悉了创建 Laravel 包的核心内容。程序目录结构应基于理解和个性化的设置规划一个更合理的包目录结构。如有进一步的需求或建议,请留言交流。
目前我们已经熟悉了创建 Laravel 包的核心内容。程序目录结构应基于理解和个性化的设置规划一个更合理的包目录结构。如有进一步的需求或建议,请留言交流。
