PDA

Просмотр полной версии : К вопросу о кодировке базы


serg-php
09.11.2008, 02:50
Был скриптец буржуйский. Решил его использовать для работы с русским языком.

Раньше был хостинг с кодировкой ср1251.

Все работало.

По определенным причинам пришлось поменять хостера, а там кодировка утф-8

Начались проблемы с кодировкой. Скриптом дампером
перенес базу с кодировкой ср1251 и принудительным ее воостановлением в кодировке утф

Но проблема не решилась!


Советуют сделать mysql_query("set CHARACTER SET cp1251");

Но я не знаю точно, куда его вставить?

Есть файл коннекта







<?php


define('DB_SERVER','localhost');
define('DB_NAME','');
define('DB_USER','');
define('DB_PW','');


define('SITE_PATH',str_replace('\\','/',substr(dirname(__FILE__),0,-3)));
define('TPL_PATH', SITE_PATH.'tpl/');

error_reporting(E_ALL ^ E_NOTICE); // | E_STRICT (php5)
// ini_set('log_errors', 'On');
// ini_set('error_log', '/usr/local/apache/logs/error_log');
ini_set('display_errors', 'On');
//ini_set('memory_limit','30M');

// Prefix that all database tables have
define('TBL_PREFIX','eu_');

// Thumbnails background color
define('THUMB_BG', 'FFFFFF');
define('THUMB_FILL', true);

// Browsing thumbnail width, set this to 0 to display photo icon instead of the thumbnail photo
define('THUMB_WIDTH', 50);

/*
Possible debug levels:
0: None - Don't show any debug information
1: Show server load, page generation time, gzip compression stats and query count
2: Show level 1 (above) and GET and POST information
3: Show level 1 + 2 and database queries
*/
define('DEBUG_LEVEL', 0);

/*
ENABLE SQL Debug Mode? (0/1)
(If yes, add '&debug=1' to any page to view SQL debug info)
*/
define('EN_DEBUG_SQL', 0);

/*
Default index page - which file from /inc/pages/ should be loaded by default,
w/o extension, e.g. browse = browse.php
*/
define('IDX_PAGE', 'browse');

/*
Listing Title DB field name (shared across all fieldsets).
It must be present in each fieldset as Ad Title
*/
$TITLE_FIELD = 'v_title';

require SITE_PATH.'inc/app_init.php';











Куда вставить данную строку

mysql_query("set CHARACTER SET cp1251");


Какие другие способы решения данной проблемы?

Pashkela
09.11.2008, 03:11
http://www.denwer.ru/faq/other.html


4. Совместимость
4.1. Проблема с кодировкой MySQL 4.1: из БД извлекаются «вопросики» вместо русских букв

MySQL 4.1 на внутреннем уровне работает с кодировкой UTF8 и перекодирует результат в требуемую форму (в нашем случае windows-1251) непосредственно перед передачей его клиенту (т.е. скрипту). В некоторых случаях оказывается, что кодировка клиента (скрипта) «не доходит» до MySQL (ссылка на обсуждение в форуме). Соответственно, сервер передает «вопросики». Можно применить одно из следующих решений.
Вписать в скрипт что-то вроде: mysql_query(«SET NAMES cp1251»). Это надо делать сразу же после подключения к MySQL. Проблема исчезнет.

Вписать init-connect="SET NAMES cp1251" в /usr/local/mysql4/my.cnf (кто не видит этого файла, пусть изучает Windows, читает FAQ и думает головой) и перезапустить MySQL. Однако это сработает только для соединений, которые проходят НЕ под root-пользователем. Скрипты, коннектящиеся к базе под root, по-прежнему будут получать неверную кодировку. Лучше всего будет все-таки завести новую базу и пользователя через http://localhost/denwer/Tools/addmuser/ и забыть о проблеме.
Чтобы диагностировать проблему, выполните в скрипте запрос SHOW VARIABLES LIKE 'char%'. Пример:

mysql> show variables like 'char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | cp1251 |
| character_set_results | latin1 |
| character_set_server | cp1251 |
| character_set_system | utf8 |
| character_sets_dir | \usr\local\mysql4/share/charsets |
+--------------------------+----------------------------------+
7 rows in set (0.00 sec)

