1

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」に置き換えられるため、最初のビットの一部を置き換えることはできません。

ありがとう、ドミニク

編集:はい!! 私はそれを(静力学を使用して)理解しましたが、以下の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

?>
4

2 に答える 2

2

あなたの問題は、すべてが静的であるということです。オブジェクト指向プログラミングの基礎をブラッシュアップすることをお勧めします。

すべてが静的であるため、状態は関数のすべての呼び出し間で共有されます。この行replace("vo", resources::getString("charlie")->show())では、ネストされた呼び出しにより、これまでに作成された文字列()が。である引数にresources::getString置き換えられます。次に、ラッピング関数はのように呼び出されますが、の値はになりました。これにはが含まれていないため、finalは単純にを返します。の代わりに、で呼び出した場合、finalは代わりにを返します。abravogetStringcharliereplace("vo", "charlie")self::$stringcharlievoshow()charlievoreplace("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文字列関数。

于 2011-06-13T22:23:49.550 に答える
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
}
于 2011-06-13T21:10:52.310 に答える