轻轻玩转 Laravel Helpers 函数

在使用 Laravel 函数时,我们都避免不了使用其提供的各种各样的全局函数,也称为辅助函数。

主要集中为处理数组、文件路径、路由和字符串等。

今天主要说说我喜欢的几个常用 Helper 函数,以及 Helpers 实现原理,最后依葫芦画瓢,自定义我们自己的全局函数。

4 个好玩的 Helpers 函数

data_get()

The data_get function retrieves a value from a nested array or object using “dot” notation: The data_get function also accepts a default value, which will be returned if the specified key is not found data_get() 函数利用“.”符号,从嵌套数组或者对象中检索数值,其中第三个参数是设置默认值,当检索健不存在时。

$array = ['albums' => ['rock' => ['count' => 75]]];
$count = data_get($array, 'albums.rock.count'); 
// 75

$avgCost = data_get($array, 'albums.rock.avg_cost', 0); 
// 0

$object->albums->rock->count = 75;
$count = data_get($object, 'albums.rock.count'); 
// 75

$avgCost = data_get($object, 'albums.rock.avg_cost', 0); 
// 0

在多级嵌套中,并不是每级 key 值都一致,对于同级不同 key 值,可以使用通配符 (*) 代替,如:

$array = ['albums' => ['rock' => ['count' => 75], 
            'punk' => ['count' => 12]]];
$counts = data_get($array, 'albums.*.count');
// [75, 12]

$array = ['albums' => ['rock', 'punk' => ['count' => 12]]];
$counts = data_get($array, 'albums.*.count');
// [NULL, 12]

str_plural()

对于我这英语不好的人来说,如何将单数形式写成复数形式,有时候就会闹出笑话了,但使用 str_plural() 方法,那就便捷多了,其中第二个参数是数值,如果大于 1 时,则转为复数形式,否则还是单数形式。

str_plural('dog'); 
// dogs

str_plural('cat'); 
// cats

str_plural('dog', 2); 
// dogs

str_plural('cat', 1); 
// cat

str_plural('child'); 
// children

str_plural('person'); 
// people

str_plural('fish'); 
// fish

str_plural('deer', 2); 
// deer

str_singular('children') 
// child

同时也有复数转单数函数:str_singular()

value() and with()

value() 函数根据传入的值,返回数据,如果,传入的是闭包函数,则会直接运行闭包函数,返回结果:

$result = value(5);
// 5

$result = value(function () {    
    return false;
});
// false

value() 个人觉得,更多用在于高阶函数中,闭包函数作为高阶函数的传值传入;

和 value() 相比,可以利用 with() 函数传入参数值:

$callback = function ($value) {    
    return (is_numeric($value)) ? $value * 2 : 0;
};
    
$result = with(5, $callback);
// 10

$result = with(null, $callback);
// 0

$result = with(5, null);
// 5

tap()

<?php

function tap($value, $callback){    
    $callback($value);    
    return $value;
}

传入 value 值,并对 value 值进行操作,最后再返回 value。tap 函数就好将 value 值进行镀金,修改 value 对象的状态和属性,最后返回结果可以进行后续操作。如:

<?php

return tap($user)->update([    
    'name' => $name,    
    'age' => $age,
]);

当我们传入一个 $user model 到 tap 方法后,我们就可以链式各种 Model 函数,正常情况下,update 方法返回的是 boolean 类型,正因为我们用了 tap 函数,update 方法返回的是 user model 对象,可以继续链式 Model 方法,操作 user 模型对象。

其它

更多全局 Helpers 函数,参见: https://laravel.com/docs/5.6/helpers

Helpers 函数实现原理

当我们在使用这些函数时,印入脑子里的第一个问题就是:Laravel 是怎么实现的?

所以我们需要从 Laravel 框架源代码入手。

在 PhpStorm IDE 转到这些全局函数定义时,发现主要集中在这两个文件中:

"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"

因为这些函数并不是定义在对象中,而要达到全局加载的目标,Laravel 通过 Composer autoload 加载的方式载入:

