No se puede reemplazar el retorno de carro y la nueva línea en php

4 minutos de lectura

Obtengo una cadena de la interfaz que tiene un salto de línea. Se guarda en una matriz que se ve así:

[address] => Array (
    [0] => Foo
Bar
)

Luego uso json_encode() en la matriz antes de escribirlo en la base de datos SQL:

$string = json_encode( $string, JSON_UNESCAPED_UNICODE );

Esto convierte la matriz en:

{"address":["Foo\r\nBar"]}

Desafortunadamente, a DB no le gusta \r o \n si no se escapa, por lo que se deshace de \r y \n.

  1. Entonces, la primera pregunta es, ¿hay alguna función que pueda usar para escapar correctamente de la cadena, de modo que pueda escribirse correctamente en la base de datos sin perder el salto de línea?

  1. No encontré ninguna función para eso, así que traté de usar str_replace para simplemente reemplazar \r\n con \\n. La función es:

$string = str_replace(["\r\n","\r","\n"], "\\n", $string);

Sin embargo, esto no funciona. no sé por qué La función en sí funciona, ya que traté de reemplazar solo “n” con “bla” y funcionó. Sin embargo, en el momento en que intento reemplazar la barra invertida, no encuentra nada para reemplazar. No sé si aquí se usa algún carácter de barra invertida “especial” o qué más podría estar pasando aquí.

Esto me está volviendo loco, en serio. Así que espero que alguien pueda ayudarme. Gracias por adelantado.

  • Solo usa PDO y no te preocupes por ninguna de esas cosas… en serio… no es difícil.

    – Dimi

    9 de febrero de 2017 a las 20:47

  • si estás usando str_replace para escapar de las cosas que eres HACIENDOLO MAL. Utilice una función de escape de base de datos adecuada. Esto depende de la interfaz que esté utilizando. Lo mínimo es usar algo como $db->escape(...). Es significativamente mejor usar declaraciones preparadas con valores de marcador de posición. Estos funcionan. Tu código no.

    – tadman

    09/02/2017 a las 20:50

  • Si está utilizando WordPress, consulte la Documentación de WPDB para más detalles.

    – tadman

    9 de febrero de 2017 a las 20:51

  • ¿Cómo estás pasando los datos a la base de datos? ¿Puede publicar su código y los datos de resultados que se almacenan en la base de datos después de ejecutar su código?

    – Umair Shah Yousafzai

    9 de febrero de 2017 a las 21:23

Avatar de usuario de Umair Shah Yousafzai
Umair Shah Yousafzai

Problema :
Su str_replace no funciona porque estás usando doble comillas.

Solución :
Debes reemplazar tu doble comillas con comillas simples y luego sucederá la magia 😀

$string = str_replace(['\r\n','\r','\n'], '\\n', $string);

INFORMACIÓN MUY ÚTIL: Para obtener más información, debe echar un vistazo a los detalles, ya que es útil conocer la diferencia entre doble comillas y comillas simples como:

¿Cuál es la diferencia entre cadenas entre comillas simples y dobles en PHP?

  • Muchas gracias, esto funcionó. También gracias por la información adicional, voy a leerlo. Sin embargo, tuve que usar hasta 3 barras invertidas para que funcionara: $cadena = str_replace([‘\r\n’,’\r’,’\n’], ‘\\\n’, $cadena); ¿Tienes alguna idea de por qué?

    – Chi

    9 de febrero de 2017 a las 21:24


  • No entiendo qué quiere decir con eso, ya que simplemente está reemplazando los caracteres en la cadena con solo otros caracteres, ¿también puede obtener cualquier cosa que escriba en la salida de la cadena?

    – Umair Shah Yousafzai

    9 de febrero de 2017 a las 21:27


Depende de cómo inserte la cadena en la base de datos. Independientemente de cómo lo hagas, debes escapar de él correctamente.

Si está utilizando PDO, puede lograr esto de esta manera:

$conn = new PDO(.....);
$sql_str = $conn->quote($string);
$conn->exec("INSERT INTO table (str_value) {$sql_str}");

O, mejor use una declaración preparada:

$conn = new PDO(.....);
$stm = $conn->prepare("INSERT INTO table (str_value) :value");
$stm->execute(array(':value' => $string));

Espero que funcione.

¿Almacenar JSON directamente en una base de datos? ¡Sí!

Sin embargo, si realmente debe hacerlo, ¿por qué siente la necesidad de cambiar la representación de los datos? Cuando lo vuelva a ejecutar a través de un decodificador JSON, recuperará los datos originales. El problema es solo cómo ponerlo en un formato seguro para insertarlo en su base de datos.

El hecho de que haya creado esto a partir de una matriz de PHP implica que NO TIENE EXCUSA para no verificar el contenido de los datos antes de guardarlos (no es que escribir datos suministrados directamente desde Javascript sea válido o perdonable de ninguna manera).

¿Hay alguna función que pueda usar para escapar correctamente de la cadena?

Sí, hay varias, pero no nos ha dicho qué API está utilizando. Este no es un truco mágico para resolver el problema en el que se encuentra actualmente: escapar cualquier dato que escriba en su base de datos correctamente es esencial para evitar la inyección de SQL.

Además de los métodos PDO mencionados por Alex, puede hacerlo en la extensión mysql (obsoleta) usando mysql_escape_cadena/mysql_real_escape_cadena o en código de procedimiento mysqli con mysql_escape_cadena / mysqli_real_escape_cadena o msqli_prepare + mysqli_bind_param. Las funciones mysqli también tienen representaciones orientadas a objetos.

¿Ha sido útil esta solución?