PROCESAR CARACTERES ESPECIALES
En tablas, y por json
1) Leer los caracteres especiales de una tabla:

Para lograr esto se deben cumplir varios requisitos:
  • Obviamente la página tendra en el head un <meta charset="UTF-8">
  • Si es un script PHP: header("Content-Type: text/html;charset=utf-8");
  • El cotejamiento (collate) de la tabla preferentemente será utf8mb4_unicode_ci
  • El cotejamiento (collate) de los campos string preferentemente será utf8mb4_spanish_ci
  • Una vez abierta la conexión incluimos mysqli_set_charset($conn, "utf8mb4"); antes del mysqli_query.
  • Los campos de texto deben tratarse con htmlspecialchars() o los caracteres < y > no aparecerán.
  • LISTO, la tabla se carga con todos los caracteres
2) Enviar por POST desde un form directamente o por AJAX:

  • En este caso si tengo que enviar el literal "10" y ' & ~10 Â ' \ <a> desde un input como value o en una variable string de PHP lo debo cargar con las "", '',< y > convertidos en entidades html. y la \ escapada doble o sea \\
    O sea "&quot;10&quot; y &apos; & ~10 Â &apos; \\ &lt;a&gt;" . Si el input se teclea desde teclado, no hay problema.
  • Si se manda desde un form directamente esto es todo (pasar al punto script PHP).
  • Si se envia por AJAX, una vez capturado los valores var entrada1= $('#texto21').val(); en data: irán como pares clave:valor ej: data: {texto1:entrada1,texto2:entrada2}, prestar atención que la clave NO va entrecomillada y el valor es una variable.
  • Al usar $_POST["variable"]; en el script PHP debo usar htmlspecialchars($recibido); o se perderán caracteres restringidos.
  • Si enviamos por ajax como "dataType: 'text'" y generamos el post como una cadena "clave1=valor1&clave2=valor2...." el post se corta en el primer ampersand embebido en los valores y en el ejemplo devoverá "10" y ' y en el ampersand ya falla.
3) Enviar por SQL caracteres especiales ( por ej :SELECT O INSERT):

En este caso si usamos "SELECT * FROM caracteres WHERE marca like '%" . $_POST["texto"] . "%'"; si hay comillas dobles o simples, barras invertidas etc. la página da error y si escapamos con htmlspecialchars($_POST["texto"]) entonces no tira error, pero no encuentra el registro.
La solución es usar sentencias preparadas (que escapa casi todos los caracteres especiales y evita la inyección SQL) y escapar la variable embebida con mysqli_real_escape_string($conn,$recibido); que escapa los caracteres NUL (ASCII 0), \n, \r, \, ', ", y Control-Z.. En el código está el ejemplo para devolver un registro, pero en SENTENCIAS PREPARADAS hay un ejemplo de recuperación de varios registros. Los campos de texto se tratan con htmlspecialchars() antes de enviarlos para evitar problemas con los caracteres < y >.

4) Leer e insertar por SQL un csv con caracteres especiales

  • LEER:
    En el caso de hacerlo directamente en la página html y no parsear el string recibido usamos fgets() y lo recibido le aplicamos htmlspecialchars()
  • ESCRIBIR EN LA DB (AJAX):
    En este caso por ser el contenido del .csv no malicioso (caso contrario agregar SQL preparados) usamos en INSERT directo pero escapamos lo que se recibe del csv con mysqli_real_escape_string($conn,$data[n]); $data[n] porque la función $data=fgetcsv($puntero, 1000, ";")parsea las lineas del .csv (max 1000 lineas, separador de campo ";") y las mete en el array $data, del cual saco los campos por índice.
Obviamente en el "ver en acción" la linea $sqldevolucion = mysqli_query($conn,$sqltxt); está comentada.
						
1) Leer los caracteres especiales de una tabla:
<?php 
	if(conectar()){
		mysqli_set_charset($conn, "utf8mb4");
		$sqltxt = "SELECT id,marca,modelo FROM caracteres";
		$sqldevolucion = mysqli_query($conn,$sqltxt);
		if (!mysqli_num_rows($sqldevolucion)) {
			echo("NO HAY REGISTROS");
		} else {
             while ($registro = mysqli_fetch_array($sqldevolucion, MYSQLI_ASSOC)){ 
				echo($registro["id"] . "<br/>" );
				echo(htmlspecialchars($registro["marca"]) . "<br/>" );   // para mostrar < y >
				echo(htmlspecialchars($registro["modelo"]) . "<br/>" );	// para mostrar < y >
			}
			mysqli_free_result($sqldevolucion);     //devuelvo recurso a memoria
			mysqli_close($conn);			// cierro conexion
		}
	}else{
		echo(mysqli_error($conn));					//no se puede conectar con la DB
	} 
?>
2) Enviar por POST y recibir desde un form o AJAX:

Jquery ( supuestos 2 input, "texto21" y "texto22" y un botón "enviar2")

