Проблема с кодировкой при выполнении фунции insert

OrlandO

Любитель
Регистрация
17.05.2007
Сообщения
752
Реакции
0
Поинты
0.000
Как я успел убедить - это длвольно распространенная проблема, но решения так и не нашел! Суть в том, что на определенной странице вызывается файл comment.php cо следующим кодом:
PHP:
<? require_once 'blocks/commetsbd.php';

$sql = "
        SELECT id, parent_id, name, comment, website, avatar,
        DATE_FORMAT(date_add, '%d %M %Y %H:%i') as date_add
        FROM commets";

$query = mysql_query($sql);

while($row = mysql_fetch_assoc($query))
{
    $data[$row[id]] = $row; 
}

function mapTree($dataset) {
	$tree = array(); 
    
    
	foreach ($dataset as $id=>&$node) {    
		if (!$node['parent_id']) {
			$tree[$id] = &$node;
		} else { 
		
            $dataset[$node['parent_id']]['childs'][$id] = &$node; //
             
		}
	}

	return $tree;
}  


 
function commentsToTemplate($comment)
{
 
    ob_start();  
      

        include 'comment_template.php';                     
    
    $comments_string =  ob_get_contents();
    ob_end_clean(); 
    
    return $comments_string;
   
} 
   
function commentsString($data)
     {
        foreach($data as $w) 
		{
         $string .= commentsToTemplate($w);
		 }
         
        return $string; 
     } 
	       
$data = mapTree($data);
$comments = commentsString($data);
$data = null;
 


?>

И вызываемый из ява скрипта файл, который вставляет введенную информацию в БД с таким кодом:
PHP:
<?php

      
      sleep(1); // Установим задержку выполнения в 3с, только для того, чтобы увидеть в браузере картинку лоадера при отправке данных))   
      
      
      if($_POST[parent_id])  $parent_id = preg_replace('/\D+/i','', $_POST[parent_id]);
      else $parent_id = 0;        
           
      $author = trim($_POST[author]);
      $comment = trim($_POST[comment]);
	  $ava = trim($_POST[ava]);
	  $web = trim($_POST[web]);
      
      /* Если имя или комментарий не заполнены, прервем выполнение скрипта и вернем массив 
      с ошибками преобразованный в строку формата JSON c сообщением об ошибке
      Мы не просто укажем js-скрипту, что у нас возникла ошибка, но также передадим сообщение и имя поля,
      которое не заполнено (или заполнено неверно, если вы решите реализовать доп. проверку)
      Конечно, можно реализовать проверку на строне клиента и не позволять человеку вообще отправлять 
      незаполненную форму, но проверка на стороне сервера обязательна */
      
      if(!$author)   $error[author] = Please type your name!';
      if(!$comment)  $error[comment] = 'Please type your comment!';
      
  
      
      // Сохраняем данные в БД
      
      require_once 'blocks/commetsbd.php';  
            $sql = "INSERT INTO commets (parent_id, name, comment,  website, avatar, date_add) VALUES ($parent_id, '$author', '$comment', '$web', '$ava', NOW())";
	  
      $result = mysql_query($sql);
      if(!$result) 
      {
        $error[] = 'Error';
        exit(json_encode($error));
      }
      exit();

 

?>

Но при вставке в БД все передается в иероглифах, хотя везде кодировка стоит cp1251, когда на странице, которая делает вывод из базы ставишь utf8 - текст выводится нормально, а вот все остальное иероглифами!

Помогите исправить проблему так, чтоб не менять всю кодировку на utf8/
 

Heromant

Любитель
Регистрация
05.07.2011
Сообщения
159
Реакции
2
Поинты
0.000
Может не прав (не кодер не капли), но ... мускуль то у вас в какой кодировке? Обычно же UTF идет... тоесть скрипты у вас кидают в базу в кодировке вин, а сама база ютф.... не?
 

soft

Интересующийся
Регистрация
24.07.2011
Сообщения
17
Реакции
0
Поинты
0.000
Перед сохранением данных в БД можно конвертировать входящий UTF8 на windows-1251 так:
$author = mb_convert_encoding($author, 'windows-1251', 'utf-8');
так для всех полей.
 

OrlandO

