我对PHP很新,虽然我找到了解决问题的方法,但我觉得有一种更容易实现相同结果的方法:
这就是我需要做的事情:
我有一个像这样的字符串(在真正的字符串中有大约25个要替换的值)
"We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##"
在这个字符串中我必须替换
##AMOUNT##
,其值为$AMOUNT
的变量
##CURRENCY##
,其值为变量$CURRENCY
##ORDER_ID##
,其值为变量$ORDER_ID
目前我创建了一个数组:
$flds=['AMOUNT','CURRENCY','ORDER_ID'];
我用循环和动态变量替换:
但我已经看到str_replace也接受数组,因此可以构建一个更优雅(和有效)的解决方案
但是......我找不到它
可以提供一些提示吗?
由于
答案 0 :(得分:5)
您可以使用str_replace(),如果您有任意变量,可以使用compact()将它们放入数组中。
<?php
$str = "We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##";
$AMOUNT = 123;
$CURRENCY = 'GBP';
$ORDER_ID = 20123;
$find = ['##AMOUNT##','##CURRENCY##','##ORDER_ID##'];
$replace = compact('AMOUNT', 'CURRENCY', 'ORDER_ID');
echo str_replace($find, $replace, $str);
<强>结果:强>
我们已收到您的OrderID n的123英镑。 20123
如果您正在寻找一种方法来定义变量/占位符一次然后匹配和替换,您可以这样做:
<?php
$str = "We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##";
$AMOUNT = 123;
$CURRENCY = 'GBP';
$ORDER_ID = 20123;
$find = ['AMOUNT', 'CURRENCY', 'ORDER_ID'];
echo str_replace(
array_map(function($v){ return '##'.$v.'##'; }, $find),
compact(...$find),
$str
);
答案 1 :(得分:1)
你可以使用str_replace函数和两个数组,一个搜索的单词和第二个替换:
$words = ["##AMOUNT##", "##CURRENCY##", "##ORDER_ID##"];
$replaces = [$AMOUNT,$CURRENCY,$ORDER_ID];
$newString = str_replace($words, $replaces, $string);
echo $newString;
答案 2 :(得分:1)
我会创建一个简单的模板类来解析它,
class SimpleTemplate
{
protected $src;
protected $vars;
public function __construct($src)
{
$this->src = $src;
}
public function assign($key, $value)
{
$this->vars[$key] = $value;
}
public function out()
{
return str_replace(array_keys($this->vars),$this->vars,$this->src);
}
}
$T = new SimpleTemplate("We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##");
$T->assign('##AMOUNT##', 'foo');
$T->assign('##CURRENCY##', 'bar');
$T->assign('##ORDER_ID##', 'hello');
echo $T->out();
输出:
"We have received foo bar for your OrderID n. hello"
你可以看到它here live:
您可以随时对其进行扩展并添加功能,例如从作业中删除##
,以及删除任何未使用的标记。等...
基本上它只是变量的数组管理工具。因为我们正在构建这样的数组:
[
'##AMOUNT##' => 'foo',
'##CURRENCY##' => 'bar',
'##ORDER_ID##' => 'hello'
];
然后使用str_replace
我们使用键作为搜索,将值作为替换值。
如果您想从标记分配中删除##
,请更改此项:
public function assign($key, $value)
{
$this->vars['##'.$key.'##'] = $value;
}
然后这样打电话:
$T->assign('AMOUNT', 'foo');
这里真正的好处是拥有一个实现逻辑的类。它保持清洁和可重用。
正如@LawrenceCherone在评论中提到的那样,你可以通过一些神奇的方法获得更清晰的界面。
class SimpleTemplate
{
protected $src;
protected $vars;
public function __construct($src)
{
$this->src = $src;
}
public function __set($key, $value)
{
$this->vars['##'.strtoupper($key).'##'] = $value;
}
public function __toString()
{
return str_replace(array_keys($this->vars),$this->vars,$this->src);
}
}
$T = new SimpleTemplate("We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##");
$T->Amount = 'foo'; //any casing works because of the transforms, in __set
$T->CURRENCY = 'bar';
$T->order_id = 'hello';
echo $T; //using __toString() lets us just output the class as our result string.
具体为__set
和__toString
。对于这个,我在key
上进行了一些变换,以使其更容易出错,并且不那么难看。例如,使用Mixed Casing作为动态属性。通过使用strtoupper
,可以在任何情况下输入它们,删除#
可以防止像这样$T->{'##AMOUNT##'} = 'foo';
我要补充的最后一件事是,如果你能拥有&#34;标签&#34;如果没有分配但希望删除它们,您可以使用此regx删除它们。
public function __toString()
{
$str = str_replace(array_keys($this->vars),$this->vars,$this->src);
return preg_replace(['/##\w+##/', '/\s{2,}/'], ['', ' '], $str); //remove any left over ##{word}## tags, and compress any run-on spaces.
}
您可以看到此here
的示例数组/\s{2,}/
中的第二个,只需要在空格上运行并将它们压缩到一个空格,所以如果你有4个空格就会变成一个空格。它没有详细记录,但
preg_replace
可以像str_replace
一样使用数组。
这就是为什么我建议建立一个班级,它为你提供了一个很好的地方来实现所有这些&#34;东西&#34;如果你愿意,而不必一直重写它。
答案 3 :(得分:0)
更优雅的方式是printf
功能。
vsprintf("We have received %s %s for your OrderID n. %s", array($AMOUNT, $CURRENCY, $ORDER_ID));
答案 4 :(得分:0)
str_replace
will work with arrays. If $find
is an array and $replace
is a string it will replace everything in $find
with the string in $replace
if both are arrays it will replace each corresponding element $find[index]
with their corresponding $replace[index]
example:
$find = ["find1", "find2" ];
$replace = [ "replace1", "replace2" ];
$string = "Find find1 and find2";
echo str_replace($find, $replace, $string); // "Find replace1 and replace2"
However there is a small catch in that the replacements are done in sequence. It generally isn't a problem until you encounter something like:
$find = [ "find", "find2" ];
$replace = [ "replace", "replaceXX2" ];
$string = "Find find1 and find2";
echo str_replace($find, $replace, $string); // "Find replace1 and replace2"
Why? Because it will replace both the "find" word and the "find" that is part of find2 with replace before it even looks for "find2".
If you want to avoid that you can use strtr
as follows:
$find = [ "find" => "replace" , "find2" => "replaceXX" ];
$string = "Find find1 and find2";
echo strtr($string, $find); // "Find replace1 and replaceXX"
答案 5 :(得分:0)
@Lawrence Cherone回答的另一种方式。也许你想使用key => value
列表。
<?php
$message = "We have received ##AMOUNT## ##CURRENCY## for your OrderID n. ##ORDER_ID##";
$messageParameters = [
'AMOUNT' => 83,
'CURRENCY' => 'USD',
'ORDER_ID' => 3271096
];
$parsedMessage = str_replace(
array_map(function($v){ return '##'.$v.'##'; }, array_keys($messageParameters)),
array_values($messageParameters),
$message
);
echo $parsedMessage;
结果:
We have received 83 USD for your OrderID n. 3271096