Как видите, кодировка неверная: character_set_client=latin1. Это из-за того, что я подключился к базе под root. Если теперь подключусь под не-root пользователем – все будет нормально.

.:EnoT:.
09.11.2008, 03:50
mysql_query('SET NAMES CP1251');
и это пишешь после функций подлючения к БД, mysql_connect() и mysql_select_db()

serg-php
09.11.2008, 11:54
.:EnoT:.,

я так понял у меня данные функции в файле соследующим содержанием:



<?php



define('DB_FETCH_ORDERED', 1);
define('DB_FETCH_ASSOC', 2);



if(!function_exists('mysql_connect')){



if(function_exists('mysqli_connect')) { // MySQLi workaround

function mysql_connect($server,$user,$pass){ return mysqli_connect($server,$user,$pass); }
function mysql_fetch_row($res) { return mysqli_fetch_row($res); }
function mysql_fetch_assoc($res) { return mysqli_fetch_assoc($res); }
function mysql_data_seek($res,$i) { return mysqli_data_seek($res,$i); }
function mysql_free_result($res) { return mysqli_free_result($res); }
function mysql_num_rows($res) { return mysqli_num_rows($res); }
function mysql_error($conn) { return mysqli_error($conn); }
function mysql_errno($conn) { return mysqli_errno($conn); }
function mysql_real_escape_string($s, $conn) { return mysqli_real_escape_string($conn, $s); }
function mysql_query($sql, $conn) { return mysqli_query($conn, $sql); }
function mysql_insert_id($conn) { return mysqli_insert_id($conn); }
function mysql_affected_rows($conn) { return mysqli_affected_rows($conn); }
function mysql_get_server_info($conn) { return mysqli_get_server_info($conn); }
function mysql_select_db($name,$conn) { return mysqli_select_db($conn, $name); }
function mysql_num_fields($res) { return mysqli_num_fields($res); }
function mysql_field_name($res, $i){
mysqli_field_seek($res,$i);



$finfo = mysqli_fetch_field($res);
return $finfo->name;
}
}
elseif(class_exists('PDO')){
include SITE_PATH.'inc/pdo.inc.php'; // experimental layer
}
}

// if PHP < 4.3.0
if(!function_exists('mysql_real_escape_string')){
function mysql_real_escape_string($s, $conn){ return mysql_escape_string($s); }
}

class Es_DB_Stats {

var $a_sql = array();
var $a_time = array();
var $a_mem = array();
var $o_tm;

function logSQL($sql){
//$sql.=' /* '.$this->_stack_trace().' */';
$this->a_sql[] = $sql;
}
function startQuery(){
$this->o_tm = &Factory::create('HwTimer');
$this->o_tm->startTimer();
}
function endQuery(){
$this->a_time[] = $this->o_tm->endTimer();
if(function_exists('memory_get_usage')) $this->a_mem[] = memory_get_usage();
}
function _stack_trace(){
$stack = array();
$trace = debug_backtrace();
array_splice($trace, 0, 3);
// push each function onto the stack
$len = strlen(SITE_PATH);
foreach($trace as $t) $stack[] = $t['function'].'() ['.substr($t['file'],$len).']';
$stack = array_reverse($stack);
return implode(' > ', $stack);
}
}

