Русский текст с "квадратиками"

scnipper

Новичок
Вобщем у меня такая проблема есть код который переводит имя из именительного падежа в родительный например Андрей -> Андрея

после того как я выполняю функцию вот так:
PHP:
$a = new RussianNameProcessor("Андрей");
$a = "".$a->fullName($a->gcaseRod);
echo $a;
Собственно мне должно вывести слово "Андрея", но выводит "Андре�я" то есть появляется какой то квадратик между Е и Я . На локальном серве все работает норм а на хосте не хочет.
 

Фанат

oncle terrible
Команда форума
Ну, "квадратик" означает неверную кодировку.
Где именно она неверная, остаётся только гадать - содержимое и условия работы RussianNameProcessor нам неизвестны.
Но в любом случае надо проверить и сравнить кодировки на разных серверах.
Небольшой чеклист находится здесь: http://www.phpfaq.ru/charset#encodings
 

scnipper

Новичок
Ну, "квадратик" означает неверную кодировку.
Где именно она неверная, остаётся только гадать - содержимое и условия работы RussianNameProcessor нам неизвестны.
Но в любом случае надо проверить и сравнить кодировки на разных серверах.
Небольшой чеклист находится здесь: http://www.phpfaq.ru/charset#encodings
вот содержимое этой функции :
PHP:
<?
class lastName {
    var $exceptions = array(
        "	дюма,тома,дега,люка,ферма,гамарра,петипа . . . . .",
        '	гусь,ремень,камень,онук,богода,нечипас,долгопалец,маненок,рева,кива . . . . .',
        '	вий,сой,цой,хой -я -ю -я -ем -е'
    );
    var $suffixes = array(
        'f	б,в,г,д,ж,з,й,к,л,м,н,п,р,с,т,ф,х,ц,ч,ш,щ,ъ,ь . . . . .',
        'f	ска,цка  -ой -ой -ую -ой -ой',
        'f	ая       --ой --ой --ую --ой --ой',
        '	ская     --ой --ой --ую --ой --ой',
        'f	на       -ой -ой -у -ой -ой',

        '	иной -я -ю -я -ем -е',
        '	уй   -я -ю -я -ем -е',
        '	ца   -ы -е -у -ей -е',

        '	рих  а у а ом е',

        '	ия                      . . . . .',
        '	иа,аа,оа,уа,ыа,еа,юа,эа . . . . .',
        '	их,ых                   . . . . .',
        '	о,е,э,и,ы,у,ю           . . . . .',

        '	ова,ева            -ой -ой -у -ой -ой',
        '	га,ка,ха,ча,ща,жа  -и -е -у -ой -е',
        '	ца  -и -е -у -ей -е',
        '	а   -ы -е -у -ой -е',

        '	ь   -я -ю -я -ем -е',

        '	ия  -и -и -ю -ей -и',
        '	я   -и -е -ю -ей -е',
        '	ей  -я -ю -я -ем -е',

        '	ян,ан,йн   а у а ом е',

        '	ынец,обец  --ца --цу --ца --цем --це',
        '	онец,овец  --ца --цу --ца --цом --це',

        '	ц,ч,ш,щ   а у а ем е',

        '	ай  -я -ю -я -ем -е',
        '	ой  -го -му -го --им -м',
        '	ах,ив   а у а ом е',

        '	ший,щий,жий,ний  --его --ему --его -м --ем',
        '	кий,ый   --ого --ому --ого -м --ом',
        '	ий       -я -ю -я -ем -и',

        '	ок  --ка --ку --ка --ком --ке',
        '	ец  --ца --цу --ца --цом --це',

        '	в,н   а у а ым е',
        '	б,г,д,ж,з,к,л,м,п,р,с,т,ф,х   а у а ом е'
    );
}

class firstName {
    var $exceptions = array (
        '	лев    --ьва --ьву --ьва --ьвом --ьве',
        '	павел  --ла  --лу  --ла  --лом  --ле',
        'm	шота   . . . . .',
        'f	рашель,нинель,николь,габриэль,даниэль   . . . . .'
    );
    var $suffixes = array(
        '	е,ё,и,о,у,ы,э,ю   . . . . .',
        'f	б,в,г,д,ж,з,й,к,л,м,н,п,р,с,т,ф,х,ц,ч,ш,щ,ъ   . . . . .',

        'f	ь   -и -и . ю -и',
        'm	ь   -я -ю -я -ем -е',

        '	га,ка,ха,ча,ща,жа  -и -е -у -ой -е',
        '	а   -ы -е -у -ой -е',
        '	ия  -и -и -ю -ей -и',
        '	я   -и -е -ю -ей -е',
        '	ей  -я -ю -я -ем -е',
        '	ий  -я -ю -я -ем -и',
        '	й   -я -ю -я -ем -е',
        '	б,в,г,д,ж,з,к,л,м,н,п,р,с,т,ф,х,ц,ч	 а у а ом е'
    );
}

