如何使preg_replace在所有PHP环境中都能工作?

时间:2018-11-09 22:43:37

标签: php encoding preg-replace

我使用preg_replace的函数在开发服务器上运行完美,但在生产服务器上则完全没有。该问题可能与编码有关。有没有一种方法可以使该表达式不受编码的影响而起作用?

$ config看起来像这样:

class JConfig {
    public $mighty = array("0" => array("0" => "/`?\\#__mightysites[` \\n]+/u"), "1" => array("0" => "`hhd_mightysites` "));
    public $mighty_enable = '0';
    public $mighty_language = '';
    public $mighty_template = '9';
    public $mighty_home = '';
    public $mighty_langoverride = '0';......

我将与要剥离的线相关联的变量放在称为条带之类的数组中

$strips = array(
    'mighty',
    'mighty_enable',
    'mighty_sync',
    'mighty_language',
    'mighty_template',.....

然后使用循环将线条去除:

foreach ($strips as $var) {
    if (JString::strpos($config, 'public $' . $var . ' =') !== false) {
        $config = preg_replace('/\tpublic \$' . $var . ' \= ([^\;]*)\;\n/u', '', $config);
        $tempvar .= $var . ", ";
    }
}

同样,它在我们的开发服务器上完美运行。它不对生产服务器上的任何行执行任何操作。我也知道它通过了strpos,就像通过preg_replace到达了行。我可以制作preg_replace环境证明吗?

我非常感谢您的帮助,因为它仅在生产服务器上发生,因此很难测试!

1 个答案:

答案 0 :(得分:2)

最安全的选择是不要“信任”您希望匹配的任何文字空格/制表符。

我建议您在期望使用制表符的位置\t和期望使用空格的位置,而不是使用\s+\s

此外,要涵盖操作系统可能在每行末尾使用\r\n\n的情况,可以使用\R来匹配两个版本。

我将在模式的开头通过^包括行字符检查的开始,并通过m作为模式修饰符。这样可以确保我们匹配并且仅匹配您期望在行首出现\t的地方。

最后,preg_replace()有一个可选的第5个参数,用于计算进行了多少次替换。如果$found为非零值,则存储当前的$var值。

代码:(Demo

$config = <<<'CONFIG'
class JConfig {
    public $mighty = array("0" => array("0" => "/`?\\#__mightysites[` \\n]+/u"), "1" => array("0" => "`hhd_mightysites` "));
    public $mighty_enable = '0';
    public $mighty_language = '';
    public $mighty_template = '9';
    public $mighty_home = '';
    public $mighty_langoverride = '0';......
CONFIG;

$strips = [
    'mighty',
    'mighty_enable',
    'mighty_sync',
    'mighty_language',
    'mighty_template'
];

$tempvar = '';
foreach ($strips as $var) {
    $config = preg_replace('~^\s+public\s\$' . $var . '\s=\s[^;]*;\R~um', '', $config, -1, $found);
    if ($found) {
        $tempvar .= $var . ", ";
    }
}
echo "\$tempvar = $tempvar\n\n";
echo $config;

输出:

$tempvar = mighty, mighty_enable, mighty_language, mighty_template, 

class JConfig {
    public $mighty_home = '';
    public $mighty_langoverride = '0';......

p.s。建议的最后一项改进...如果您实际上实际上不需要项目的$tempvar变量(意味着您仅在调试期间使用此变量),则可以完全避免循环,并且只需implode('|', $strips),将生成的字符串包装在()中,另存为$var,然后仅调用preg_replace()。这样会更有效,并且不需要$strips来准备示例preg_quote()数据,因为有一些“特殊字符”可以逃脱。