引自:https://docs.phpcomposer.com/04-schema.html Files 如果你想要明确的指定,在每次请求时都要载入某些文件,那么你可以使用 ‘files’ autoloading。通常作为函数库的载入方式(而非类库)。 实例

{    
    "autoload": {        
        "files": ["src/MyLibrary/functions.php"]
    }
}

接下来我们看看其中一个函数是怎么写的:

if (! function_exists('tap')) {    
    /**
     * Call the given Closure with the given value then return the value.
     *
     * @param  mixed  $value
     * @param  callable|null  $callback
     * @return mixed
     */
    function tap($value, $callback = null) {        
        if (is_null($callback)) {            
            return new HigherOrderTapProxy($value);
        }        
        $callback($value);        
        return $value;
    }
}

可以看出,每个函数都是以这种格式的:

if (! function_exists('xxx')) {    
    function xxx() {        
        // ...
    }
}

注:从 tap 函数源代码可以看出,无论传入的 $callback 闭包函数有没有返回值,函数返回的值,都是 $value,和传入的值一样,这样也就达到「链式编程」的目标。

自定义 Helpers 函数

如果以上 Helpers 函数还满足不了你的话,我们就可以通过上文的方式来自定义 Helpers 函数,来满足我们自己的开发需求。

主要有以下几步:

  1. 在项目中创建 helper.php 文件
  2. 在 composer.json 中将 helper 文件 autoload 载入
  3. composer dump-autoload
  4. 在 helper.php 文件写入我们的全局函数
  5. test

举个栗子 ?

总结

学习 Laravel Helpers 实现原理,不仅有助于我们理解和使用这些 Helpers 方法,并且,通过研究每一个 Helper 函数是怎么写的,也有助于规范我们代码逻辑和思维。学其之所长。

参考:

  1. https://laravel.com/docs/5.6/helpers
  2. https://laravel-news.com/creating-helpers
  3. 链式编程

原文发布于微信公众号 - coding01(coding01)

原文发表时间:2018-03-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

JVM内幕:Java虚拟机详解

这篇文章解释了Java 虚拟机(JVM)的内部架构。下图显示了遵守 Java SE 7 规范的典型的 JVM 核心内部组件。

1072
来自专栏java思维导图

HashMap为什么是线程不安全的?

一直以来只是知道HashMap是线程不安全的,但是到底HashMap为什么线程不安全,多线程并发的时候在什么情况下可能出现问题?

1242
来自专栏流柯技术学院

TestNG 三 测试方法

测试方法是可以带有参数的。每个测试方法都可以带有任意数量的参数,并且可以通过使用TestNG的@Parameters向方法传递正确的参数。

1013
来自专栏闪电gogogo的专栏

【数据结构(C语言版)系列三】 队列

队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素。这和我们日常生活中的排队是一致的,最早进入队列的元素最早离开。在队列中,允许插入的一...

2892
来自专栏Brian

Python进阶教程(二)

概述 在上一篇博客中,我们介绍了Python进阶教程(一),还有一些新的技巧没有翻译完,我们下面来继续我们的翻译。 Intermediate Python 中译...

4478
来自专栏大内老A

Dora.Interception, 为.NET Core度身打造的AOP框架:不一样的Interceptor定义方式

相较于社区其他主流的AOP框架,Dora.Interception在Interceptor提供了完全不同的编程方式。我们并没有为Interceptor定义一个接...

3535
来自专栏我是业余自学C/C++的

redis_3.0.7_sds.c_sdsempty_so_on

1033
来自专栏JavaEdge

Java异常之IllegalMonitorStateExceptionJavaDoc解决方法:总结

Thrown to indicate that a thread has attempted to wait on an object's monitor or...

563
来自专栏自学笔记

python基本常识

tuple,str都可以看做是一种list,都可以进行切片操作。 利用切片操作,去掉一个字符串的前后空格。要注意是是前后空格是不止一个的,可能有很多个。

2835
来自专栏用户2442861的专栏

Python基础学习笔记之(二)(华工大神)

         Python中每一个.py脚本定义一个模块,所以我们可以在一个.py脚本中定义一个实现某个功能的函数或者脚本,这样其他的.py脚本就可以调用...

1194

扫码关注云+社区

领取腾讯云代金券