class middleName {
	var $exceptions = array();
    var $suffixes = array (
        '	ич   а  у  а  ем  е',
        '	на  -ы -е -у -ой -е'
    );
}
        
class Rules {
    var $lastName, $firstName, $middleName;
    function Rules(){
        $this->lastName = new lastName();
        $this->firstName = new firstName();
        $this->middleName = new middleName();
    }
}

class RussianNameProcessor {
    var $sexM = 'm';
    var $sexF = 'f';
    var $gcaseIm =  'nominative';      var $gcaseNom = 'nominative';      // именительный
    var $gcaseRod = 'genitive';        var $gcaseGen = 'genitive';        // родительный
    var $gcaseDat = 'dative';                                       // дательный
    var $gcaseVin = 'accusative';      var $gcaseAcc = 'accusative';      // винительный
    var $gcaseTvor = 'instrumentative';var $gcaseIns = 'instrumentative'; // творительный
    var $gcasePred = 'prepositional';  var $gcasePos = 'prepositional';   // предложный
    
    var $fullNameSurnameLast = false;
    var $ln = '', $fn = '', $mn = '', $sex = '';

    var $rules;
    var $initialized = false;

    function init(){
        if ( $this -> initialized ) { 
            return;
        }
        $this->rules = new rules();
        $this->prepareRules();
        $this -> initialized = true;
    }
    
    function RussianNameProcessor ($lastName, $firstName = NULL, $middleName = NULL, $sex = NULL) {
        $this->init();
        if (!isset($firstName)) {
            preg_match("/^\s*(\S+)(\s+(\S+)(\s+(\S+))?)?\s*$/", $lastName, $m);
            if(!$m) exit("Cannot parse supplied name");
            if($m[5] && preg_match("/(ич|на)$/",$m[3]) && !preg_match("/(ич|на)$/",$m[5])) {
                // Иван Петрович Сидоров
                $lastName = $m[5];
                $firstName = $m[1];
                $middleName = $m[3];
                $this -> fullNameSurnameLast = true;
            } else {
                // Сидоров Иван Петрович
                $lastName = $m[1];
                $firstName = $m[3];
                $middleName = $m[5];
            }
        }
        $this -> ln = $lastName;
        if (isset($firstName)) $this -> fn = $firstName;
        else $this -> fn = '';
        if (isset($middleName)) $this -> mn = $middleName;
        else $this -> mn = '';
        if (isset($sex)) $this -> sex = $sex;
		else $this -> sex = $this -> getSex();
        
        return;
    }

    function prepareRules () {
        foreach ( array("lastName", "firstName", "middleName") as $type ) {
            foreach(array("suffixes" ,"exceptions") as $key) {
                $n = count($this -> rules->$type->$key);
                for ($i = 0; $i < $n; $i++) {
                    $this->rules->$type->{$key}[$i] = $this->rule($this->rules->$type->{$key}[$i]);
                }
            }
        }
    }

    function rule ($rule) {
        preg_match("/^\s*([fm]?)\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/", $rule, $m);
            if ( $m ) return array (
            "sex" => $m[1],
            "test" => split(',', $m[2]),
            "mods" => array ($m[3], $m[4], $m[5], $m[6], $m[7])
        );
        return false;
    }

    // склоняем слово по указанному набору правил и исключений
    function word ($word, $sex, $wordType, $gcase) {
        // исходное слово находится в именительном падеже
        if( $gcase == $this->gcaseNom) return $word;

        // составные слова
        if( preg_match("/[-]/", $word)) {
                $list = $word->split('-');
                $n = count($list);
                for($i = 0; $i < $n; $i++) {
                        $list[$i] = $this->word($list[$i], $sex, $wordType, $gcase);
                }
                return join('-', $list);
        }

        // Иванов И. И.
        if ( preg_match("/^[А-ЯЁ]\.?$/i", $word)) return $word;
        $this->init();
        $rules = $this->rules->$wordType;

        if ( $rules->exceptions) {
                $pick = $this->pick($word, $sex, $gcase, $rules->exceptions, true);
                if ( $pick ) return $pick;
        }
        $pick = $this->pick($word, $sex, $gcase, $rules->suffixes, false);
        if ($pick) return $pick;
        else return $word;
    }

