header-bg.jpg
使用 call_user_func_array 让 PHP 代码变得更加优雅
发表于 2019-07-30 15:26
|
分类于 PHP
|
评论次数 0
|
阅读次数 2026

https://img.lcgod.com/2019/07/30/1564471547.png

自从使用了 Laravel 框架后,我就一直在学习如何使自己的代码变得更优雅,今天阅读框架源码时发现很多地方都使用了 call_user_func_array 这个方法,而且发现这个方法极其好用,下面我讲列举几个经常可以使用到的地方:

Redis 实例静态调用

众所周知,在 PHP 中连接并操作 Redis 是需要经过以下步骤的:

$redis = new Redis();
$status = $rds->connect('127.0.0.1', 6379, 1);
if (!$status) return false;
var_dump($redis->get('key'));

并且必须使用实例 和 -> 来访问方法,并不能使用 Redis::get($key) 这样的静态调用写法,

而且多个控制器都需要连接 Redis,那每次都需要写一遍以上的连接代码,就显得很麻烦,于是 call_user_func_array 配合 __callstatic 就派上用场了:

class RedisHandle
{
    private static $redis;
    private static $status;

    public static function __callStatic($method, $arguments) {
        if (!self::$status) {
            self::$redis = new \Redis();
            self::$status = self::$redis->pconnect('127.0.0.1', 6379, 1);
        }
        return self::$status ? call_user_func_array([self::$redis, $method], $arguments) : false;
    }
}

就这么简单几行代码,就完成了以上需求,后面每次需要操作 Redis 的时候,只需要先 use,然后静态调用即可,例如:

use App\Helpers\RedisHandle as Rds;

class ArticleService
{
    public function index() {
        Rds::set('articles', 'test content');
        $articles = Rds::get('articles');
	return $articles;
    }

是不是变成非常方便?

控制器中调用服务类

经常遇到控制器中需要判断请求参数,然后调用不同的服务的情况,并且每个服务的参数数量都不是相同的,这时候也是可以使用 call_user_func_array 来完成这个功能的:

namespace App\Http\Controllers;

use App\Services\VideoService;
use Illuminate\Http\Request;

class VideoController extends Controller
{
    private static $service;

    public function __construct()
    {
        self::$service = new VideoService();
    }

    public function index(Request $r)
    {
        $offset = (int) $r->get('page');
        $size = (int) $r->get('size');
        $data = [$offset, $size, $r->get('tab')];

        self::ok(call_user_func_array([self::$service, $r->get('is_admin') ? 'getAdminVideos' : 'getUserVideos'], $data));
    }
}

上面的代码中,我需要根据 is_admin 参数来判断调用 VideoServicegetAdminVideosgetUserVideos 方法,他们接收的参数个数不是相同的

此时,我只需要借助 call_user_func_array,然后将参数按顺序放进 $data 中,即可完成调用,而且代码非常优雅,屡试不爽。

发布评论
还没有评论,快来抢沙发吧!