preg_replace_callback does not work

0

I'm trying to change a variable with preg_replace_callback, but I'm not succeeding, does anyone know where the error is ??

 $replacements = array(
                '[PEDIDO]' => $oID,
                '[NOME]' => $order->customer['name'],
                '[VALOR]' => $order->totals['ot_subtotal'],
                '[FRETE]' => $order->totals['ot_shipping'],
                '[DESCONTO]' => $order->totals['ot_payment'],
                '[TOTAL]' => $order->totals['ot_total'],
            );

 $msg = preg_replace_callback('/[\w+]/', 
                        create_function('$matches',
                          'return $replacements[$matches[0]];'
                    , $m['msg']));
    
asked by anonymous 02.08.2014 / 03:47

3 answers

2

Well that solved it, but I need to consider a few points and even explain why your code did not work as you hoped.

create_function () is not only a dangerous feature because it is subject to all security issues related to evil eval () as well as poor performance.

Not to mention that the Closures were introduced as an alternative in PHP 5.3 released in June 2009 (more than 5 years ago). I strongly suggest an upgrade.

Also, whenever possible, consider not to use ERs. If you have no regular pattern, as you solved yourself, working directly with the strings is much easier (and faster).

But the reason it did not work, beyond of two syntax errors, since create_function () expects two rather than three arguments and preg_replace_callback () expects three rather than two, E of the missing as pointed out by @Jader, you have suffered from the old case of Variable Scope .

Although create_function return a string, for preg_replace_callback () she is a callable . Not that create_function returns a function, but it is interpreted as one and therefore is subject to local scope "constraints" and global.

In summary:

$order = "Pedido: [PEDIDO]\nNome: [NOME]\nValor: [VALOR]\nFrete: [FRETE]\n Desconto: [DESCONTO]\nTotal: [TOTAL]";

$replacements = array(
                '[PEDIDO]' => 123,
                '[NOME]' => 'Bruno Augusto',
                '[VALOR]' => 69.00,
                '[FRETE]' => 0,
                '[DESCONTO]' => 69.00,
                '[TOTAL]' => 'It\'s FREE!',
            );

  $order = preg_replace_callback(

          '/\[\w+\]/', // Colchetes escapados

          create_function(

               // Variável globalizada

              '$matches', 'global $replacements; return $replacements[$matches[0]];'
          ),

          // Número de argumentos corrigido

          $order
);

I would return, as expected:

  

Order: 123 Name: Bruno Augusto Price: 69 Shipping: 0 Discount: 69 Total: It's FREE!

    
02.08.2014 / 14:07
1

So it worked well here:

$replacements = array(
                '[PEDIDO]' => $oID,
                '[NOME]' => $order->customer['name'],
                '[VALOR]' => $order->totals['ot_subtotal'],
                '[FRETE]' => $order->totals['ot_shipping'],
                '[DESCONTO]' => $order->totals['ot_payment'],
                '[TOTAL]' => $order->totals['ot_total'],
            );

   $msg = preg_replace_callback('/\[\w+\]/', 
                        function ($matches) {
                            global $replacements;
                            return $replacements[$matches[0]];
                        }
                    , $m['msg']);
    
02.08.2014 / 04:13
0

The solution for me was to change the way I was doing so I wasted no time.

$in = array('[PEDIDO]','[NOME]','[VALOR]','[FRETE]','[DESCONTO]','[TOTAL]');
$out = array($oID, $order->customer['name'],$order->totals['ot_subtotal'],$order->totals['ot_shipping'],$order->totals['ot_payment'],$order->totals['ot_total']);  

$msg = str_replace($in, $out, $m['msg']);

It's there to help someone.

    
02.08.2014 / 04:53