Любитель
Регистрация
17.05.2007
Сообщения
752
Реакции
0
Поинты
0.000
Чтоб не создавать новую тему, напишу здесь! При написании кода для защиты от взлома и проверки наличия пользователя в базе возникли проблемы! На основе найденого в интернете был сделан следующий код:
PHP:
<?php
session_start();// вся процедура работает на сессиях. Именно в ней хранятся данные пользователя, пока он находится на сайте. Очень важно запустить их в самом начале странички!!!
if (isset($_POST['login'])) { $login = $_POST['login'];
 if ($login == '') { unset($login);} } //заносим введенный пользователем логин в переменную $login, если он пустой, то уничтожаем переменную
 if (isset($_POST['password'])) { $password=$_POST['password']; 
 if ($password =='') { unset($password);} }//заносим введенный пользователем пароль в переменную $password, если он пустой, то уничтожаем переменную
 if (empty($login) or empty($password)) //если пользователь не ввел логин или пароль, то выдаем ошибку и останавливаем скрипт
 {
 exit ("Вы ввели не всю информацию, вернитесь назад и заполните все поля!");
 }//если логин и пароль введены,то обрабатываем их, чтобы теги и скрипты не работали, мало ли что люди могут ввести
 $login = stripslashes($login);
 $login = htmlspecialchars($login);
 $password = stripslashes($password);
 $password = htmlspecialchars($password);//удаляем лишние пробелы
 $login = trim($login);
 $password = trim($password);// подключаемся к базе 

 include ("../blocks/bd.php");// файл bd.php должен быть в той же папке, что и все остальные, если это не так, то просто измените путь
 // минипроверка на подбор паролей
$ip=getenv("HTTP_X_FORWARDED_FOR");
if (empty($ip) || $ip=='unknown') { $ip=getenv("REMOTE_ADDR"); }

mysql_query("DELETE FROM oshibka WHERE UNIX_TIMESTAMP() - UNIX_TIMESTAMP(date) > 900");//удаляем ip-адреса ошибавшихся при входе пользователей через 15 минут. 
$result = mysql_query("SELECT col FROM oshibka WHERE ip='$ip'",$db);
 // извлекаем из базы количество неудачных попыток входа за последние 15 у пользователя с данным ip 
$myrow = mysql_fetch_array($result);
 if ($myrow['col'] > 2) {//если ошибок больше двух, т.е три, то выдаем сообщение.
 exit("Вы набрали логин или пароль неверно 3 раз. Подождите 15 минут до следующей попытки.");} 
 $password = md5($password);//шифруем пароль
 $password = strrev($password);// для надежности добавим реверс
 $password = $password."vvttv";//можно добавить несколько своих символов по вкусу, например, вписав "b3p6f". Если этот пароль будут взламывать методом подбора у себя на сервере этой же md5,то явно ничего хорошего не выйдет. Но советую ставить другие символы, можно в начале строки или в середине. //При этом необходимо увеличить длину поля password в базе. Зашифрованный пароль может получится гораздо большего размера.   
 $result = mysql_query("SELECT * FROM users WHERE login='$login' AND password='$password'",$db); //извлекаем из базы все данные о пользователе с введенным логином и паролем
 $myrow = mysql_fetch_array($result);
 if (empty($myrow['id'])){//если пользователя с введенным логином и паролем не существует//Делаем запись о том, что данный ip не смог войти. 
 $select = mysql_query ("SELECT ip FROM oshibka WHERE ip='$ip'");
 $tmp = mysql_fetch_row($select);
 if ($ip == $tmp[0]) {//проверяем, есть ли пользователь в таблице "oshibka" 
 $result52 = mysql_query("SELECT col FROM oshibka WHERE ip='$ip'",$db);
 $myrow52 = mysql_fetch_array($result52); $col = $myrow52[0] + 1;//прибавляем еще одну попытку неудачного входа 
 mysql_query ("UPDATE oshibka SET col=$col,date=NOW() WHERE ip='$ip'");} 
 else {mysql_query ("INSERT INTO oshibka (ip,date,col) VALUES ('$ip',NOW(),'1')");}//если за последние 15 минут ошибок не было, то вставляем новую запись в таблицу "oshibka"   
 exit ("Извините, введённый вами логин или пароль неверный.");}
 else { nbsp;         //если пароли совпадают, то запускаем пользователю сессию! Можете его поздравить, он вошел!          
 $_SESSION['password']=$myrow['password'];                      
 $_SESSION['login']=$myrow['login'];           
 $_SESSION['id']=$myrow['id'];//эти данные очень часто используются, вот их и будет "носить с собой" вошедший пользователь                     //Далее мы запоминаем данные в куки, для последующего входа.//ВНИМАНИЕ!!! ДЕЛАЙТЕ ЭТО НА ВАШЕ УСМОТРЕНИЕ, ТАК КАК ДАННЫЕ ХРАНЯТСЯ В КУКАХ БЕЗ ШИФРОВКИ
if ($_POST['save'] == 1) {//Если пользователь хочет, чтобы его данные сохранились для последующего входа, то сохраняем в куках его браузера
setcookie("login", $_POST["login"], time()+9999999);setcookie("password", $_POST["password"], time()+9999999);}}                  
echo "<html><head><meta http-equiv='Refresh' content='0; URL=index.php'></head></html>";//перенаправляем пользователя на главную страничку, там ему и сообщим об удачном входе ?>

