BG Development


  Reply to this topicStart new topicStart Poll

> Странен проблем с енкодинг на база данни на скрипт
seo
Публикувано на: 13-12-2023, 14:39
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 4
Регистриран на: 22.06.17



Здравейте,

преди 10 дни инсталирах 1 система за обяви.

Инсталацията премина успешно, като спазих напълно всички изисквания за инсталация и специфики при ползване на системата с кирилица на разработчика, но при тест на системата се получава много странен проблем с визуализиране на текста на описанието в обявата който е на кирилица.

Проблемния момент е, че отделни букви от кирилицата в текста се визуализират с този символ: � �

Проверих енкодингите зададени във файла config.php, там енкодинга е: UTF-8

В базата данни енкодинга е дефолт енкодинг cp1251_general_ci, но прави впечатление, че текста на кирилица в отделните таблици от базата при преглед с phpmyadmin а и след сваляне и преглед с текстов редактор notepad++ е енкоднат и нечетим пример: %D0%A5%D0%B5%D0%BB%D0%B5%D0%BD%D0%B0+%D0%9F%D0%B0%D1%80%D0%BA+-+%D0%A1%D0%BB%D1%8A%D0%BD%D1%87%D0%B5%D0%B2+%D0%B1%D1%80%D1%8F%D0%B3

Опитах да конвертирам базата през таб операции на phpmyadmin на utf-8 но положението е същото след успешено конвертиране.

Още по странното е, че при опит за редакция на обявата през потребителския акаунт през фронтенда на сайта текста на описанието директно изчезва поради тези проблемни символи в описанието и е празно поле, ако се вкара нормален текст на кирилица то той се запазва но с проблемните символи.

Моля за Вашата помощ за локализиране на този странен проблем с който се боря със стотици тестове вече 10 дни без никакъв успех, включая безброй съвети открити от гугъл, включая и тук: https://abeus.com/mysql-encoding/ и тук: https://mpetrov.net/chesto-sreschani-proble...ncoding-pri-php

За целта предоставям данни за достъп до потребителския акаунт в сайта за тест:

https://www.zastrahovki.net/index.php?a=10

потребител: webtest
парола: dbtest

Адрес на проблемната обява:
https://www.zastrahovki.net/index.php?a=2&b=195

След вход в сайта в ляво от менюто кликвате на my active listings и в списъка с обявата manage this listing и 3ти бутон отляво надясно Edit и накрая бутон edit details. Виждате, че текста на описанието е празен, но реално текст има и той се вижда от адреса на обявата https://www.zastrahovki.net/index.php?a=2&b=195

Ако се вкара текст на кирилица който се енкодне правилно всичко е ок и при последвала редакция се вижда текста без проблеми в символите, но не всеки текст се енкодва и разбира от системата, и ако има проблемни символи в текста, той се запазва с проблемите и при редакция полето за описание в обявата е празно.

НАПРАВИХ ЗАПИТВАНЕ ЗА ПРОБЛЕМА КЪМ ХОСТИНГ КОМПАНИЯТА, ЕТО И ТЕХНИЯ ОТГОВОР, ЩЕ БЪДЕ ОТ ПОЛЗА ЗА ОРИЕНТАЦИЯ В ПРОБЛЕМА:
---------------------------------------------------------------------------------
Здравейте,

Разгледах подробно случая. Глобалните настройки за колацията на сървъра, charset-a и за всяка нова зададена връзка към MySQL-a са следните:

collation-server=cp1251_general_ci
init-connect="SET NAMES cp1251"
character-set-server=cp1251
В случая всяка една новосъздадена база на сървъра ще използва cp1251_general_ci charset-a. Вашата 'zastrahovki_db', както споменахте, не е изключение. Възможно да ковнертирате енкодинга посредством PHP кода ви за което ще е необходимо да го промените всякакви настройки като

mysqli_set_charset($conn, "cp1251");
$encodedString = mb_convert_encoding($originalString, 'cp1251');
да използват стандартния за сървъра cp1251 charset и енкодинг.

Това обаче няма да промени в базата данни старите символи, защото те вече са били записани с конкретен енкодинг.
Алтернативно също така можете да пробвате да презапиште SET NAMES cp1251 настройката на сървъра на SET NAMES UTF8 през PHP кода на CMS-a ви и да видите дали това ще помогне.

Като финално решение можем да предложим миграция на друг сървър, където тези глобални настройки ще отговарят на изискванията на сайта.

Поздрави,
Калоян
Техническа поддръжка
---------------------------------------------------------------------------------


ПРЕДОСТАВЯМ ЧАСТ от конфиг файла config.php на скрипта (С ДЕФОЛТ НАСТРОЙКИ) за по лесно локализиране на проблема:

//Database Type. Most will never need to change this.
//defaults to "mysqli," but the older "mysql" should work fine if needed for compatibility on super-old servers
//"pdo_mysql" might work if needed, but is entirely untested/unsupported.
$db_type = 'mysqli';

