使用 call_user_func_array 让 PHP 代码变得更加优雅
自从使用了 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
参数来判断调用 VideoService
的 getAdminVideos
和 getUserVideos
方法,他们接收的参数个数不是相同的
此时,我只需要借助 call_user_func_array
,然后将参数按顺序放进 $data
中,即可完成调用,而且代码非常优雅,屡试不爽。
发布评论
还没有评论,快来抢沙发吧!