class Database {

var $CONN = '';
var $CURDB = '';
var $ERR_EXIT = TRUE;
var $ERR_MSG = '';

var $DEBUG = FALSE;

var $o_stats;
var $is_1st_obj = TRUE;

function Database(){
$this->DEBUG = (EN_DEBUG_SQL==1 && $_GET['debug']);
if($this->DEBUG || DEBUG_LEVEL>0){
$this->o_stats = &Factory::singleton('Es_DB_Stats');
}
if(!isset($GLOBALS['MYSQL_CONN'])) $GLOBALS['MYSQL_CONN'] = '';
else $this->is_1st_obj = false;
}

function __destruct(){
// for session_db.php
if($this->is_1st_obj && !is_resource($GLOBALS['MYSQL_CONN'])) $GLOBALS['MYSQL_CONN'] = $this->CONN;
}

function error($text = '') {

if($this->ERR_EXIT){

$v = array();
$v['mysql_error'] = mysql_error();
$v['mysql_errno'] = mysql_errno();
$v['date'] = date('l dS of F Y h:i:s A');
$v['ADMIN_EMAIL'] = ADMIN_EMAIL;
$v['EC_TITLE'] = EC_TITLE;
$v['REQUEST_URI'] = html_esc($_SERVER['REQUEST_URI']);
$v['HTTP_REFERER'] = html_esc($_SERVER['HTTP_REFERER']);
EvalAdvTpl(TPL_PATH.'error_db_query.htm',$v,1);

// FileWrite("/path/error_sql_log", $text."\n".$v['mysql_error']."\n".$v['REQUEST_URI']."\n\n", true);
// Display Error Details if debug option is enabled only
if(EN_DEBUG_SQL==1){
echo $text;
// print_r(debug_backtrace());
// debug_print_backtrace(); // php5
}
exit;
}
else $this->ERR_MSG = mysql_error();
}





function connect($server, $user = '', $pass = '', $dbase = '', $new_link = FALSE) {

if($user=='' && $pass==''){
$user = ini_get('mysql.default_user');
$pass = ini_get('mysql.default_password');
}

if(!function_exists('mysql_connect')) die('No MySQL extension found');
$this->CONN = @mysql_connect($server,$user,$pass,$new_link);
if(!$this->CONN) return false; // since 4.0.5
if($dbase) $this->set_db($dbase);
// possible mysql 5.x tweaks
// mysql_query('SET SQL_MODE="MYSQL40"', $this->CONN);
// mysql_query('SET SESSION storage_engine=MyISAM', $this->CONN);
return true;
}

/*
Valid SQL examples :
$db->query('SELECT * FROM TABLE WHERE COND="'.$db->quote($val).'"');
$db->query('SELECT * FROM TABLE WHERE COND='.$db->esc($val));
$db->query('SELECT * FROM TABLE WHERE COND=?', array($val));
$db->query('SELECT * FROM TABLE WHERE COND=:val', array(':val'=> $val));
*/

function query($sql, $a_in = NULL) {

if($this->DEBUG) $this->o_stats->startQuery();

$res = NULL;
if(!is_null($a_in)){
if(!is_array($a_in)) $a_in = array($a_in);

if(is_object($this->CONN)){ // PDO
$res = $this->CONN->prepare($sql);
$res->execute($a_in);
}
elseif(key($a_in)===0){
$a_sql = explode('?', $sql);
$sql = '';
$cnt = count($a_in);
for($k=0;$k<$cnt;$k++){
if($a_in[$k]!='') $a_in[$k] = mysql_real_escape_string($a_in[$k],$this->CONN);
$sql.=$a_sql[$k].'"'.$a_in[$k].'"';
}
$sql.=$a_sql[$k];
}
else{
foreach(array_keys($a_in) as $k){
if($a_in[$k]!='') $a_in[$k] = mysql_real_escape_string($a_in[$k],$this->CONN);
$sql = str_replace( ($k[0]!=':' ? ':' : '').$k , '"'.$a_in[$k].'"', $sql);
}
}
}

if(!$res) $res = mysql_query($sql, $this->CONN);

if(!$res) $this->error("QUERY failed : $sql");
if($this->DEBUG || DEBUG_LEVEL>0){
if($this->DEBUG) $this->o_stats->endQuery();
$this->o_stats->logSQL($sql);
}
return $res;
}

function insert_id() {
return (int)mysql_insert_id($this->CONN);
}

function affected_rows() {
return (int)mysql_affected_rows($this->CONN);
}

function set_db($name){
if(!$name || $this->CURDB==$name) return;
if(!@mysql_select_db($name,$this->CONN)) $this->error('DB select failed');
$this->CURDB = $name;
}

function esc($s) {
if($s=='') return '""';
return '"'.mysql_real_escape_string($s,$this->CONN).'"';
}

function quote($s) { // deprecated, use esc() instead ?
if($s=='') return '';
return mysql_real_escape_string($s,$this->CONN);
}

function one_data($sql, $a_in = NULL) {
$res = $this->query($sql, $a_in);
if(empty($res)) return;
$v = mysql_fetch_row($res);
return $v[0];
}

function one_assoc($sql, $a_in = NULL) {
$res = $this->query($sql, $a_in);
if(empty($res)) return array();
return mysql_fetch_assoc($res);
}

function one_row($sql, $a_in = NULL) {
$res = $this->query($sql, $a_in);
if(empty($res)) return array();
return mysql_fetch_row($res);
}

function one_col_array($sql, $a_in = NULL){
$res = $this->query($sql, $a_in);
if(empty($res)) return array();
$data = array();
while ($v = mysql_fetch_row($res)) $data[] = $v[0];
mysql_free_result($res);
return $data;
}

function two_col_assoc($sql, $a_in = NULL){
$res = $this->query($sql, $a_in);
if(empty($res)) return array();
$data = array();
while($v = mysql_fetch_row($res)) $data[$v[0]] = $v[1];
mysql_free_result($res);
return $data;
}

function select($sql, $a_in = NULL, $mode = DB_FETCH_ASSOC){

$res = $this->query($sql, $a_in);
if(empty($res)) return array();
$data = array();

if($mode == DB_FETCH_ORDERED){
while ($v = mysql_fetch_row($res)) $data[] = $v;
}
else{
while ($v = mysql_fetch_assoc($res)) $data[] = $v;
}
mysql_free_result($res);
return $data;
}

function version() {
if(defined('DB_VERSION')) return DB_VERSION;
$s = explode('.', mysql_get_server_info($this->CONN));
define('DB_VERSION', (int)sprintf('%d%02d%02d', $s[0], $s[1], intval($s[2])));
return DB_VERSION;
}

function get_server_info() { return mysql_get_server_info($this->CONN); }

// some extra functions

function getAll($sql, $params = NULL){ return $this->select($sql, $params); }

function getCol($sql, $col = 0, $a_in = NULL){
$res = $this->query($sql, $a_in);
if(empty($res)) return array();
$data = array();
if(is_int($col)){
while ($v = mysql_fetch_row($res)) $data[] = $v[$col];
}
else{
while ($v = mysql_fetch_assoc($res)) $data[] = $v[$col];
}
mysql_free_result($res);
return $data;
}

function getAssoc($sql, $force_array = false, $a_in = NULL, $mode = DB_FETCH_ORDERED){

$res = $this->query($sql, $a_in);
if(empty($res)) return array();

$data = array();

if(!$force_array && mysql_num_fields($res) == 2){
while($v = mysql_fetch_row($res)) $data[$v[0]] = $v[1];
}
else{
if($mode == DB_FETCH_ASSOC){
$fid = mysql_field_name($res, 0);
while($v = mysql_fetch_assoc($res)){
$k = $v[$fid];
unset($v[$fid]);
$data[$k] = $v;
}
}
else{
while($v = mysql_fetch_row($res)){
$k = $v[0];
unset($v[0]);
$data[$k] = $v; // array_values ??
}
}
}
mysql_free_result($res);
return $data;
}

}




