回想一下PHP

时间:2016-07-12 21:10:50

标签: php oop

我调用一个给定某些链式方法返回数组的对象:

Songs::duration('>', 2)->artist('Unknown')->genre('Metal')->stars(5)->getAllAsArray();

问题在于每次我想要获取此数组时,例如,在另一个脚本中,我必须再次链接所有内容。现在想象一下超过10个脚本。

有没有办法回忆链接的方法供以后使用?

3 个答案:

答案 0 :(得分:0)

如果你不能按照建议缓存结果,正如我评论的那样,这里有几个想法。如果您的应用程序允许混合功能(如您的公司标准允许的那样)和类,则可以使用函数包装器:

// The function can be as complex as you want
// You can make '>', 2 args too if they are going to be different all the time
function getArtists($array)
    {
        return \Songs::duration('>', 2)->artist($array[0])->genre($array[1])->stars($array[2])->getAllAsArray();
    }

print_r(getArtists(array('Unkown','Metal',5)));

如果您只允许使用类并且开发中不禁止使用__callStatic(),并且您使用的PHP版本中也提供了// If you have access to the Songs class public __callStatic($name,$args=false) { // This should explode your method name // so you have two important elements of your chain // Unknown_Metal() should produce "Unknown" and "Metal" as key 0 and 1 $settings = explode("_",$name); // Args should be in an array, so if you have 1 value, should be in key 0 $stars = (isset($args[0]))? $args[0] : 5; // return the contents return self::duration('>', 2)->artist($settings[0])->genre($settings[1])->stars($stars)->getAllAsArray(); } ,那么您可以尝试:

print_r(\Songs::Unknown_Metal(5));

这应该与你的链一样返回:

Unknown_Metal

应该注意的是,重载很难遵循,因为没有称为public function getArtists($array) { // Note, '>', 2 can be args too, I just didn't add them return self::duration('>', 2)->artist($array[0])->genre($array[1])->stars($array[2])->getAllAsArray(); } print_r(\Songs::getArtists(array('Unkown','Metal',5))); 的具体方法,因此调试起来比较困难。另请注意,我没有在本地测试过这个特定的设置,但我注意到应该在哪里发生。

如果不允许这样做,我会制定一种缩短该链的方法:

Input: 3,9,1,2,3,8,13,7,2,9,20,7,4,5,13,1,5,6,2,5,20,13,3,5,6

Output: Sorted unique array: 
        1 2 3 4 5 6 7 8 9 13 20
        Sorted unique array element frequency: 
        2 3 3 1 4 2 2 1 2 3 2

答案 1 :(得分:0)

由于您无法缓存结果,因此可以将调用链的结构缓存在数组中。

$chain = [
    'duration' => ['>', 2],
    'artist' => 'Unknown',
    'genre' => 'Metal', 
    'stars' => 5,
    'getAllAsArray' => null
];

您可以将其用于使用缓存数组模拟链式调用的函数:

function callChain($object, $chain) {
    foreach ($chain as $method => $params) {
        $params = is_array($params) ? $params : (array) $params;
        $object = call_user_func_array([$object, $method], $params);
    }
    return $object;
}

$result = callChain('Songs', $chain);

答案 2 :(得分:0)

我写了一个库,可以完全满足您的需求,并以高质量的方式实现了“不要惊慌”建议的原理:https://packagist.org/packages/jclaveau/php-deferred-callchain

在您的情况下,您可以进行编码

$search = DeferredCallChain::new_(Songs::class)  // or shorter: later(Songs::class)
    ->duration('>',2)   // static syntax "::" cannot handle chaining sadly
    ->artist('Unknown')
    ->genre('Metal')
    ->stars(5)
    ->getAllAsArray();

print_r( $search($myFirstDBSongs) );
print_r( $search($mySecondDBSongs) );

希望它能满足您的需求!