为什么这个PHP spintax代码重复相同的迭代?

时间:2012-08-03 22:24:56

标签: php spintax

http://ronaldarichardson.com/2011/09/23/recursive-php-spintax-class-3-0/

我喜欢这个剧本,但它并不完美。如果您使用此测试输入案例:

  

{这是我的{spintax | spuntext}格式化字符串,我的{spintax | spuntext}格式化字符串,我的{spintax | spuntext}格式化字符串示例。}

你可以看到结果总是包含3次重复的" spintax"或" spuntext"。它永远不会包含1" spintax"和2" spuntext",例如。

示例:

  

这是我的spuntext格式化字符串,我的spuntext格式化字符串,我的spuntext格式化字符串示例。

要真正随机,它需要为每个spintax {|}块生成一个随机迭代,而不是对相同的块重复相同的选择,如{spintax | spuntext}。

如果您查看该页面上的注释#7,那么fransberns就会出现问题,但是当在实时环境中使用他修改过的代码时,该脚本会在无限循环中重复运行并占用所有服务器内存。所以那里肯定有一个错误,但我不确定它是什么。

有什么想法吗?或者有没有人知道一个强大的PHP spintax脚本允许嵌套的spintax并且是真正的随机?

2 个答案:

答案 0 :(得分:1)

请检查此gist,它正常工作(它比原始代码简单得多..)。

答案 1 :(得分:1)

Spintax类用相同的随机选择的选项替换{spintax | spuntext}的所有实例的原因是因为该类中的这一行:

  $str = str_replace($match[0], $new_str, $str);

str_replace函数用搜索字符串中的替换替换子字符串的所有实例。要替换仅第一个实例,按照需要以串行方式进行,我们需要使用函数preg_replace并将传递的“count”参数设置为1.但是,当我查看时your link到Spintax类并引用#7后我注意到他对Spintax类的建议扩充中出现错误。

fransberns 建议更换:

$str = str_replace($match[0], $new_str, $str);

用这个:

//one match at a time
$match_0 = str_replace("|", "\|", $match[0]);
$match_0 = str_replace("{", "\{", $match_0);
$match_0 = str_replace("}", "\}", $match_0);
$reg_exp = "/".$match_0."/";
$str = preg_replace($reg_exp, $new_str, $str, 1);

fransbergs'建议的问题是,在他的代码中,他没有正确构造preg_replace函数的正则表达式。他的错误来自于没有正确转义\字符。他的替换代码应该是这样的:

//one match at a time
$match_0 = str_replace("|", "\\|", $match[0]);
$match_0 = str_replace("{", "\\{", $match_0);
$match_0 = str_replace("}", "\\}", $match_0);
$reg_exp = "/".$match_0."/";
$str = preg_replace($reg_exp, $new_str, $str, 1);

考虑使用我对 fransberns 建议的replacemnet上的更正,用这个扩充版本替换原始类:

class Spintax {

   function spin($str, $test=false)
   {
      if(!$test){
         do {
            $str = $this->regex($str);
         } while ($this->complete($str));
         return $str;
      } else {
         do {
            echo "<b>PROCESS: </b>";var_dump($str = $this->regex($str));echo "<br><br>";
         } while ($this->complete($str));
         return false;
      }
   }

   function regex($str)
   {
      preg_match("/{[^{}]+?}/", $str, $match);
      // Now spin the first captured string
      $attack = explode("|", $match[0]);
      $new_str = preg_replace("/[{}]/", "", $attack[rand(0,(count($attack)-1))]);
//      $str = str_replace($match[0], $new_str, $str); //this line was replaced
      $match_0 = str_replace("|", "\\|", $match[0]);
      $match_0 = str_replace("{", "\\{", $match_0);
      $match_0 = str_replace("}", "\\}", $match_0);
      $reg_exp = "/".$match_0."/";
      $str = preg_replace($reg_exp, $new_str, $str, 1);    
      return $str;
   }

   function complete($str)
   {
      $complete = preg_match("/{[^{}]+?}/", $str, $match);
      return $complete;
   }
}

当我尝试使用 fransberns'建议替换“按原样”时,由于\字符的不正确转义,我得到了一个无限循环。我认为这是你的记忆问题的来源。在纠正了 fransberns'建议替换后,我没有进入\字符的正确转义。

使用更正的扩充程序尝试上面的类,看看它是否适用于您的服务器(我看不出它不应该出现的原因)。