<script>
  $("#enviar2").click(function(evento){
				var entrada1= $('#texto21').val();
				var entrada2= $('#texto22').val();
				$.ajax({       
					type: "POST",  
					url: "tec-php-caracteres-procesar.php?accion=2",  
					data: {texto1:entrada1,texto2:entrada2},
					dataType: 'text',  
					success: function(datos) { 
						if(datos.indexOf('Error') != 0){
							$('#msg2').html(datos);		 
						}else{
							$('#msg2').html('error en el ajax');
						}
					}	 //fin success
				});   		 //fin ajax
			});
</script>

Script PHP 

Switch ($accion){
   case "2":
		$recibido1 = $_POST["texto1"];
		$recibido2 = $_POST["texto2"];
		$preparado1 = htmlspecialchars($recibido1);
		$preparado2 = htmlspecialchars($recibido2);
		echo ($preparado1 . '
' . $preparado2); //htmlspecialchars se aplica antes de armar el echo o
break; // no funciona, va literal. } 3) Enviar por SQL caracteres especiales por ej un SELECT por AJAX: Jquery ( supuestos 1 input, "texto3" y un botón "enviar3") <script> $("#enviar3").click(function(evento){ var entrada= $('#texto3').val(); $.ajax({ type: "POST", url: "tec-php-caracteres-procesar.php?accion=3", data: {texto:entrada}, dataType: 'json', success: function(datos) { if (datos.id=="Nulo"){ $("#msg3").html(datos.marca); }else{ $('#msg3').html(datos.id + '   '+ datos.marca + '   '+ datos.modelo); } } }); }); </script> Script PHP $recibido = $_POST["texto"]; if(conectar()){ Try{ mysqli_set_charset($conn, "utf8mb4"); $recibido = mysqli_real_escape_string($conn,$recibido); //Los caracteres codificados son NUL (ASCII 0), \n, \r, \, ', ", y Control-Z. $recibido = $recibido . "%"; //$sqltxt = "SELECT id,marca,modelo FROM caracteres WHERE marca=?"; $sqltxt = "SELECT id,marca,modelo FROM caracteres WHERE marca like ?" ; $sentencia = $conn->prepare($sqltxt); //1 prepara la sentencia $sentencia->bind_param("s", $recibido); //2 enlaza la variable $sentencia->execute(); //3 ejecuta la consulta $resultado = $sentencia->get_result(); //4 pasa el resultado a un array en cache $n = $resultado->num_rows; //5 N° de registros devueltos if($n==0){ //6 si no hay registros..... $salida = array('id'=>'Nulo','marca'=> 'No hay registros','modelo'=> ' '); }else{ $registro = $resultado->fetch_array(); //7 recupero el registro $salida = array('id'=> $registro["id"],'marca'=> htmlspecialchars($registro["marca"]),'modelo'=> htmlspecialchars($registro["modelo"])); } $sentencia->close(); }catch(Exception $e){ $salida = array('id'=>'Nulo','marca'=> 'Error al recuperar el registro','modelo'=> ' '); //echo("no se pudo encontrar los registros por error: " . $e); } }else{ $salida = array('id'=>'Nulo','marca'=> 'No se puede abrir la base de datos','modelo'=> ' '); //echo(mysqli_error($conn)); //no se puede conectar con la DB } echo (json_encode($salida)); 4) Leer e insertar por SQL un csv con caracteres especiales Código PHP embebido en html para leer el .csv <div style="border:#333 solid 1px; padding:10px; width:fit-content;float:left;"> <?php $arch = "tec-php-caracteres.csv"; if (file_exists ($arch)) { if($conector = fopen($arch, "r")){ //no puedo abrir el .txt while(!feof($conector)){ $cadena = fgets($conector); echo htmlspecialchars($cadena) . "<br/>"; } fclose($conector); }else{ echo "No se puede abrir el archivo "; } }else{ echo "No existe el archivo "; } ?> </div> Jquery ( supuesto un botón "enviar4") <script> $("#enviar4").click(function(evento){ $.ajax({ type: "POST", url: "tec-php-caracteres-procesar.php?accion=4", dataType: 'text', success: function(datos) { $('#msg4').html(datos); } }); }); </script> Código script PHP if (file_exists("tec-php-caracteres.csv")) { //si existe el fichero if(conectar()){ //si abre la DB $data = array(); if($puntero = fopen("tec-php-caracteres.csv","r")){ //si abre el .csv mysqli_set_charset($conn, "utf8mb4"); while (($data = fgetcsv($puntero, 1000, ";")) !== FALSE) { $marca = mysqli_real_escape_string($conn,$data[0]); $modelo = mysqli_real_escape_string($conn,$data[1]); $sqltxt="INSERT INTO caracteres (marca,modelo) VALUES ('" . $marca . "','" . $modelo . "')"; $sqldevolucion = mysqli_query($conn,$sqltxt); } fclose($puntero); //cierro conexión al .csv echo "exito"; }else{ echo "No se puede abrir el archivo csv."; } mysqli_close($conn); // cierro conexion a la DB }else{ echo "No se puede abrir la base de datos."; } } else { echo "tec-php-caracteres.csv no existe, subir el archivo."; }
© IQSystems 2023