sprintf生成字符串不符合预期,需在迭代中批量替换字符串
问题分析与修复方案
我一眼就看到两个关键问题导致你的代码达不到预期效果:
1. sprintf() 用法错误
你现在写的sprintf(5, $operator , $value)完全不符合sprintf的语法规则——它的第一个参数必须是格式控制字符串,而不是数字5。你想要生成5>3或5<0这类字符串,应该把格式字符串写成包含占位符的形式,比如:
// 如果value是字符串类型用%s,数字类型用%d更严谨 $condition = sprintf("5%s%s", $operator, $value);
这样当$operator是>、$value是3时,就能生成你要的5>3了。
2. 字符串替换的迭代逻辑错误
你每次循环都用原始的$stringSet去做str_replace,这会导致之前的替换结果被丢弃。比如第一次把1换成5>3得到5>3 AND 2,但第二次循环又回到最初的1 AND 2去替换2,最后结果变成1 AND 5<0,完全不是你想要的最终组合字符串。
正确的做法是初始化一个变量保存当前的替换结果,每次迭代都基于这个变量继续修改:
foreach (self::model()->findAll($q) as $ruleSet) { $stringSet = $ruleSet->logic; // 初始内容为"1 AND 2" // 初始化$w为原始字符串,后续迭代基于它修改 $w = $stringSet; foreach (CampaignAutoLogic::model()->findAll($q) as $rule) { $operator = $rule->operator; $value = $rule->value; // 修复后的sprintf $condition = sprintf("5%s%s", $operator, $value); // 基于上一次替换后的$w进行替换 $w = str_replace($rule->id, $condition, $w); } // 这里的$w就是最终替换完成的字符串了,比如"5>3 AND 5<0" }
另外额外提个小建议:如果$rule->id有可能出现在$condition的内容里(比如value里包含数字1),最好用更精准的替换方式,比如给id加上边界标记(比如原始字符串写成"[1] AND [2]"),然后替换"[$rule->id]",避免误替换。
内容的提问来源于stack exchange,提问作者Shiromi
相关产品推荐
相关产品推荐

