[英]Recall chained methods on PHP
I call an object that returns an array given certain chained methods:我调用一个对象,该对象在给定某些链式方法的情况下返回一个数组:
Songs::duration('>', 2)->artist('Unknown')->genre('Metal')->stars(5)->getAllAsArray();
The problem lies that every time I want to get this array, for example, in another script, I have to chain everything again .问题在于,每次我想要获取这个数组时,例如在另一个脚本中,我必须再次链接所有内容。 Now imagine that in over 10 scripts.
现在想象一下,在 10 多个脚本中。
Is there a way to recall the chained methods for later use?有没有办法调用链式方法供以后使用?
If you can not cache your results as suggested, as I commented, here are a couple ideas.如果您无法按照建议缓存结果,正如我所评论的,这里有一些想法。 If your application allows for mixing of functions (as in you are permitted by standards of your company's development rules) and classes, you can use a function wrapper:
如果您的应用程序允许混合使用函数(因为您公司的开发规则标准允许您这样做)和类,您可以使用函数包装器:
// 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)));
If you are only allowed to use classes and __callStatic()
is not forbidden in your development and is also available in the version of PHP you are using, you might try that:如果您只允许使用类并且
__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();
}
This should return the same as your chain:这应该返回与您的链相同的内容:
print_r(\Songs::Unknown_Metal(5));
It should be noted that overloading is hard to follow because there is no concrete method called Unknown_Metal
so it's harder to debug.需要注意的是,重载很难遵循,因为没有名为
Unknown_Metal
具体方法,因此更难调试。 Also note I have not tested this particular set-up out locally, but I have notated what should happen where.另请注意,我没有在本地测试过这个特定的设置,但我已经注明了应该在何处发生的情况。
If those are not allowed, I would then make a method to shorten that chain:如果这些不被允许,那么我将制定一种方法来缩短该链:
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)));
Since you can't cache the result, you could cache the structure of the call chain in an array.由于您无法缓存结果,您可以将调用链的结构缓存在数组中。
$chain = [
'duration' => ['>', 2],
'artist' => 'Unknown',
'genre' => 'Metal',
'stars' => 5,
'getAllAsArray' => null
];
You could use that with a function that emulates the chained call using the cached array:您可以将它与使用缓存数组模拟链接调用的函数一起使用:
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);
I wrote a lib doing exactly what you're looking for, implementing the principle suggested by Don't Panic in a high quality way: https://packagist.org/packages/jclaveau/php-deferred-callchain我写了一个库,完全符合你的要求,以高质量的方式实现了 Don't Panic 建议的原则: https : //packagist.org/packages/jclaveau/php-deferred-callchain
In your case you would code在你的情况下,你会编码
$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) );
Hoping it will match your needs!希望它能满足您的需求!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.