Laravel 创建自己的 Facade

Laravel 创建自己的 Facade 扩展 geoip 根据 IP 获取国家、地域、城市信息 Laravel 创建自己的 Facade 扩展 geoip 根据 IP 获取国家、地域、城市信息... 阅读详情

博客原文:Laravel 创建自己的 Facade

前言

laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该如何写自己的 facade 呢?

Facade 是什么?

首先,facade 并不是 laravel 独有的东西,它就是设计模式中的外观模式(Facade)。
当然,这里就不长篇大论去讨论外观模式的定义了。这篇文章写的很不错 : 设计模式(九)外观模式Facade(结构型)。
那么,laravel 的 facade 做了什么?
同样的, laravel 实现了外观模式的开关功能,并且使用魔术方法 __callstatic 实现了静态方式调用、动态创建对象的功能。参考 (官方文档)

当然你可能觉得这些概念很抽象,都什么玩意。那么其实简单的讲,laravel 的 facade 就是将某些功能封装成工具类,而且能以静态方式调用工具类的方法。

建立自己的 facade

首先、以 laravel 5.1 框架,我之前写过的 Geoip facade 为例,说一下怎么去建立自己的 facade。

下载 geoip 扩展

geoip 是一个可以更具 IP 获取国家、地域、城市信息的 PHP 扩展,基于 maxmind 数据库。 github 在此。

首先,为 laravel 添加 geoip 扩展。
打开 composer.json,添加 “geoip2/geoip2”: “~2.0” 到 require。
项目根目录运行 composer update ( 需要安装 composer )更新一下,geoip 的依赖和软件包就被下载到 vendor 文件夹中了。

然后下载 geoip 依赖的数据库,免费库的地址 : GeoLite2

我下载了 GeoLite2 Country 和 GeoLite2 City 库,放到了 storage/geoipdb 中。

建立 facade

在 app 目录下新建 Facades 文件夹,里面新建 Facades/GeoIP/GeoIP.php 和 Facades/GeoIP/Facade/GeoIP.php (建议每个功能新建一个文件夹区分,比如我这里给 GeoIP 新建一个文件夹,关于GeoIP 的东西全放到这里)
注意,Facades/GeoIP 下的 GeoIP.php 是你要对 geoip 扩展进行封装的类, Facades/GeoIP/Facade 下的 GeoIP.php 是你的 facade,用来给 laravel 解析使用,这两个文件可以不同名。
image.png

Facades/GeoIP/Facade/GeoIP.php 如下

<?php

namespace App\Facades\GeoIP\Facade;

use Illuminate\Support\Facades\Facade;

class GeoIP extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'geoip';
    }
}

注意你的 facade 现在只有一个方法,返回了一个字符串 ‘geoip’ , 这个字符串是一个标号,用来给 laravel 的服务提供者解析使用的。

Facades/GeoIP/GeoIP.php 如下(吐槽:写的有点随意)

<?php

namespace App\Facades\GeoIP;

use GeoIp2\Database\Reader;

class GeoIP
{
    /**
     * GeoIP country db path (base on storage_path).
     *
     * @var GeoIP
     */
    private $_country_db = 'geoipdb/GeoLite2-Country.mmdb';

    /**
     * GeoIP city db path (base on storage_path).
     *
     * @var GeoIP
     */
    private $_city_db = 'geoipdb/GeoLite2-City.mmdb';

    /**
     * Instance for GeoIP .
     *
     * @var GeoIP
     */
    private $_instance;

    /**
     * Init instance.
     *
     */
    public function init($mode)
    {
        switch ($mode) {
          case 'getCountry':
            $path = $this->_country_db;
            break;
          case 'getCity':
            $path = $this->_city_db;
            break;
          default:
            break;
        }

        $this->_instance = new Reader(storage_path($path));
    }

    /**
     * Get Country infomations.
     *
     * @param  String  $ip
     * @return Array
     */
    public function getCountry($ip)
    {
      $this->init(__FUNCTION__);

      $record = $this->_instance->country($ip);

      // 国家信息
      $data['iso_code'] = $record->country->isoCode;
      $data['country_name'] = $record->country->name;
      $data['country_name_zh_cn'] = $record->country->names['zh-CN'];

      return $data;
    }
 
 /**
     * Get City infomations.
     *
     * @param  String  $ip
     * @return Array
     */
    public function getCity($ip)
    {
      $this->init(__FUNCTION__);

      $record = $this->_instance->city($ip);

      $data['iso_code'] = $record->country->isoCode;
      $data['country_name'] = $record->country->name;
      $data['country_name_zh_cn'] = $record->country->names['zh-CN'];

      // 省、州信息
      $data['sub_division_name'] = $record->mostSpecificSubdivision->name;
      $data['sub_division_name_zh_cn'] = $record->mostSpecificSubdivision->names['zh-CN'];
      $data['sub_division_code'] = $record->mostSpecificSubdivision->isoCode;

      // 城市信息
      $data['city_name'] = $record->city->name;
      $data['postal_code'] = $record->postal->code;

      // 经纬度
      $data['latitude'] = $record->location->latitude;
      $data['longitude'] = $record->location->longitude;

      return $data;
    }
}