    // выбираем из списка правил первое подходящее и применяем 
    function pick ($word, $sex, $gcase, $rules, $matchWholeWord) {
        $wordLower = strtolower($word);
        $n = count($rules);
        for($i = 0; $i < $n; $i++) {
            if ( $this->ruleMatch($wordLower, $sex, $rules[$i], $matchWholeWord)) {
                return $this->applyMod($word, $gcase, $rules[$i]);
            }
        }
        return false;
    }


    // проверяем, подходит ли правило к слову
    function ruleMatch ($word, $sex, $rule, $matchWholeWord) {
        if ($rule["sex"] == $this->sexM && $sex == $this->sexF) return false; // male by default
        if ($rule["sex"] == $this->sexF && $sex != $this->sexF) return false;
        $n = count($rule["test"]);
        for($i = 0; $i < $n; $i++) {
            $test = $matchWholeWord ? $word : substr($word, max(strlen($word) - strlen($rule["test"][$i]), 0));
            if($test == $rule["test"][$i]) return true;
        }
        return false;
    }

    // склоняем слово (правим окончание)
    function applyMod($word, $gcase, $rule) {
        switch($gcase) {
            case $this -> gcaseNom: $mod = '.'; break;
            case $this -> gcaseGen: $mod = $rule["mods"][0]; break;
            case $this -> gcaseDat: $mod = $rule["mods"][1]; break;
            case $this -> gcaseAcc: $mod = $rule["mods"][2]; break;
            case $this -> gcaseIns: $mod = $rule["mods"][3]; break;
            case $this -> gcasePos: $mod = $rule["mods"][4]; break;
            default: exit("Unknown grammatic case: "+gcase);
        }
        $n = strlen($mod);
        for($i = 0; $i < $n; $i++) {
            $c = substr($mod, $i, 1);
            switch($c) {
                case '.': break;
                case '-': $word = substr($word, 0, strlen($word) - 1); break;
                default: $word .= $c;
            }
        }
        return $word;
    }
    
    function getSex() {
        if( strlen($this->mn) > 2) {
            switch(substr($this->mn, -2)) {
                case 'ич': return $this->sexM;
                case 'на': return $this->sexF;
            }
        }
        return '';
    }
	
    function fullName($gcase) {
    	$tmpstr = ($this->fullNameSurnameLast ? '' : $this->lastName($gcase) . ' ')
            . $this -> firstName($gcase) . ' ' . $this -> middleName($gcase)
            . ($this -> fullNameSurnameLast ? ' ' . $this -> lastName($gcase) : ''); 
        return preg_replace("/^ +| +$/", '', $tmpstr);
    }
    
    function lastName($gcase) {
        return $this->word($this -> ln, $this -> sex, 'lastName', $gcase);  
    }
    
    function firstName($gcase) {
        return $this->word($this -> fn, $this -> sex, 'firstName', $gcase);
    }
    
    function middleName($gcase) {
        return $this->word($this -> mn, $this -> sex, 'middleName', $gcase);
    }
}






?>
 

Фанат

oncle terrible
Команда форума
Да содержимое не так важно.
Я думаю, эта функция заточена под однобайтные кодировки, а на вход ей подается утф
 

Фанат

oncle terrible
Команда форума
я думаю, проще всего будет перед ее вызовом перекодировать текст в windows1251, а после вызова - обратно
 

scnipper

Новичок
я думаю, проще всего будет перед ее вызовом перекодировать текст в windows1251, а после вызова - обратно
это не помогает. На локальном сервере все работает под утф но на хосте почему то такой бред . Я не знаю что делать помогите.......
 

Фанат

oncle terrible
Команда форума
точно не помогает?
а как ты пробовал? а как проверял?
 

scnipper

Новичок
не работает точно вот так проверял
PHP:
mb_internal_encoding("cp1251");
да и данные берутся из mysql базы но там все норм ни каких закарючек
 

Фанат

oncle terrible
Команда форума
перед вызовом этой функции перекодировать текст в windows1251, а после вызова - обратно
 

Фанат

oncle terrible
Команда форума
mb_convert_encoding
третьим параметром указывать действительную кодировку текста.

после применения функции, соответственно - обратная операция
 
Сверху