If your comparison is latin2_general_ci
( ISO 8859-2
, does not support neither ñ
or ¡
) then I recommend that all your code work with it and do not use neither utf8_encode
or utf8_decode
since no will have no effect:
<?php
/* Avisamos que el contenido está codificado en iso-8859-2 */
header('Content-Type: text/html; charset=iso-8859-2');
/* Si estamos recibiendo el formulario insertamos el registro */
if (isset($_POST['cad'])) {
/* Establecemos la conexión */
$conexion = mysqli_connect($servidor, $usuario, $pass, $bbdd) or die("Error 505 NOT FOUND");
/* Hacemos coincidir el juego de caracteres con el cotejo de la base de datos */
mysqli_set_charset($conexion, 'latin2');
/* Preparamos la consulta */
$consulta = mysqli_prepare($conexion, '
INSERT into datos (texto, cadenas )
VALUES (?, ?)
');
if ($consulta === false) {
die('Error: ' . mysqli_error($conexion));
}
/* Asignamos a cada ? un valor de tipo string */
mysqli_stmt_bind_param($consulta, 'ss',
$_POST['cad'],
$_POST['text']
);
if (mysqli_stmt_execute($consulta) === false) {
die('Error: ' . mysqli_error($conexion));
}
}
?><!DOCTYPE html>
<html lang="es">
<head>
<meta charset="iso-8859-2">
<title>Página de prueba</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
</head>
<body>
<form action="<?= $_SERVER['PHP_SELF'] ?>" method="post" name="Entrada" enctype="multipart/form-data">
<input name="cad" maxlength="5" size="3" />
<textarea name="text"></textarea>
<input id="enviar" type="submit" value="Publicar" />
</form>
</body>
</html>
I have added the correct form to avoid an SQL failure when characters that can close the query (such as '
) are received using prepared queries. With this code you will also avoid problems of SQL injection .
I have also reinforced the code to show the error that a query might cause (in your case I was giving you a SQL syntax error that you were not showing at any time).
Summary and proposed solution
The main problem that you suffer is to inject strings directly into the SQL query, which causes that if there are SQL characters (such as the string closure '
) the SQL query has syntax error and it does not run.
To fix it use queries prepared with mysqli_prepare()
. If you insist on adding strings directly to SQL, at least use mysqli_real_escape_string()
.
The second one is related to the chains you have to test. For example, there is no way to code ¡Caña! to'
(in ISO 8859-15
) in the character set ISO 8859-2
, appearing instead ĄCańa! to'
.
In the string '´ñ
of your question there is no character ´
or% ISO-8859-2
or ISO-8859-15
, so it will be impossible to store it with this collation or character set.
To solve this I recommend that you change everything to utf-8
(collation utf8_general_ci
) and that both your pages and databases, tables, etc. share the same character set. You will support many more languages, including emoticons and symbols (such as ☀, ☎, ☘, ☺, etc.), and you will not be limited to just 256 characters (of which only a small portion are actually useful).
Here is a link to the character table of ISO-8859-2
, and here a href="https://en.wikipedia.org/wiki/ISO/IEC_8859-15"> ISO-8859-15
. You can check the limitations of using either of them.
Conversion of the database
You must execute the following SQL queries to change the default collation of the database and the table:
ALTER DATABASE nombre_de_tu_base_de_datos
CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE datos
CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Note that moving from virtually any character set to utf-8
is possible, but the opposite conversion (to iso-8859-2
of return, for example) could fail and there is loss of data by using characters that could not be code to that game.
Modifications in HTML / PHP
After correcting the default collation (or character set) of the database and the table, you can change the character set of the PHP files (not all editors support the latter, I recommend Atom
, Notepad++
, etc) and make the following changes:
<?php
/* Ahora avisamos que el contenido está en UTF-8 */
header('Content-Type: text/html; charset=utf-8');
/* Si estamos recibiendo el formulario insertamos el registro */
if (isset($_POST['cad'])) {
/* Establecemos la conexión */
$conexion = mysqli_connect($servidor, $usuario, $pass, $bbdd) or die("Error 505 NOT FOUND");
/* Ahora debemos informar que todo irá en UTF-8 */
mysqli_set_charset($conexion, 'utf8');
/* Preparamos la consulta, todo esto no cambia */
$consulta = mysqli_prepare($conexion, '
INSERT into datos (texto, cadenas )
VALUES (?, ?)
');
if ($consulta === false) {
die('Error: ' . mysqli_error($conexion));
}
/* Asignamos a cada ? un valor de tipo string, tampoco cambia */
mysqli_stmt_bind_param($consulta, 'ss',
$_POST['cad'],
$_POST['text']
);
/* Ejecutamos la consulta igual que antes, sin cambios */
if (mysqli_stmt_execute($consulta) === false) {
die('Error: ' . mysqli_error($conexion));
}
}
?><!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8"><!-- Ahora debemos cambiar aquí el juego de caracteres -->
<title>Página de prueba</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><!-- Y también aquí -->
</head>
<body>
<form action="<?= $_SERVER['PHP_SELF'] ?>" method="post" name="Entrada" enctype="multipart/form-data">
<input name="cad" maxlength="5" size="3" />
<textarea name="text"></textarea>
<input id="enviar" type="submit" value="Publicar" />
</form>
</body>
</html>
With these changes you will have your entire application converted to utf-8
and, therefore, you will support practically any character of any language or special symbol.