PHP链接...我只是无法得到它!

时间:2011-06-13 21:03:56

标签: php oop static replace method-chaining

我正在尝试创建一个链接函数来处理从XML文件返回的字符串。

1个原始字符串可能有多个替换,其中一些来自XML文件。

这是丑陋且标准的包装方法:

str_replace("what","is meant", str_replace("name","randomer",str_replace("blah", "hello", $string1)));

这是我正在尝试复制的方法(如Java):

$string1.replace("blah","hello").replace("name","randomer").replace("what","is meant");

通过上述内容,它可以轻松实现......直到我使用XML函数来获取替换字符串。

这是我的班级:

class resources{

private static $instance, $string;

public static function getString($stringName){
    # Create new instance
    self::$instance = new self;

    # Grabs stringName from an XML file
    self::$string = $stringName;

    # Return instance
    var_dump(self::$instance);
    return self::$instance;

}

public static function replace($replace_this, $with_this){
    # Replace and return instance
    self::$string = str_replace($replace_this, $with_this, self::$string);
    return self::$instance;
}

public static function show(){
    # Return String
    return self::$string;
}

}

echo resources::getString("alpha") // alpha
    ->replace("lpha","bravo") // abravo
    ->replace("vo", resources::getString("charlie")->show()) // should be abracharlie
 ->show(); // charlie

我希望它能理解为什么它不起作用,因为我认为应该如何以及它应该如何工作。 似乎当我再次调用类时(尽管var_dump说它是一个单独的实例),它用“charlie”替换原始文本,所以我不能只替换第一位的一部分。

谢谢,Dominic

编辑:是的!!我已经弄明白了(使用静力学)但看起来下面的Ryano有一个更好的解决方案

<?php

class resources{
private static $instance, $string, $originalString;

public static function getInstance($stringName){
    self::$instance = new self();
    self::$originalString = $stringName;
    return self::$instance;
}

public static function getString($stringName){
    # Grabs stringName from an XML file
    self::$string = $stringName;
    return self::$instance;
}

function replace($replace_this, $with_this){
    self::$originalString = str_replace($replace_this, $with_this, self::$originalString);
    self::$string = self::$originalString;
    return self::$instance;
}

function show(){
    return self::$string;
}

}

echo resources::getInstance("alpha") // alpha
    ->replace("lpha","bravo") // abravo
    ->replace("vo", resources::getString("charlie")->show()) // should be abracharlie
    ->replace("lie", resources::getString("vo")->show()) // abracharvo
    ->show(); // abracharvo

echo "<br />";

echo resources::getInstance("randomer") // randomer
    ->replace("er","") //  random
    ->replace("ran", resources::getString("")->show()) // dom
    ->replace("dom", resources::getString("Dom")->show()) // Dom
    ->show(); // Dom

echo "<br />";

echo resources::getInstance("nomster") // nomster
    ->replace("nom","nmo") //  nmoster
    ->replace("nom", resources::getString("mon")->show()) // nmoster
    ->replace("nmo", resources::getString("mon")->show()) // monster
    ->show(); // monster

?>

2 个答案:

答案 0 :(得分:2)

你的问题是一切都是静态的。我建议刷一些面向对象的编程基础知识。

因为一切都是静态的,所以在函数的所有调用之间共享状态。在第replace("vo", resources::getString("charlie")->show())行中,对resources::getString的嵌套调用将目前构建的字符串(abravo)替换为getString的{​​{1}}参数。然后调用包装函数,如charlie,但replace("vo", "charlie")的值现在为self::$string,不包含charlie,因此最后vo返回只需show()。如果您使用charlie调用vo,而不是replace("ar", resources::getString("charlie")->show()),则最终show()将返回chcharlielie

您必须使用非静态成员变量和方法创建一个类,以便维护不同的状态。

这是一个有效的版本:

class resources {

  private $string;

  public function __construct ($string) {
    $this->string = $string;
  }

  public static function getString ($string) {
    $obj = new resources($string);

    return $obj;
  }

  public function replace ($replace_this, $with_this) {
    # Replace and return instance
    $this->string = str_replace($replace_this, $with_this, $this->string);
    return $this;
  }

  public function show () {
    # Return String
    return $this->string;
  }

}

编辑:我喜欢上面的代码作为问题代码的最近转换。如果我自己写了类似的东西,我会进一步简化它:

class Str {
    private $str;

    private function __construct ($str) {
      $this->str = $str;
    }

    public static function with ($str) {
        return new Str($str);
    }

    public function replace($replace_this, $with_this) {
      $this->str = str_replace($replace_this, $with_this, $this->str);
      return $this;
    }

    public function __toString () {
      return $this->str;
    }
}

echo Str::with('nomster')->replace('nom', 'mon') . "\n";

现在不需要show(),并且输入的名称更好一些。这里可以添加许多其他有用的方法;你想要链接的任何php字符串函数。

答案 1 :(得分:0)

当您多次致电getString()时,由于您在new self()中致电getString(),因此您创建了多个实例。

为防止这种情况发生,您应该创建方法getInstance()并在getString()

中使用该方法
public static function getInstance() {
    if(!self::instance) {
        self::instance = new self();
    }
    return self::instance;
}

public static function getString() {
    $instance = self::getInstance();

    // use $instance here instead of self::instance
}