//DB Connection Charset - This charset setting is used when connecting to the database,
//to force the connection charset to be different than the charset setting used at
//the server level. This is not often needed, so before enabling this setting see
//the documentation from: http://dev.mysql.com/doc/refman/4.1/en/cha...connection.html

// To use, un-comment the line below (remove the #) and change the 'charset_name' to the
// charset needed.
#$force_db_connection_charset = 'charset_name';

ДОБАВЕНИ ОТ МЕН ОЩЕ 4 ТЕСТОВИ НАСТРОЙКИ КОИТО НЕ РАБОТЯТ и са коментирани:
#$mysqli->set_charset('utf8mb3');
#mysqli_set_charset($link, 'cp1251');
#mysql_query("set names 'cp1251'");
#mysqli_set_charset( $con, 'latin1');

----CHARSET Settings----

The settings below are used for various operations that are charset sensitive,
for instance cleaning "user input". The settings with # in front will need
to be un-commented (remove the #) to use.

For "input cleaning", and anywhere else the PHP function htmlspecialchars()
would normally be used, there is a 3 step process (below) to ensure that the
data is not corrupted due to differences in charsets. Note that step
1 and 3 are skipped if the appropriate settings are not specified (Most sites
will only need to set CHARSET_CLEAN, step 2):

1. (Optional step, only run if CHARSET_FROM is set): The input's charset is
converted from the CHARSET_FROM setting to the CHARSET_CLEAN setting. It
is converted either using mb_convert_string() or iconv(), according
to CLEAN_METHOD setting.

See http://www.php.net/mb_convert_encoding for more information on setting
CLEAN_METHOD to mb_convert_encoding. CHARSET_FROM is used as the 3rd var passed
to that function. If CLEAN_METHOD is not set, and the function exists,
mb_convert_encoding is the default method used to convert the charset.

See http://www.php.net/iconv for more information on setting CLEAN_METHOD
to iconv. CHARSET_FROM is used as the 1st var passed to that function.

This step, and optionally step 3, are necessary in order to be able to
clean any charset that is not compatible with the function
htmlspecialchars() (see step 2)

2. (Always run): The input is "cleaned" using the PHP function htmlspecialchars()
This step will use the CHARSET_CLEAN setting for the charset, that charset must
be compatible with htmlspecialchars().

This step is always run for security reasons, to prevent a certain type of
hacking called "Cross Site Scripting" or XSS attack. If the charset is not
specified, or is not a compatible charset, the default of ISO-8859-1 is used.

See http://www.php.net/htmlspecialchars for a list of compatible charsets you can
use.

3. (Optional step, only run if CHARSET_TO is set): The cleaned input's charset
is converted from the CHARSET_CLEAN setting to the CHARSET_TO setting. It
is converted either using mb_convert_string() or iconv(), according
to CLEAN_METHOD setting.

See http://www.php.net/mb_convert_encoding for more information on setting
CLEAN_METHOD to mb_convert_encoding. CHARSET_TO is used as the 2nd var passed
to that function, at this step. If CLEAN_METHOD is not set, and the function exists,
mb_convert_encoding is the default method used to convert the charset.

See http://www.php.net/iconv for more information on setting CLEAN_METHOD
to iconv. CHARSET_TO is used as the 2nd var passed to that function during
this step.
*/

define('CHARSET_CLEAN', 'UTF-8'); //Required, see notes above (step 2)

#define('CHARSET_FROM', 'UTF-8'); //optional, un-comment and modify 'UTF-8' as needed
//to use. See notes above (step 1)

#define('CHARSET_TO','UTF-8'); //optional, un-comment and modify 'UTF-8' as needed
//to use. See notes above (step 3)

#define('CLEAN_METHOD', 'mb_convert_string'); //optional, un-comment to use mb_convert_string()
//in steps 1 and 3 above, or un-comment and change
//the 'mb_convert_string' to 'iconv' to use iconv()
//instead. Valid settings are 'mb_convert_string'
//and 'iconv'. See notes above (steps 1 and 3)


КРАЙ CONFIG.PHP ---------------------------------------------------------------------------------

ПРЕДОСТАВЯМ И ФРАГМЕНТ ОТ ДЪМП НА БАЗАТА:

-- phpMyAdmin SQL Dump
-- version 5.2.1
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3302
-- Generation Time: Dec 06, 2023 at 04:56 PM
-- Server version: 10.6.12-MariaDB
-- PHP Version: 8.1.16

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `zastrahovki_db`
--

-- --------------------------------------------------------

--
-- Table structure for table `ge_addons`
--

CREATE TABLE `ge_addons` (
`name` varchar(128) NOT NULL,
`version` varchar(64) NOT NULL,
`enabled` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_general_ci;


Благодаря много за съдействието,
С Уважение,
И. Пенева
PMEmail Poster
Top
thrawn
Публикувано на: 13-12-2023, 17:12
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3678
Регистриран на: 17.01.17



Каква е тая система, дето ползва cp1251? Единствената правилна кодова таблица, към днешна дата е utf8.
Ако системата не е много антична и писана от кликач, то създаване на базата данни с явно посочване на utf8 за кодова таблица ще реши проблемите (който най-вероятно се дължат на двойно кодиране с неправилно посочени таблици).

Прехвърлянето на вече въведените данни ще е по-голяма играчка, защото трябва да се използва обратната неправилна последователност на тази ползвана за кодирането, за да се получат коректно текстовете, които после да се импортират в чистата таблица.
PMEmail Poster
Top
relax4o
Публикувано на: 13-12-2023, 18:51
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



Доста мазало ми се струва. Настройките на сървъра са в cp1251, дъмпа се изпълнява в utf8 (дано няма insert-и в тоя дъмп), а таблиците са в cp1251 също.

Реално, ако системата използва utf8 (което трябва да е така), всичко останало също трябва да е utf8.

И за предпочитане използвай в базата данни utf8mb4 и utf8mb4_general_ci колация, за пълна поддръжка на utf8 (4 bytes). Има и по-пълни варианти, но според мен *_general_ci е достатъчно.

Ако преди 10 дни си я пуснал системата и все още няма истински данни, аз бих те посъветвал да преинсталираш като предварително оправиш всичко да е utf8.

Тези шльокавици (както ги наричаме) се получават поради разликите в байтовете. cp1251 е 1 байт, докато utf8 е между 1 и 3 или 4 (4 ако ползваш utf8mb4, иначе е до 3 байта). Извън mysql utf8 е винаги до 4 байта.

Когато системата ти изпраща данни в utf8, може да изпрати от 1 до 4 байта на символ (според символа). Ако получиш 2 байта за един символ за utf8, cp1251 ще ги възприеме като два отделни символа, ако въобще ги разбере.

Двойно кодиране можеш да получиш, ако колоната ти е в utf8, а вкарваш данни в cp1251, защото всеки байт ще бъде конвертиран в utf8.

Ето един подробен линк относно колации и кодови таблици. Можеш да обърнеш внимание на Conversions and Common Errors секцията. За мен ти си случай 1 от там.
https://mysql.rjweb.org/doc.php/charcoll

Това мнение е било редактирано от relax4o на 13-12-2023, 18:53


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
seo
Публикувано на: 16-12-2023, 14:39
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 4
Регистриран на: 22.06.17



@thrawn

системата е писана в периода 2012-2016, и при уеб инсталацията й явно прихваща дефолт чарсет и колация на сървъра който е cp1251

@relax4o

пробвах със следното в config.php файла:

$dbhost = "localhost";
$dbuser = "root";
$dbpass = "dbpass";
$dbname = "dbname";

$conn = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);

mysqli_query($conn,"SET CHARACTER SET 'utf8'");
mysqli_set_charset($conn,"utf8");
mysqli_query($conn,"SET NAMES 'utf8'");


и базата я конвертирах през phpmyadmin / operations /collation -

Change all tables collations : utf8mb4_general_ci
Change all tables columns : collations utf8mb4_general_ci

и сега базата е: ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

и когато опитах да вкарам текст на кирилица в описание отново отделни символи се визуализират през сайта с: � �

В базата текста е:

%D0%A5%D0%BE%D1%82%D0%B5%D0%BB+%D0%9F%D0%BB%D0%B0%D0%BD%D0%B5%D1%82%D0%B0+%D0%B5+%D0%BD%D0%B0%D0%B9-

Не знам какво друго ми убягва, ако имате идея, споделете я да тествам icon_smile.gif

Поздрави
PMEmail Poster
Top
relax4o
Публикувано на: 16-12-2023, 15:22
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



А сигурен ли си, че като запазваш в базата данни не създаваш нова връзка (сесия), която използва настройките по подразбиране на сървъра, които са все още зададени на cp1251?

Ако не използваш същата връзка, където задаваш чарсета да е utf8, то новата няма как да знае.

При възможност си промени настройките и на сървъра и премахни всякакви cp1251 глупости.

И използвай само mysqli_set_charset($conn,"utf8"); . Другите не ти трябват.
https://www.php.net/manual/en/mysqli.set-charset.php

QUOTE

Note:

This is the preferred way to change the charset. Using mysqli_query() to set it (such as SET NAMES utf8) is not recommended. See the MySQL character set concepts section for more information.


https://www.php.net/manual/en/mysqlinfo.concepts.charset.php

П.П. Входните данни от браузъра с каква кодировка постъпват? Там оправи ли да не е windows-1251?

Това мнение е било редактирано от relax4o на 16-12-2023, 15:24


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0