Проблема с utf8. В Mysql инфо на русском не заносится вообще.

Pusichka

Новичок
Всем доброго времени суток!
Отчаялся искать в интернете ответ, поэтому пишу здесь)
Итак,
Создана utf8 таблица в бд:
require_once $_SERVER['DOCUMENT_ROOT']."/php/mysql_connect_private.php";
@mysql_connect_private();

$string = "CREATE TABLE `users` (`user_id` int(9) unsigned not null auto_increment,
`email` VARCHAR(50),
`password` VARCHAR(40),
`name` VARCHAR(30),
`surname` VARCHAR(40),
`avatar` VARCHAR(50),
PRIMARY KEY (`user_id`)) ENGINE=MyISAM CHARACTER SET=utf8";
mysql_query($string) or die(mysql_error());
mysql_query("ALTER TABLE `users` ADD INDEX (`user_id`)") or die(mysql_error());
mysql_query("ALTER TABLE `users` ADD INDEX (`email`)") or die(mysql_error());

В таблицу делаем инъекцию при регистрации пользователя:
$string = "INSERT INTO `users` (`user_id`, `email`, `password`, `name`, `surname`) VALUES ('0', ";
$string .= "'".mysql_real_escape_string($_REQUEST['email'])."', ";
$string .= "'".mysql_real_escape_string(md5($_REQUEST['password']))."', ";
$string .= "'".mysql_real_escape_string($_REQUEST['name'])."', ";
$string .= "'".mysql_real_escape_string($_REQUEST['surname'])."')";
echo $string;
mysql_query($string) or die(mysql_error());

Выдает:
INSERT INTO `users` (`user_id`, `email`, `password`, `name`, `surname`) VALUES ('0', '[email protected]', '098f6bcd4621d373cade4e832627b4f6', 'Mihail', 'Баженов')

- Проверял и русский и английский языки.

В итоге в БД фамилия на русском языке не заносится - пусто.
Если вручную через phpmyadmin заношу фамилию, то все нормально.
В итоге, что делать?) Понимаю, что ответ, скорее всего, прост, но уже убил час на поиск решения и тщетно.
Кстати, комментарии по правильному оформлению тоже приветствуются) Может что не так написано с точки черния защиты/правильно оформления. Спасибо!

П.С. Подключение к базе:

function mysql_connect_private()
{
$addr = "localhost";
$user = "____";
$pass = "____";
$db = "____";
// MySQl
$abc = mysql_connect($addr, $user, $pass)
or die(" MySQL: ".mysql_error());
//
@mysql_query('CREATE DATABASE $db');
//
mysql_select_db($db)
or die(" $db: ".mysql_error());
mysql_query("SET NAMES 'utf8'");
mysql_query ("set character_set_client='utf8'");
mysql_query ("set character_set_connection='utf8'");
mysql_query ("set character_set_results='utf8'");
mysql_query ("set character_set_database='utf8'");
mysql_query ("set collation_connection='utf8_bin'");
}

П.П.С.
Отображается при вытаскивании из базы вручную внесенная фамилия на русском тоже иероглифами...

Также, в процессе передачи данных к скриптам везде проверил работающую с mysql кодировку:
$z = mysql_fetch_array(mysql_query("SHOW VARIABLES LIKE 'character_set_database'"));
print_r($z);
Пишет везде, что utf8

Пробовал везде прописать
<meta http-equiv="Content-Type" content="text/html"; charset="utf8">

Тоже не помогает.
 

aaachilov

Новичок
У меня было так, только с кодировкой 1251
причём на денвере проблемы не было, потому что по умолчанию выставлено у меня 1251, а вот на хостинге появилась проблема, так как у них по умолчанию utf8.
Проблему решил добавлением одной строки в класс подключения к базе данных.
То есть указал кодировку подключения к бд
PHP:
mysql_set_charset("CP1251");
, но у тебя вроде кодировка указана

Была похожая ситауция при использовании ajax запросов, но для utf8 таких проблем не должно быть...
Выложи сам скрипт - попробую воспроизвести...
 

Pusichka

Новичок
index.php:

