Pregunta

¿Cuál es la mejor manera de tomar un texto plano (no un código PHP) que contenga variables de estilo PHP y luego sustituirlo por el valor de la variable? Esto es un poco difícil de describir, así que aquí hay un ejemplo.

// -- myFile.txt --
Mary had a little $pet.

// -- parser.php --
$pet = "lamb";
// open myFile.txt and transform it such that...
$newContents = "Mary had a little lamb.";

He estado considerando usar una expresión regular o tal vez eval(), aunque no estoy seguro de cuál sería más fácil. Este script solo se ejecutará localmente, por lo que cualquier preocupación relacionada con problemas de seguridad y get_defined_vars() no se aplica (¿creo?) .

También agregaré que puedo obtener todas las variables necesarias en una matriz usando <=>:

$allVars = get_defined_vars();
echo $pet;             // "lamb"
echo $allVars['pet'];  // "lamb"
¿Fue útil?

Solución

Si es de una fuente confiable, puede usar (pausa dramática) eval () (jadeos de horror de la audiencia).

$text = 'this is a $test'; // single quotes to simulate getting it from a file
$test = 'banana';
$text = eval('return "' . addslashes($text) . '";');
echo $text; // this is a banana

Otros consejos

Regex sería bastante fácil. Y no le importarían cosas que eval() considerarían un error de sintaxis.

Aquí está el patrón para encontrar nombres de variables de estilo PHP.

\$\w+

Probablemente tomaría este patrón general y usaría una matriz PHP para buscar cada coincidencia que haya encontrado (usando (preg_replace_callback()). De esa manera, la expresión regular debe aplicarse solo una vez, lo que es más rápido a largo plazo .

$allVars = get_defined_vars();
$file = file_get_contents('myFile.txt');

// unsure if you have to use single or double backslashes here for PHP to understand
preg_replace_callback ('/\$(\w+)/', "find_replacements", $file);

// replace callback function
function find_replacements($match)
{
  global $allVars;
  if (array_key_exists($match[1], $allVars))
    return $allVars[$match[1]];
  else
    return $match[0];
}

Esto es lo que acabo de inventar, pero todavía estaría interesado en saber si hay una mejor manera. Saludos.

$allVars = get_defined_vars();
$file = file_get_contents('myFile.txt');

foreach ($allVars as $var => $val) {
    $file = preg_replace("@\\$" . $var . "([^a-zA-Z_0-9\x7f-\xff]|$)@", $val . "\\1", $file);
}

¿Tiene que ser $ pet? ¿Podría ser <?= $pet ?> en su lugar? Porque si es así, solo usa include. Esta es toda la idea de php como un motor de plantillas.

//myFile.txt
Mary had a little <?= $pet ?>.

//parser.php

$pet = "lamb";
ob_start();
include("myFile.txt");
$contents = ob_end_clean();

echo $contents;

Esto hará eco:

Mary had a little lamb.

Dependiendo de la situación, str_replace podría hacer el truco.

Ejemplo:

// -- myFile.txt --
Mary had a little %pet%.

// -- parser.php --
$pet = "lamb";
$fileName = myFile.txt

$currentContents = file_get_contents($fileName);

$newContents = str_replace('%pet%', $pet, $currentContents);

// $newContents == 'Mary had a little lamb.'

Cuando observa str_replace, tenga en cuenta que los parámetros de búsqueda y reemplazo pueden tomar matrices de valores para buscar y reemplazar.

Puede usar strtr :

$text = file_get_contents('/path/to/myFile.txt'); // "Mary had a little $pet."
$allVars = get_defined_vars(); // array('pet' => 'lamb');
$translate = array();

foreach ($allVars as $key => $value) {
    $translate['$' . $key] = $value; // prepend '$' to vars to match text
}

// translate is now array('$pet' => 'lamb');

$text = strtr($text, $translate);

echo $text; // "Mary had a little lamb."

Probablemente quiera hacer el prepending en get_defined_vars (), para no repetir las variables dos veces. O mejor aún, solo asegúrese de que las teclas que asigne inicialmente coincidan con el identificador que usa en myFile.txt.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top