El modificador e, correspondiente a la constante PCRE PREG_REPLACE_EVAL, era utilizado en expresiones regulares junto a la función preg_replace() cuando era necesario ejecutar PHP para generar el string de salida.

Para hacer su trabajo, el modificador e echaba mano de la función eval(), una función muy delicada en lo que a seguridad se refiere, y por ello el modificador e fue deprecidado en PHP 7. En su lugar se recomienda utilizar preg_replace_callback(), ya que nos permite definir un callback propio donde podemos ejecutar PHP si es necesario, pero sin necesidad de recurrir a eval().

¿Por qué ha sido depreciado?

Vamos a ver un sencillo ejemplo para explicarlo; imaginemos esta expresión donde pasamos un título a letras mayúsculas aplicando la función strtoupper() al string de salida de preg_replace():

$title = "<h1>The /e modifier</h1>";
$title = preg_replace(
    '#<h([1-6])>(.*?)</h\1>#e',
    '"<h$1>" . strtoupper("$2") . "</h$1>"',
    $title
);

Lo que hace preg_repalce() es:

  1. Busca el patrón definido en la expresión regular (primer parámetro) en la variable $title
  2. Captura los fragmentos que coincidan con los conjuntos entre paréntesis: ([1-6]) y (.*?), y los numera por orden de aparición: 1, 2, etc (0 sería la coincidencia completa).
  3. Duelve el string del segundo parámetro sustituyendo las referencias $1, $2, etc, por los correspondientes valores capturados en el paso anterior.

Si observamos el string de salida, podemos ver que se ejecuta una función, strtoupper() , pero la función está contenida en un string. Para que funciones PHP contenidas en un string sean ejecutadas, hay que pasar ese string a la funcnón eval(), y eso es lo que hace el modificador e.

Imaginemos ahora el mismo código pero tomando el valor de $title desde un input:

$title = $__GET['title'];
$title = preg_replace(
    '#<h([1-6])>(.*?)</h\1>#e',
    '"<h$1>" . strtoupper("$2") . "</h$1>"',
    $title
);

Si el usuario introduce código PHP en el string de entrada, ese código sería ejecutado debido al uso que comentábamos de la función eval(). Es un punto débil de seguridad, ese es el motivo por el que el modificador e fue depreciado en PHP 7, y motivo por el que la propia función eval() se debe utilizar con muchísima precaución.

Alternativa: preg_replace_callback()

Para conseguir el mismo resultado que con preg_replace() y el modificador e, pero sin el riesgo de utilizar eval(), se puede utilizar preg_replace_callback(), función que nos permite definir un callback propio dónde podemos manejar los valores capturados y generar el string de salida como deseemos, incluyendo la ejecución de código.

El ejemplo anterior quedaría:

$title = $__GET['title'];
$title = preg_replace_callback(
    '#<h([1-6])>(.*?)</h\1>#',
    function ( $matches ) {
        $output = '<h' . $matches[1] . '>' . strtoupper( $matches[2] ) .'</h' . $matches[1] . '>';
        return $output;
    },
    $title
);

O un poco mejor:

$title = $__GET['title'];
$title = preg_replace_callback(
    '#<h([1-6])>(.*?)</h\1>#',
    function ( $matches ) {
        $output = '<h%1$d>%2$s</h%1$d>';
        return sprintf(
            $output,
            $matches[1],
            strtoupper( $matches[2] )
        );
    },
    $title
);

En pocas palabras, si se necesita ejecutar PHP en el string de salida de preg_replace(), hay que utilizar preg_replace_callback().

En versiones inferiores a PHP 7 se puede utilziar preg_replace() y el modificador e, funcionará, pero por ser un potencial agujero de seguridad, mejor utilizar preg_replace_callback() incluso en versiones inferiores a PHP 7.