Даже при правильно вводе выдает ошибку: "Извините, введённый вами логин или пароль неверный" и не выполняет функцию трех неправильных вводов, то есть сколько не вводи, все равно не помогает! Где ошибка, помогите найти!
С чем это может быть связано?
 
Последнее редактирование:

Senator2

ТОП-МАСТЕР
Регистрация
25.09.2007
Сообщения
7,027
Реакции
489
Поинты
0.000
OrlandO, а что происходит в базе oshibka при этом (при неправильных входах) ?
Значение переменной col изменяется ?
Это что касается 3-х неправильных вводов..

А по поводу того что пароль вводите правильный а оно все равно не находит его - так тут вариантов несколько...
- вы в функции сохранения пароля (после регистрации) делали то же самое что и в этом методе проверки пароля (т.е. md5, реверс, и добавление строки) ?
Если да - то добавьте на этой странице проверки пароля - отображение его перед тем как искать в базе - и посмотрите на него - сравните с тем что записан в базе..
- на поле password в базе пользователей сколько символов выделено ? Попробуйте увеличить его, например до 255 символов... Может пароль просто не помещается и обрезается..
 

dkameleon

МАСТЕР
Регистрация
14.12.2006
Сообщения
4,237
Реакции
3,167
Поинты
0.000
$login = stripslashes($login);
$login = htmlspecialchars($login);
$password = stripslashes($password);
$password = htmlspecialchars($password);
это издевательство над значениями переменных.

$password = md5($password);//шифруем пароль
$password = strrev($password);// для надежности добавим реверс
$password = $password."vvttv";
все напутано.
 

OrlandO

Любитель
Регистрация
17.05.2007
Сообщения
752
Реакции
0
Поинты
0.000
Senator2 спасибо, увеличение длинны значения пароля помогло!
dkameleon, а что не так?

Возник походу еще один вопрос:
При регистрации можно ввести аватар:

<input type="FILE" name="fupload">

В файле обработчике есть условие:
PHP:
if (!empty($_POST['fupload'])) //проверяем, отправил ли пользователь изображение
{$fupload=$_POST['fupload']; $fupload = trim($fupload); if ($fupload =='' or empty($fupload)) {unset($fupload);// если переменная $fupload пуста, то удаляем ее 
}}
if (!isset($fupload) or empty($fupload) or $fupload =='')
{
//если переменной не существует (пользователь не отправил изображение),то присваиваем ему заранее приготовленную картинку с надписью "нет аватара"
$avatar = "images/avatars/noavatar.png";//можете нарисовать noavatara.jpg или взять в исходниках
}

Но в любой ситуации когда я ввожу путь до аватара выполняется эта функция, то есть постоянно передается пустая переменная! В чем может быть проблема?
 

Senator2

ТОП-МАСТЕР
Регистрация
25.09.2007
Сообщения
7,027
Реакции
489
Поинты
0.000
OrlandO, как то мало информации Вы привели...
Сложно по этому кусочку сказать что-то определенное..

Но, что странно, в этом скрипте зачем-то проверяется переменная $_POST['fupload'] ?

После нажатия на кнопку загрузки файла (в форме отправки) - файл сразу загружается на сервер в Tmp, и доступен по переменной $_FILES["fupload"]... (это для Вашего примера)
Вот эту переменную и надо проверять, анализировать и если всё нормально - копировать в нужную Вам директорию..

P.S. Почитайте более подробно (с примером) вот здесь..
 
Последнее редактирование:

OrlandO

