是好是坏?为PHP提供“功能链”功能

时间:2009-01-23 06:31:06

标签: php language-features

所以我在想一种方法,你可以通过内置的全局函数将方法链接到PHP中,“借用”|>来自F#的(管道)操作员。它会将左侧的结果输入到右侧函数的第一个参数中。当然,PHP必须重新审视其某些功能的参数顺序。

这将允许你写:

function StrManip($val) {  
  return str_repeat(strtolower(trim($val)),2);  
}  

像这样:

function StrManip($val) {  
  return $val |> trim() |> strtolower() |> str_repeat(2);  
}  

4 个答案:

答案 0 :(得分:8)

看起来他想要的是一个String类,其方法可以反映内置函数。这是猜测,但也许您可以使用__call魔术方法来完成这样的工作:

(适用未经测试)

class String {
   private $_value = '';
   public function __construct($value) {
      $_value = $value;
   }
   public function __call ($name, $arguments) {
      return new String($name($_value, $arguments));
   }
}

$string = new String($string);
echo $string->trim()->strtolower()->str_repeat(2);

你必须做一些解析才能让$ arguments部分工作,并且当你链接方法时它会创建很多对象,但理论上这应该会为你提供一些你正在寻找的功能。

答案 1 :(得分:3)

使用流畅的对象方法可以完成类似的事情。例如:

class Foo 
{
    public function bar()
    {
        echo 'Hello<br/>';
        return $this;
    }

    public function bar2()
    {
        echo 'Goodbye<br/>';
        return $this;
    }   
}

$foo = new Foo();

$foo->bar()->bar2();

输出以下内容:

您好
再见

答案 2 :(得分:2)

我之前从未见过这种注释,但它看起来确实不错。不知何故让我想起函数编程(也许只是我)。

但我实际上已经不再希望PHP小组会对语言做出如此根本性的改变。他们似乎追赶其他语言 - 他们看看其他人在做什么,然后他们选择他们喜欢的东西,以及适合(ir)PHP世界的东西。作为示例,面向对象和名称空间是最新的功能,当您看到竞争对手时。

我个人希望看到命名参数(ála“strpos(needle=$foo, haystack=$bar)”),因为我在Python中看到了它们。从那时起,PHP设计组实际上已经refused来实现它。

答案 3 :(得分:0)

这很有趣。这个解决方案怎么样?

function pipe($v, $fs)
{   
    foreach(explode('|', $fs) as $f)
    {
        if(strpos($f, '[') === FALSE){
            $v = call_user_func($f, $v);
        }else{
            list($fun, $args) = explode('[', trim($f), 2);
            $args = explode(',', str_replace('!', $v, substr($args, 0, -1)));
            $v = call_user_func_array($fun, $args);
        }
    }
    return $v;
}


echo pipe(' test STRING??', 'trim|strtolower|str_repeat[!,3]|str_replace[string,cheese,!]');

打印出来

test cheese??test cheese??test cheese??

函数管道有两个参数。第一个是初始值,第二个是管道分隔的函数列表,要应用于第一个参数。为了允许多参数函数,可以使用[和]字符(就像在PHP中使用括号一样)。占位符'!'可用于指定沿链插入字符串的位置。

在上面的示例中,发生以下情况:

trim(' test STRING??') => 'test STRING??'
strtolower('test STRING??') => 'test string??'
str_repeat('test string??', 3) => 'test string??test string??test string??'
str_replace('string', 'cheese', 'test string??test string??test string??') => 'test cheese??test cheese??test cheese??'

字符[,]和!是任意选择的。此外,这不允许您在函数参数中使用逗号,尽管可以扩展它以允许它。

有趣的问题!

(想法来自Code Igniter的'|'分隔函数列表,虽然它们不做变量替换。它也可以很容易地成为字符串数组,但是array()构造函数是详细的)