OK,现在 geoip 的常用功能已经封装到方法中了。

注册服务

完成了 facade 的创建和功能封装,下面就要使用它了。自己创建的 facade 要在 laravel 使用是要进行注册的,以便 laraval 在启动时能自动注入依赖(请看 laravel 的依赖注入简介 : laravel 依赖注入 学院君)

编写服务提供者

在 app/Providers 下新建 FacadesServiceProvider.php
可以手动建,也可以用 artisan 命令来生成,随你喜欢。
app/Providers/FacadesServiceProvider.php 代码如下:

<?php

namespace App\Providers;

use App\Service\ApiService;
use Illuminate\Support\ServiceProvider;

// include the class facade binded
use App\Facades\GeoIP\GeoIP;

class FacadesServiceProvider extends ServiceProvider
{
    /**
     * 在容器中注册绑定。
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('geoip', function ($app) {
            return new GeoIP($app);
        });
    }
}

上面代码可知,服务提供者注册时会注册一个单例,标号为 ‘geoip’,也就是我们自己的 facade 返回的那个,然后回调函数会返回一个对象,也就是我们封装 geoip 功能的那个类的实例,不明白的同学可以看看 laravel 的服务提供者和服务容器相关知识哦。(注意要 use 将 facade 和封装类的命名空间引用一下哦)

注册服务提供者

laravel 5.1 以上版本的话, config/app.php 中找到 providers 和 aliases ,将你的服务提供者和 facade 别名配置一下 :

providers 加入 :

App\Providers\FacadeServiceProvider::class,
aliases 加入(不用每次都写很长的命名空间前缀) :

'GeoIP' => App\Facades\GeoIP\Facade\GeoIP::class,
对于 lumen 5.2 以上,需要在 bootstrap/app.php 中添加
$app->register(App\Providers\FacadesServiceProvider::class);
注:放到AppServiceProvider类的register方法里更合理一些
$this->app->register(App\Providers\FacadesServiceProvider::class);
注册完毕后,每次使用 facade::function 的时候,laravel 会自动解析 facade, 然后创建一个对象给用户使用,,而无需用户自己去 new 一个对象出来。

使用
现在,在任何一个控制器,或者路由的回调函数中,使用

$res = GeoIP::getCountry('75.101.195.215');
var_dump($res);

你会发现,facade 已经可以好好工作了,enjoy!

参考文章

【1】设计模式(九)外观模式Facade(结构型)
【2】Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)
【3】Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例

Laravel开发-laravel-geoip2 Laravel开发-laravel-geoip2 MaxMind geoip2的Laravel包装 立即下载

相关推荐

laravel-geoip:Laravel的GeoIP扩展

laravel-geoip Laravel的IP位置查询模块 平台支持 环境需求 PHP> = 7.2.5 安装 composer require larva/laravel-geoip -vv $ info = \ Larva \ GeoIP \ GeoIP :: get ( '218.1.2.3' ); $ info = \ Larva \ GeoIP \ GeoIP :: getRaw ( '218.1.2.3' ); $ info = \ Larva \ GeoIP \ GeoIP :: with ( 'baidu' )-> get ( '218.1.2.3' ); $ info = \ Larva \ GeoIP \ GeoIP :: with ( 'baidu' )-> getRaw ( '218.1.2.3' );

Laravel根据Ip获取国家,城市信息

https://blog.youkuaiyun.com/zhezhebie/article/details/79097133 1、安装: composer require geoip2/geoip2:~2.0 2、用法: <?php require_once 'vendor/autoload.php'; use GeoIp2\Database\Reader...

lxw1844912514的博客 2100

Laravel开发-geoip Laravel GeoIP 服务集成包

Laravel开发-geoip Laravel GeoIP 服务集成包 通过IP获取对应的地理位置信息(geoip数据库)

laravel自定义facade

在conf\app.conf文件中aliases下加上你自己facade,名字自定义,不要和框架中的facade冲突即可和常规的facade使用方法一样。

weixin_41539438的博客 503

Laravel开发-geoip2country

Laravel开发-geoip2country Laravel套装地理位置2国家

开源TMS系统cortex-tms私有化部署与二次开发实战指南

运输管理系统(TMS)是现代物流数字化的核心组件,它通过将线下零散的物流操作转化为线上标准化、可追溯的数据流,实现订单、调度、跟踪与结算的全流程管理。其技术原理通常基于微服务架构,采用Spring Boot、Vue.js等成熟技术栈构建,确保系统的稳定性和可扩展性。TMS的技术价值在于显著提升物流企业的运营效率、降低成本并增强过程可控性,尤其适用于中小型物流企业实现从手工管理到系统化管理的跨越。在应用场景上,TMS广泛应用于车队管理、订单跟踪和财务结算等环节。本文聚焦于开源TMS项目cortex-tms,深

weixin_42523907的博客 746

在Laravel中创建Service Provider和Facade

环境 Laravel 5.4 前言 下面我们以“音乐播放器”为例子,介绍如何在Laravel中创建一个Service Provider,并且为这个Provider创建一个门面(Facade)。 创建自定义Service Provider 1)既然是音乐播放器,那肯定会有播放功能,因此先定义一个音乐播放器的接口,接口有一个play方法,文件路径app/Helpers/Contracts/MusicPlayerContract.php: namespace App\Helpers\Contracts; int

IT部落格 1119

AWR射频仿真基本操作(一)

这里只讲述一个基本的操作: 软件是AWR 14版本

钢丝 2万+

Laravel 创建自己的 Facade(转载)

Laravel 创建自己的 Facade(转载) 原文:https://segmentfault.com/a/1190000009759459 前言 laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该如何写自己的 facade 呢? Facade 是什么? 首先,facade 并不是 laravel 独有的东西,它就是设计模式中的外观模式(Facade)。 当然,这里就不长篇大论去讨论外观模式的定义了。这篇文章写

zhuimengchizixinwx的博客 452

Gartner DSG数据安全治理 架构及解读

目录背景:架构图: 解释:英文解释:(自上而下)平衡业务与风险、威胁、合规之间的关系(5个维度之间的平衡)优先处理数据集制定安全策略实施安全工具策略配置同步从上到下,从需求调研开始实施数据安全治理。千万不要跨过数据摸底、治理优先级分析、制定治理整体策略,而直接从技术工具开始对数据安全进行治理。 先明确选择需要治理的对象,优先选择重要数据进行数据安全治理工作。可以通过数据梳理、分类分级等手段,完成数据资产盘点和筛选,在纷杂的数据中理清头绪。

锦慈的技术博客 7216

汽车信息安全--SHE中的密钥管理(二)

上一篇我们讲解了HTA基本概念,SHE和EVITA HSM区别以及SHE的架构,接下来我们聊一聊SHE中的密钥管理策略。

认真搞搞汽车MCU 2402

laravel5如何创建service provider和facade

laravel5如何创建service provider和facade 2015-04-17 10:10 by 轩脉刃, ... 阅读, ... 评论, 收藏, 编辑 laravel5如何创建service provider和facade laravel5创建一个facade,可以将某个service注册个门面,这样,使用的时候就不...

轩脉刃的刀光剑影 131

Altium Designer(AD24/25)PCB编辑的几种方法介绍

本文介绍了Altium Designer(AD24/25)软件中PCB编辑的四种操作方法:1)通过菜单栏"Place→Component"激活;2)点击工具栏元器件图标;3)右键快捷菜单选择;4)快捷键P+C组合操作。建议初学者先通过菜单栏和快捷菜单熟悉操作,熟练后转为工具栏和快捷键以提高效率。文章配有操作示意图,帮助用户快速掌握PCB元器件放置技巧。

fydar的博客 943

laravel services.php,laravel5创建service provider和facade的方法详解

本文实例讲述了laravel5创建service provider和facade的方法。分享给大家供大家参考,具体如下:laravel5创建一个facade,可以将某个service注册个门面,这样,使用的时候就不需要麻烦地use 了。文章用一个例子说明怎么创建service provider和 facade。目标我希望我创建一个AjaxResponse的facade,这样能直接在controll...

weixin_30336701的博客 303

SAP FICO 中的 F-02 :概念、使用场景及案例解析

在 SAP FICO (财务会计与管理会计) 模块中,F-02 是一个用于录入总账凭证的事务代码。这个事务代码主要用于手动输入总账凭证,适用于各类财务交易,例如资产购入、费用支付、收入确认等。F-02 的重要性在于,它允许财务人员在 SAP 系统中创建凭证,并确保这些凭证能够正确影响总账账户。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2060

YOLOv13改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣ 已更新种不同的改进方案,专栏内的每篇文章皆,均可顺利运行。2️⃣ 订阅专栏即可进群获取以及从的各种答疑内容。3️⃣ 全新的YOLOv13改进专栏,,只为更好的满足论文发表的要求。专栏内容,专栏实时评分,全网最高,质量保证。🎫。。

Limiiiing的博客 9155

facade php,如何在 Laravel 项目中创建自己的 Facade

通过这篇文章,我们可以学会如何定义自己的facade类,并且在我们的项目中使用它。这里我想创建一个名称为SmartLogger的类,同时尝试使用它,下面让我们开始吧:首先创建一个以SmartLogger命名的目录,并且在目录中创建如下php文件:.├── SmartLoggerFacade.php└── SmartLogger.php0 directories, 2 filesSmartLogge...

weixin_39732249的博客 209

LSTM在交通流量预测中的应用:优化城市交通管理

我们使用的数据集来自某个城市的交通监测系统,包含多个监测点在不同时间段内的交通流量记录。每个监测点的数据包括时间戳、交通流量、天气状况和道路状态等信息。

斌擎科技 1258
上一篇: 热重启golang服务器(graceful restart golang http server)
下一篇: laravel 服务容器bind与上下文绑定的一个应用实例
cqims21
博客等级 码龄18年 4粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值