Любитель
Регистрация
17.05.2007
Сообщения
752
Реакции
0
Поинты
0.000
Это помогло тем не менее)) Спасибо Вам большое!
А вы не подскажите, почему функция
PHP:
	if(preg_match('/[.](GIF)|(gif)$/', $filename)) {
	$im = imagecreatefromgif($path_to_90_directory.$filename) ;
не хочет принимать гиф файлы и выдает ошибку: Warning: imagecreatefromgif() [function.imagecreatefromgif]: 'images/avatars/avatar1343_1.gif' is not a valid GIF file in /home/virtwww
 

Senator2

ТОП-МАСТЕР
Регистрация
25.09.2007
Сообщения
7,027
Реакции
489
Поинты
0.000
OrlandO, а остальные типы изображений работают нормально ?

Тут дело может быть вот в чем...
В версиях GD library меньше чем 1.6 поддержка GIF изображений была...
В старших версиях поддержку GIF отключили...
И только начиная с версии GD library 2.0.28 - вернули поддержку GIF...
Так что - посмотрите какая версия GD у Вас используется в PHP...

А что Вы дальше делаете с переменной $im ?
Может попробовать действовать как-то по другому ?
 
Последнее редактирование:

OrlandO

Любитель
Регистрация
17.05.2007
Сообщения
752
Реакции
0
Поинты
0.000
другие типы файлов png u jpeg нормально обрабатывает, без проблем!Дальнейший код, где используется эта переменная:
PHP:
$w = 90; 
$w_src = imagesx($im); 
$h_src = imagesy($im);
         $dest = imagecreatetruecolor($w,$w); 

         if ($w_src>$h_src) 
         imagecopyresampled($dest, $im, 0, 0,
                          round((max($w_src,$h_src)-min($w_src,$h_src))/2),
                          0, $w, $w, min($w_src,$h_src), min($w_src,$h_src)); 

         if ($w_src<$h_src) 
         imagecopyresampled($dest, $im, 0, 0, 0, 0, $w, $w,
                          min($w_src,$h_src), min($w_src,$h_src)); 

  
         if ($w_src==$h_src) 
         imagecopyresampled($dest, $im, 0, 0, 0, 0, $w, $w, $w_src, $w_src); 
		 

$date=time()

$avatar = $path_to_90_directory.$date.".jpg";
На счет версии, чесно говоря, никогда не сталкивался с этим, поэтому не знаю как это посмотреть!
 

Senator2

ТОП-МАСТЕР
Регистрация
25.09.2007
Сообщения
7,027
Реакции
489
Поинты
0.000
OrlandO, чтобы посмотреть версию GD, с которой собран PHP - нужно выполнить команду phpinfo() - и там найти строку о версии GD.
Можете создать простенький файлик (типа info.php) - в него пропишите эту команду, выложите его на хостинг, и вызовите из браузера - Вам будет показана информация о PHP, который используется на хостинге.

А так - по поводу картинок - так смотрю дальше просто ресемплинг делается (т.е. аватары приводятся к стандартному размеру)...
Может, как вариант, не делать вообще ресемплинг...
Проверять размер картинок при загрузке на хостинг, и если изображение больше 90 пикселей по горизонтали или вертикали - то не сохранять его - а пусть укажут другую картинку...
А при отображении - просто показывать сохраненную картинку (раз пропустили - значит размеры подходят).. Т.е. воспользоваться стандартным тегом IMG...
 

Senator2

ТОП-МАСТЕР
Регистрация
25.09.2007
Сообщения
7,027
Реакции
489
Поинты
0.000
Хотелось бы эту функцию сохранить, так вроде бы проще для пользователя)
На счет версии: GD Version bundled (2.0.34 compatible)

Странно тогда..
В этой версии должно было бы работать...
А чуть ниже (где Вы нашли номер версии) - там есть пару строчек о GIF...
Что у Вас там написано - enabled или нет ?
Вот так должно быть по идее :
GD Support enabled
GD Version bundled (2.0.34 compatible)
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.2.1
GIF Read Support enabled
GIF Create Support enabled

JPG Support enabled
PNG Support enabled
WBMP Support enabled
XPM Support enabled
XBM Support enabled

Если GIF включен - то тогда непонятно почему оно работать не хочет...
Файл то, к которому обращается, существует ? И не битый ли он ?
Пробовали какой-то другой gif подсунуть ?
 
Сверху Снизу