Русский Текст Обрезается С Крякозябрами

Тема в разделе "PHP", создана пользователем Tias, 4 июл 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Tias

    Tias

    Регистр.:
    26 дек 2007
    Сообщения:
    438
    Симпатии:
    147
    Замечал во многих движках и скриптах такой косяк. Сейчас проблема с joomla и модулем "JoomlaXTC News Pro Module
    ".
    Модуль выводит новости из разделов и показывает заданное количество символов текста первой новости.
    С латиницей скрипт работает нормально, а вот когда статьи на русском, то случается, что обрезаются слова криво и в конце обрезанного слова ставится иероглиф.
    Как можно убрать эту ошибку? Ниже код модуля:
    PHP:
    <?PHP
    /*
     JoomlaXTC News Pro Module
     version 1.0 (Joomla 1.5)
     copyright (c) 2008 JoomlaXTC   www.joomlaxtc.com
    */
    defined('_JEXEC') or die('Restricted access');
    require_once (
    JPATH_SITE.DS.'components'.DS.'com_content'.DS.'helpers'.DS.'route.php');
    if (!
    function_exists('jxtcParseRow')) {
        function 
    jxtcParseRow($row,$html,$aid,$maxintro) {
                if(
    $row->access <= $aid) {
                    
    $link JRoute::_(ContentHelperRoute::getArticleRoute($row->slug$row->catslug$row->sectionid));
                } else {
                    
    $link JRoute::_('index.php?option=com_user&view=login');
                }
                
    $intro $row->introtext;
                
    $ini=strpos(strtolower($row->introtext),'<img');
                if (
    $ini === false$img '';
                else {
                    
    $ini strpos($row->introtext,'src="',$ini)+5;
                    
    $fin strpos($row->introtext,'"',$ini);
                    
    $img substr($row->introtext,$ini,$fin-$ini);
                    
    $fin strpos($row->introtext,'>',$fin);
                    
    $intro substr($row->introtext,$fin+1);
                }
                if (!empty(
    $maxintro)) $intro trim(substr($intro,0,$maxintro)).'...';
                
    $hold $html;
                
    $hold str_replace'{link}'$link$hold );
                
    $hold str_replace'{title}'htmlspecialchars($row->title), $hold );
                
    $hold str_replace'{intro}'$row->introtext$hold );
                
    $hold str_replace'{introtext}''<p class="jnpp">'.$intro.'</p>'$hold );
                
    $hold str_replace'{introimage}'$img$hold );
                
    $hold str_replace'{section}'$row->sec_title$hold );
                
    $hold str_replace'{category}'$row->cat_title$hold );
                
    $hold str_replace'{date}'$row->created$hold );
                
    $hold str_replace'{moddate}'$row->modified$hold );
                
    $hold str_replace'{author}'$row->author$hold );
                
    $hold str_replace'{authorid}'$row->authorid$hold );
            return 
    $hold;
        }
    }
    global 
    $mainframe;
    $db                =& JFactory::getDBO();
    $user            =& JFactory::getUser();
    $userId        $user->get('id');
    $columns    trim$params->get('columns',3) );
    $lines        $params->get('lines'1);
    $pages        $params->get('pages'1);
    $more            $params->get('more'0);
    $moretext    trim($params->get('moretext'''));
    $morehtml    $params->get('morehtml''{title}');
    $morecols    trim$params->get('morecols',1) );
    $morergb    trim$params->get('morergb','cccccc') );
    $catid        trim$params->get('catid') );
    $secid        trim$params->get('secid') );
    $button        $params->get('button','default');
    $html            trim$params->get('html','{intro}') );
    $maxintro    trim$params->get('maxintro') );
    $show_front    $params->get('show_front'1);
    $class         trim($params->get('moduleclass_sfx'));
    $autoscroll    $params->get('autoscroll',0);
    $autospeed    $params->get('autospeed',1000);
    $autopause    $params->get('autopause',800);
    $scrollstep    $params->get('scrollstep',1);
    $mouse    $params->get('mouse',0);
    $easingtype    $params->get('easingtype','none');
    $easingspeed    $params->get('easingspeed',0);
    $speed    $params->get('speed',0);
    $scrolltype    $params->get('scrolltype','h');
    $circular    $params->get('circular',1);
    $layout    $params->get('layout',1);
    $aid            $user->get('aid'0);
    $contentConfig = &JComponentHelper::getParams'com_content' );
    $access        = !$contentConfig->get('show_noauth');
    $nullDate    $db->getNullDate();
    $date =& JFactory::getDate();
    $now $date->toMySQL();
    $where        'a.state = 1'
        
    ' AND ( a.publish_up = '.$db->Quote($nullDate).' OR a.publish_up <= '.$db->Quote($now).' )'
        
    ' AND ( a.publish_down = '.$db->Quote($nullDate).' OR a.publish_down >= '.$db->Quote($now).' )'
        
    ;
    // User Filter
    switch ($params->get'user_id' ))
    {
        case 
    'by_me':
            
    $where .= ' AND (created_by = ' . (int) $userId ' OR modified_by = ' . (int) $userId ')';
            break;
        case 
    'not_me':
            
    $where .= ' AND (created_by <> ' . (int) $userId ' AND modified_by <> ' . (int) $userId ')';
            break;
    }
    // Ordering
    switch ($params->get'ordering' )) {
        case 
    'm_dsc':
            
    $ordering        'a.modified DESC, a.created DESC';
            break;
        case 
    'c_dsc':
        default:
            
    $ordering        'a.created DESC';
            break;
    }
    if (
    $catid) {
        
    $ids explode','$catid );
        
    JArrayHelper::toInteger$ids );
        
    $catCondition ' AND (cc.id=' implode' OR cc.id='$ids ) . ')';
    }
    if (
    $secid) {
        
    $ids explode','$secid );
        
    JArrayHelper::toInteger$ids );
        
    $secCondition ' AND (s.id=' implode' OR s.id='$ids ) . ')';
    }
    // Content Items only
    $query 'SELECT a.*, cc.title as cat_title, s.title as sec_title, u.name as author, u.username as authorid,' .
        
    ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'.
        
    ' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug'.
        
    ' FROM #__content AS a' .
        (
    $show_front == '0' ' LEFT JOIN #__content_frontpage AS f ON f.content_id = a.id' '') .
        
    ' INNER JOIN #__categories AS cc ON cc.id = a.catid' .
        
    ' INNER JOIN #__sections AS s ON s.id = a.sectionid' .
        
    ' INNER JOIN #__users AS u ON u.id = a.created_by' .
        
    ' WHERE '$where .' AND s.id > 0' .
        (
    $access ' AND a.access <= ' .(int) $aid' AND cc.access <= ' .(int) $aid' AND s.access <= ' .(int) $aid '').
        (
    $catid $catCondition '').
        (
    $secid $secCondition '').
        (
    $show_front == '0' ' AND f.content_id IS NULL ' '').
        
    ' AND s.published = 1' .
        
    ' AND cc.published = 1' .
        
    ' ORDER BY '$ordering;
        
    $limit $columns*$lines*$pages;
    $db->setQuery($query0$limit+$more);
    $items $db->loadObjectList();
    if (
    count($items) == 0) return;    // Return empty
    $i=1;
    $c=1;
    $r=1;
    $p=1;
    $rows array_slice($items,0,$limit);
    $mores array_slice($items,$limit);
    if (
    $pages 1) {
        
    $jshdr '<script src="modules/mod_jxtc_newspro/js/jquery.js" type="text/javascript"></script>
        <script src="modules/mod_jxtc_newspro/js/jcarousellite.js" type="text/javascript"></script>'
    ;
        
    $jscall '<script language="javascript">
            jQuery.noConflict();
            jQuery(window).load(function(){
              jQuery(".jnp'
    .$class.'main").jCarouselLite({';
        if (
    $autoscroll == 1) {
            
    $jscall .= 'auto: '.$autopause.', speed: '.$autospeed.',';
        }
        if (
    $scrollstep != 1) {
            
    $jscall .= 'scroll: '.$scrollstep.',';
        }
        if (
    $mouse == 1) {
            
    $jshdr .= '<script src="modules/mod_jxtc_newspro/js/jquery.mousewheel.js" type="text/javascript"></script>';
            
    $jscall .= 'mouseWheel: true,';
        }
        if (
    $easingtype != 'none') {
            
    $jshdr .= '<script src="modules/mod_jxtc_newspro/js/jquery.easing.js" type="text/javascript"></script>';
            
    $jscall .= 'easing: "'.$easingtype.'", speed: '.$easingspeed.',';
        }
        if (
    $speed 0) {
            
    $jscall .= 'speed: '.$speed.',';
        }
        if (
    $scrolltype == 'v') {
            
    $jscall .= 'vertical: true,';
        }
        if (
    $circular == 0) {
            
    $jscall .= 'circular: false,';
        }
        
    $jscall .= '
              btnNext: ".jnp'
    .$class.'prev",
              btnPrev: ".jnp'
    .$class.'next"
          });
        });
        </script>'
    ;
        echo 
    $jshdr.$jscall;
    //
    // wrapper div for all newspro module, closest thing to css taming
    //
        
    echo '<div style="position:relative; width:100% !important ;overflow:hidden !important; margin-right:auto;">';
        switch (
    $layout) {
            case 
    "0":    // none
            
    echo '<div class="jnp'.$class.'main">';
            break;
            case 
    "1":    // left/right
            
    echo '<img class="jnp'.$class.'prev" src="modules/mod_jxtc_newspro/buttons/'.$button.'/prev.gif" style="float:left"/>';
            echo 
    '<div class="jnp'.$class.'main" style="float:left;">';
            break;
            case 
    "2":    // top
            
    echo '<div><img class="jnp'.$class.'prev" src="modules/mod_jxtc_newspro/buttons/'.$button.'/prev.gif" style="float:left"/>';
            echo 
    '<img class="jnp'.$class.'next" src="modules/mod_jxtc_newspro/buttons/'.$button.'/next.gif" style="float:right"/></div>';
            echo 
    '<div class="jnp'.$class.'main">';
            break;
            case 
    "3":    // bottom
            
    echo '<div class="jnp'.$class.'main">';
            break;
            case 
    "4":    // top/bottom
            
    echo '<img class="jnp'.$class.'prev" src="modules/mod_jxtc_newspro/buttons/'.$button.'/prev.gif" />';
            echo 
    '<div class="jnp'.$class.'main">';
            break;
        }
        echo 
    '<ul>';
        foreach ( 
    $rows as $row ) {
            if (
    $c==&& $r==1) {
                echo 
    '<li><table width="100%" border="0" cellpadding="0" cellspacing="0">';
            }
            if (
    $c==1) {
                echo 
    '<tr>';
            }
            echo 
    '<td valign="top">'.jxtcParseRow($row,$html,$aid,$maxintro).'</td>';
            
    $i++;$c++;
            if (
    $c $columns) {
                echo 
    '</tr>';
                
    $c=1;
                
    $r++;
                if (
    $r $lines && $i $limit) {
                    echo 
    '</table></li>';
                    
    $r=1;
                    
    $p++;
                }
            }
        }
        if (
    $r 1) echo '</table></li>';
        echo 
    '</ul>';
        switch (
    $layout) {
            case 
    "0"// none
            
    echo '</div>';
            break;
            case 
    "1":    // left/right
            
    echo '</div>';
            echo 
    '<img class="jnp'.$class.'next" src="modules/mod_jxtc_newspro/buttons/'.$button.'/next.gif" style="float:left"/>';
            break;
            case 
    "2"// top
            
    echo '</div>';
            break;
            case 
    "3"// bottom
            
    echo '</div>';
            echo 
    '<div style="margin:-6px 0px 0px 0px; padding-right:15px; background:url(modules/mod_jxtc_newspro/dotted.gif) 50px 0px no-repeat;"><img class="jnp'.$class.'prev" src="modules/mod_jxtc_newspro/buttons/'.$button.'/prev.gif"/>';
            echo 
    '<img class="jnp'.$class.'next" src="modules/mod_jxtc_newspro/buttons/'.$button.'/next.gif"/></div>';
            break;
            case 
    "4"// top/bottom
            
    echo '</div>';
            echo 
    '<img class="jnp'.$class.'next" src="modules/mod_jxtc_newspro/buttons/'.$button.'/next.gif" />';
            break;
        }
        echo 
    '</div>';
    }
    else {
        echo 
    '<table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>';
        foreach ( 
    $rows as $row ) {
            if (
    $c==1) {
                echo 
    '<tr>';
            }
            echo 
    '<td valign="top">'.jxtcParseRow($row,$html,$aid,$maxintro).'</td>';
            
    $i++;$c++;
            if (
    $c $columns) {
                echo 
    '</tr>';
                
    $c=1;
            }
        }
        if (
    $c 1) echo '</tr>';
        echo 
    '</table>';
    }
    if (
    count ($mores) > 0) {
        if (
    $moretext) {
            echo 
    '<img src="modules/mod_jxtc_newspro/images/article-grey.gif">&nbsp;&nbsp;<span style="color:#'.$morergb.'">'.$moretext.'</span><br/>';
        }
        echo 
    '<table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>';
        
    $i=1;
        
    $c=1;
        foreach ( 
    $mores as $row ) {
            if (
    $c==1) {
                echo 
    '<tr>';
            }
            echo 
    '<td valign="top">'.jxtcParseRow($row,$morehtml,$aid,$maxintro).'</td>';
            
    $i++;$c++;
            if (
    $c $morecols) {
                echo 
    '</tr>';
                
    $c=1;
            }
        }
        if (
    $c 1) echo '</tr>';
        echo 
    '</table>';
    }
     
  2. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    просто те функции работают с однобайтными символами и двухбайтный символ из кириллицы обрезается пополам до одного и получается однобайтный символ неизвестно чего.

    решение например включить внутреннюю кодировку utf8 если не включена
    PHP:
    mb_internal_encoding("UTF-8");
    и дальше заменить функции которые работают с текстом на мультибайтные (приставка mb_:(

    PHP:
    //было
    print substr('авбхдеёшзи'33);
    //стало
    print mb_substr('авбхдеёшзи'33);
     
    Paulus и Tias нравится это.
Статус темы:
Закрыта.