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 ""10" y ' & ~10 Â ' \\ <a>"
. 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.";
}