Как я могу заставить preg_replace работать во всех средах PHP? - PullRequest
0 голосов
/ 10 ноября 2018

Моя функция, использующая 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 голосов
/ 10 ноября 2018

Самая безопасная ставка - не доверять никаким буквальным пробелам / табуляциям, которым вы ожидаете соответствовать.

Вместо использования \t и я рекомендую \s+ там, где вы ожидаете вкладку, и \s там, где вы ожидаете пробел.

Кроме того, чтобы охватить случаи, когда операционная система может использовать \r\n или \n в конце каждой строки, вы можете использовать \R для соответствия обоим вариантам.

Я собираюсь включить проверку начала строки через ^ в начале шаблона и m в качестве модификатора шаблона. Это гарантирует, что мы сопоставим и сопоставим только в том месте, где вы ожидаете \t в начале строки.

Наконец, preg_replace() имеет необязательный 5-й параметр, который подсчитывает, сколько было сделано замен. Если $found является ненулевым значением, сохраните текущее значение $var.

Код: ( Демо )

$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(), потому что у вас есть «специальные символы», которые вы хотите экранировать.

...