<?php
session_start();
require_once $_SERVER['DOCUMENT_ROOT']."/php/mysql_connect_private.php";
ini_set(’magic_quotes_runtime’, 0);
ini_set(’magic_quotes_sybase’, 0);
if (isset($_REQUEST['action']))
{
if ($_REQUEST['action']=='logout')
{
session_destroy();
session_start();
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html"; charset="utf8">
<meta http-equiv="Content-Language" content="ru">
<meta http-equiv="pragma" Content="no-cache">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="main.css" >

</head>
<body>
<?php
if (!isset($_REQUEST['email']))
{
echo "<form action = 'index.php?action=registration' method = 'post'>";
echo "<table>";
echo " <tr>";
echo " <td colspan = '2' align = 'center'><b>Registration</b></td>";
echo " </tr>";
echo " <tr>";
echo " <td>E-mail:</td><td><input type = 'text' name = 'email' class = 'text' size = '30' value = '".$_SESSION['registration']['email']."'></td>";
echo " </tr>";
echo " <tr>";
echo " <td>Password:</td><td><input type = 'password' name = 'password' class = 'text' value = '".$_SESSION['registration']['password']."'></td>";
echo " </tr>";
echo " <tr>";
echo " <td>Password again:</td><td><input type = 'password' name = 'password2' class = 'text' value = '".$_SESSION['registration']['password2']."'></td>";
echo " </tr>";
echo " <tr>";
echo " <td>Name:</td><td><input type = 'text' name = 'name' class = 'text' value = '".$_SESSION['registration']['name']."'></td>";
echo " </tr>";
echo " <tr>";
echo " <td>Surname:</td><td><input type = 'text' name = 'surname' class = 'text' value = '".$_SESSION['registration']['surname']."'></td>";
echo " </tr>";
echo " <tr>";
echo " <td colspan = '2' align = 'center'><input type = 'submit' value = 'Register'></td>";
echo " </tr>";
echo "</table>";
echo "</form>";
}
else
{
@mysql_connect_private();
$string = "SELECT * FROM `users` WHERE `email`='".mysql_real_escape_string($_REQUEST['email'])."'";
$r = mysql_query($string);
$result = mysql_fetch_array($r);
if ($result > 0)
{
echo "User with such an e-mail is already registered... <a href='index.php?action=registration'>Try again</a>";
$_SESSION['registration']['email'] = "";
$_SESSION['registration']['password'] = $_REQUEST['password'];
$_SESSION['registration']['password2'] = $_REQUEST['password2'];
$_SESSION['registration']['name'] = $_REQUEST['name'];
$_SESSION['registration']['surname'] = $_REQUEST['surname'];
}
else if ($_REQUEST['password']!=$_REQUEST['password2'])
{
echo "Sorry, but the passwords you've entered are not equal... <a href='index.php?action=registration'>Try again</a>";
$_SESSION['registration']['email'] = $_REQUEST['email'];
$_SESSION['registration']['name'] = $_REQUEST['name'];
$_SESSION['registration']['surname'] = $_REQUEST['surname'];
$_SESSION['registration']['password'] = "";
$_SESSION['registration']['password2'] = "";
}
else
{
$string = "INSERT INTO `users` (`user_id`, `email`, `password`, `name`, `surname`) VALUES ('0', ";
$string .= "'".mysql_real_escape_string($_REQUEST['email'])."', ";
$string .= "'".mysql_real_escape_string(md5($_REQUEST['password']))."', ";
$string .= "'".mysql_real_escape_string($_REQUEST['name'])."', ";
$string .= "'".mysql_real_escape_string($_REQUEST['surname'])."')";
echo $string;
mysql_query($string) or die(mysql_error());
echo "Registration is finished. Now you can log in!";
}
}
?>
</body>
</html>


mysql_connect_private.php:
<?php
// MySQL
$abc = "";

function mysql_close_private()
{
mysql_close($abc);
}

function mysql_connect_private()
{
$addr = "localhost";
$user = "root";
$pass = "";
$db = "stas";
// MySQl
$abc = mysql_connect($addr, $user, $pass)
or die(" MySQL: ".mysql_error());
//
@mysql_query('CREATE DATABASE $db');
//
mysql_select_db($db, $abc)
or die(" $db: ".mysql_error());

@mysql_query ('SET character_set_client="utf8"');
@mysql_query ('SET character_set_connection="utf8"');
@mysql_query ('SET character_set_results="utf8"');
@mysql_query ('SET character_set_database="utf8"');
@mysql_query ('SET collation_connection="utf8_general_ci"');
}
?>
 

aaachilov

Новичок
держи - замени

mysql_connect_private.php:
PHP:
<?php
 // MySQL
 $abc = "";

 function mysql_close_private()
 {
 mysql_close($abc);
 }

 function mysql_connect_private()
 {
 $addr = "localhost";
 $user = "root";
 $pass = "";
 $db = "stas";
 // MySQl
  mysql_set_charset("utf8");
 $abc = mysql_connect($addr, $user, $pass)
 or die(" MySQL: ".mysql_error());
 //
 @mysql_query('CREATE DATABASE $db');
 //
 mysql_select_db($db, $abc)
 or die(" $db: ".mysql_error());


 }
 ?>
Сам код конечно тоже у тебя страшный - но со временем оптимизируешь.
Ошибка была именно в кодировке сединения
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Автор, тебе дико повезло, что попался такой добряк как aaachilov, твою простыню в 100500 строк кода, тут никто другой читать не стал бы. В другой раз - если хочешь вывалить это на публику, пользуйся, пожалуйста. pastebin и другими сервисами, специально для этого созданными. На форум постится обычно 10-20 строк кода, где у тебя затык.
 

Pusichka

Новичок
держи - замени

mysql_connect_private.php:
PHP:
<?php
 // MySQL
 $abc = "";

 function mysql_close_private()
 {
 mysql_close($abc);
 }

 function mysql_connect_private()
 {
 $addr = "localhost";
 $user = "root";
 $pass = "";
 $db = "stas";
 // MySQl
  mysql_set_charset("utf8");
 $abc = mysql_connect($addr, $user, $pass)
 or die(" MySQL: ".mysql_error());
 //
 @mysql_query('CREATE DATABASE $db');
 //
 mysql_select_db($db, $abc)
 or die(" $db: ".mysql_error());


 }
 ?>
Сам код конечно тоже у тебя страшный - но со временем оптимизируешь.
Ошибка была именно в кодировке сединения
Aaachilov, спасибо огромное! Но, к сожалению, не помогло. К тому же, "SET NAMES" разве не тоже самое?
c0dex, понял, спасибо. В следующий раз обязательно так и сделаю.
 

aaachilov

Новичок
Это не могло не помочь, так как я этот код по чесноку не поленился к себе на денвер залить, а потом на хост. Значит смотри настройки своего сервера. Причём на одном по умолчанию 1251 стоит на другом utf8.
 

Вложения

sobachnik

Новичок
Бывают такие весёлые б.д. (я видал такие не раз), когда текстовые поля таблицы в одной кодировке, а данные, которые там находятся - в другой. Т.е., например, таблица:
PHP:
CREATE TABLE `some_table` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `some_text` TEXT,
    PRIMARY KEY(`id`)
) DEFAULT CHARSET = utf8 COLLATE = utf8_general_ci;
Но при этом всё что в ней есть - в кодировке cp1251.
И при этом получается такое веселье, что всякие программы типа phpMyAdmin или Navicat - выводят данные в виде вопросиков или иероглифов, а PHP (без запроса SET NAMES) выводит читабельные данные. Более того, я как-то по работе встретился с таблицей, в которой часть данных была в одной кодировке, а часть - в другой :)