А кудуда ставить именно здесь?

serg-php
09.11.2008, 12:18
Да, вот еще нашел еще один фалй:





<?php


if ( !function_exists( "mysql_connect" ) && class_exists( "PDO" ) )
{
class esPDO extends PDO
{

public $_aff_rows = 0;


public function exec( $sql )
{
return $this->_aff_rows = parent::exec( $sql );
}

public function affected_rows( )
{
return $this->_aff_rows;
}

}

function mysql_connect( $server, $user, $pass )
{
try
{
return new esPDO( "mysql:host=".$server, $user, $pass );
}
catch ( PDOException $e )
{
exit( $e->getMessage( ) );
}
}
function mysql_fetch_row( $st )
{
return $st->fetch( PDO::FETCH_NUM );
}
function mysql_fetch_assoc( $st )
{
return $st->fetch( PDO::FETCH_ASSOC );
}
function mysql_data_seek( $st, $i )
{
if ( $i == 0 )
{
$st->execute( );
}
else
{
trigger_error( "N/a in PDO mode", E_USER_ERROR );
}
}
function mysql_free_result( $st )
{
unset( $st );
}
function mysql_num_rows( $st )
{
return $st->rowCount( );
}
function mysql_error( $conn )
{
$v = $conn->errorInfo( );
return $v[2];
}
function mysql_errno( $conn )
{
return $conn->errorCode( );
}
function mysql_real_escape_string( $s, $conn )
{
return substr( $conn->quote( $s, PDO::PARAM_STR ), 1, -1 );
}
function mysql_query( $sql, $conn )
{
if ( preg_match( "/^(?:DELETE|UPDATE|INSERT)/i", $sql ) )
{
return $conn->exec( $sql );
}
return $conn->query( $sql );
}
function mysql_insert_id( $conn )
{
return $conn->lastInsertId( );
}
function mysql_affected_rows( $conn )
{
return $conn->affected_rows( );
}
function mysql_get_server_info( $conn )
{
return $conn->getAttribute( PDO::ATTR_SERVER_VERSION );
}
function mysql_select_db( $name, $conn )
{
$conn->query( "USE ".$name );
return true;

}


function mysql_num_fields( $st )
{
return $st->columnCount( );
}
function mysql_field_name( $st, $i )
{
$finfo = $st->getColumnMeta( $i );
return $finfo['name'];
}


}

?>

[x26]VOLAND
09.11.2008, 12:22
mysql_query('SET NAMES CP1251');
и это пишешь после функций подлючения к БД, mysql_connect() и mysql_select_db()
я например вот так делаю:
@mysql_query('SET NAMES ' . $this->encoding . ' COLLATE ' . $this->encoding);
@mysql_query('SET character_set_results=' . $this->encoding);
@mysql_query('SET character_set_client=' . $this->encoding);
@mysql_query('SET character_set_connection=' . $this->encoding);где $this->encoding - кодировка

serg-php
09.11.2008, 12:25
Мне необходимо найти функции подключения к базе в приведенных и точно определить место!

[x26]VOLAND
09.11.2008, 12:29
if(function_exists('mysqli_connect')) { // MySQLi workaround

function mysql_connect($server,$user,$pass){ return mysqli_connect($server,$user,$pass); }
function mysql_fetch_row($res) { return mysqli_fetch_row($res); }
function mysql_fetch_assoc($res) { return mysqli_fetch_assoc($res); }Зачем такие извращения? Напиши нормальные классы для mysql и mysql с отдельными полиморфными функциями для автоопределения.

serg-php
09.11.2008, 12:33
Сие извращение не я писал!

serg-php
09.11.2008, 12:35
Так правильно?



if(function_exists('mysqli_connect')) { // MySQLi workaround

function mysql_connect($server,$user,$pass){ return mysqli_connect($server,$user,$pass); }
function mysql_fetch_row($res) { return mysqli_fetch_row($res); }
function mysql_fetch_assoc($res) { return mysqli_fetch_assoc($res); }
function mysql_data_seek($res,$i) { return mysqli_data_seek($res,$i); }
function mysql_free_result($res) { return mysqli_free_result($res); }
function mysql_num_rows($res) { return mysqli_num_rows($res); }
function mysql_error($conn) { return mysqli_error($conn); }
function mysql_errno($conn) { return mysqli_errno($conn); }
function mysql_real_escape_string($s, $conn) { return mysqli_real_escape_string($conn, $s); }
function mysql_query($sql, $conn) { return mysqli_query($conn, $sql); }
function mysql_insert_id($conn) { return mysqli_insert_id($conn); }
function mysql_affected_rows($conn) { return mysqli_affected_rows($conn); }
function mysql_get_server_info($conn) { return mysqli_get_server_info($conn); }
function mysql_select_db($name,$conn) { return mysqli_select_db($conn, $name); }

########## Исправление кодировки

@mysql_query('SET NAMES ' . $this->encoding . ' COLLATE ' . $this->encoding);
@mysql_query('SET character_set_results=' . $this->encoding);
@mysql_query('SET character_set_client=' . $this->encoding);
@mysql_query('SET character_set_connection=' . $this->encoding);

###############################

function mysql_num_fields($res) { return mysqli_num_fields($res); }
function mysql_field_name($res, $i){
mysqli_field_seek($res,$i);

[x26]VOLAND
09.11.2008, 12:37
Нет. Объявление функции и её вызов - разные вещи. Определене кодировки должно идти после вызова mysql_connect и mysql_select_db

serg-php
09.11.2008, 13:25
Проблема решена! Благодарю всех!