В такой ситуации я могу посоветовать для начала вообще убрать запрос SET NAMES и посмотреть, что придёт. Потому, что иначе получается, что б.д. начинает преобразовывать из кодировки А в кодировку Б данные, которые реально находятся в кодировке В...
Попробуй просто получать данные без указания кодировки вообще, выводить их в браузер. А там дальше - в браузерах есть такая штука, как кодировка страницы - побалуйся этой штукой, посмотри страницу в разных кодировках, которые знает браузер и найди ту, при которой данные будут правильно отображаться.
 

aaachilov

Новичок
sobachnik
Его скрипт рабтает без указания SET NAMES на сервере, кодировка по умолчанию у которого стоит utf8, но не работает например у меня на денвере, где кодировка по умолчанию стоит 1251. Если принудительно указать кодировку сединения то данные в обоих вариантах передаваться будут в utf8.
Скрипт должен быть независим от настроек сервера.
А изменив кодировку в браузере Вы только укажете браузеру в какой кодировке отображать данные и это не каким местом не повлияет на получаемые данные и тем более он знает уже в какой кодировке он их хочет.
Даже если явно указать кодировку базы данных и таблиц в 1251 в его случае при указании кодировки соединения мы будем писать и получать данные в utf8.
Вот пример с его же скриптом при кодировке соединния utf8 и базой в win1251 - все отлично пишется и выводится в utf8.





 

sobachnik

Новичок
aaachilov
Извини, не знаю, как зовут, по этому... вроде как по фамилии получается.
В общем о чём я писал - попробую ещё раз, может понятней будет.
Я не знаю, такая ситуация у топикстартера или нет, я просто решил поделиться неким опытом, возможно поможет.
Допустим есть таблица в б.д., кодировка которой - latin1 (стандартная кодировка MySQL, которая по-умолчанию при установке, то бишь Windows-1250). Но при записи данных в эту таблицу - PHP отправлял данные в кодировке cp1251. При этом MySQL не знал, что эти данные в cp1251. Он думал, что там cp1250, потому что явного указания, в какой именно кодировке приходят данные - не было. MySQL, по сути, просто пихал поток байт "как есть" в таблицу - и всё. Получилась такая хрень, что MySQL уверен, что данные, которые записаны в таблицу, в кодировке latin1, однако на самом деле - там cp1251. А теперь мы ставим запрос SET NAMES utf8 и пробуем эти данные получить. MySQL получил команду отдавать данные в кодировке utf8 и он уверен, что данные в кодировке latin1. При выдаче данных он будет перекодировать из кодировки latin1 в кодировку utf8 данные, которые реально в кодировке cp1251. Естественно, ничего путного из этого не выйдет.
Если не указать SET NAMES - MySQL ничего и никак перекодировать не будет, он по сути просто отдаст тот же поток байт, который когда-то получил. А PHP, в свою очередь, сделает просто echo этому потоку байт, в какой бы кодировки они не были. Браузер - получит этот поток байт "как есть". Теперь мы можем указывать браузеру, в какой кодировке нам хотелось бы видеть все эти байты, чтобы хотя бы понять, в какой кодировке данные лежат в таблице и, соответственно, что нужно делать дальше. Вот как-то так.

П.С. Я может быть не всегда очень понятно выражаюсь - не знаю, хотя пытаюсь написать наиболее понятно. Я просто сталкивался в реальной практике не раз с таким явлением, когда какой SET NAMES не укажи - будешь всегда на выходе получать иероглифы. Не потому, что данные реально в какой-то очень редкой кодировке, а потому, что любое преобразование кодировки данных будет приводить к ошибке - и просто из-за того, что MySQL считает, что исходная кодировка данных одна, а на самом деле она другая.
 

Pusichka

Новичок
aaachilov,
Проблема в том, что изначально представленный тобой вариант сработал. И данные в базу стали отправляться правильно, за что огромное спасибо. И, кстати, спасибо, что не поленился весь код прочитать мною выложенные. Но дальше, когда я стал опять наращивать код - проблема возобновилась. Не знаю, только с чем это было связано. Сейчас заново все перепишу и проверю!
 

aaachilov

Новичок
Тут конкретный случай и был конкретнрый вопрос.
База в utf8 страницы в utf8 почему что не так - значит данные перекодировались по пути от клиента на сервер.
Здесь все до нельзя просто - а мы его только загрузим сейчас своими историями про то как бывает.
Вот если не указать кодировку происходит то что Вы выше описали.
Но у него проблема вероятно не в кодировке, а в чем то другом..............., потому что у меня его код работает при любой кодировке сервера и базы данных
 

aaachilov

Новичок
Проблема в том, что изначально представленный тобой вариант сработал. И данные в базу стали отправляться правильно, за что огромное спасибо. И, кстати, спасибо, что не поленился весь код прочитать мною выложенные. Но дальше, когда я стал опять наращивать код - проблема возобновилась. Не знаю, только с чем это было связано. Сейчас заново все перепишу и проверю!
А у тебя единый класс отвечает за поключение к базе данных?, вернее даже не класс в твоём случае, а файл?
 

Pusichka

Новичок
Так, пришли к следующему!)))
Я сверил Ваш и мой index.php и мне не верится, но у меня не работал скрипт из-за того, что у в начале вызывается функция @mysql_connect_private(); . Я, если честно, не понимаю, какое отношение это имеет к проблемам в кодировке, но проверил несколько раз - загвоздка реально в этом! МОжет кто объяснить почему?!?!?!?

П.С. Оставив подключение к базе только в index.php проблемы с кодтровкой вообще ушли, но это для ооооочень большая загадка....
 

dimitrius

Новичок
В php.ini какая кодировка по умолчанию? если не совпадает с базой тоже может "глючить".
Попробуй заменть.
 
Сверху