Php 把字符串剪短

Php 把字符串剪短,php,string,Php,String,如何将字符串缩短,使其不会转到div标记中的下一行,例如mymessage字符串包含以下内容: 我们更喜欢可以回答的问题,而不仅仅是讨论。提供详细信息。写得清楚简单。如果你的问题是关于这个网站的,可以在meta上提问 我想最好把它显示为 我们更喜欢可以回答的问题,而不仅仅是讨论。提供。。。阅读更多 我想用PHP把字符串缩短,但是你有以下问题 。。。阅读更多 您可以看到上面的字符串仍然可以进一步扩展。无论是否可以这样做,请提前感谢检查大小,如果大小大于最大值,请使用最左边的字符 最左边的#=总大小

如何将字符串缩短,使其不会转到div标记中的下一行,例如my
message
字符串包含以下内容:

我们更喜欢可以回答的问题,而不仅仅是讨论。提供详细信息。写得清楚简单。如果你的问题是关于这个网站的,可以在meta上提问

我想最好把它显示为

我们更喜欢可以回答的问题,而不仅仅是讨论。提供。。。阅读更多

我想用PHP把字符串缩短,但是你有以下问题

。。。阅读更多


您可以看到上面的字符串仍然可以进一步扩展。无论是否可以这样做,请提前感谢检查大小,如果大小大于最大值,请使用最左边的字符

最左边的#=总大小-大小(“…阅读更多”)。 然后将“读取更多”附加到最左边的字符


Jacob

以下是一个例子:

函数Truncate($str,$length=10,$trailing='…')) { //取下尾随的木炭 $length-=strlen($training); 如果(strlen($str)>$length) { //字符串超出长度,截断并添加尾随点 返回substr($str,0,$length)。$trailing; } 其他的 { //字符串已足够短,请返回字符串 $res=$str; } 返回$res; }
关于如何缩短字符串的问题已经有了答案,但您的主要问题是:

您如何将字符串剪短,使其不会转到div标记中的下一行

这在大多数情况下都不起作用

例如:

iiiiiiiiii

wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

你看到问题了吗

这仅在您的角色具有相同的宽度时有效,如:

iiiiiiiiii
wwwwwwwwww

这完全取决于字体。当然,您可以使用单空格字体,但这不是一个解决方案。不管怎样,你为什么要这么做?即使您设法使其在特定字体上工作,也可能是用户没有它。然后将使用不同的字体,一切都可能中断…

在PHP中使用非单空格字体基本上不可能做到这一点(即使使用单空格字体,也很难准确判断字符串在某个浏览器中的长度。在浏览器中执行此操作的唯一方法是将其放在a中,并将跨度的宽度设置为某个宽度,然后使用溢出:隐藏。

使用PHP,可以使用函数执行截断:

function truncate_to_length($text, $length, $text_if_longer = "...") 
{
    if (strlen($text) > $length) 
    {
        $text = wordwrap($text, $length);
        $text = substr($text, 0, strpos($text, "\n"));
        return $text . $text_if_longer;
    }
    return $text;
}

哦,我想出了一些有效但不完全有效的方法…我想和大家分享

div.string{
    
    height:15px;        
    overflow:hidden;
}
它解决了由于溢出而无法将整个单词隐藏到行尾的问题,并且高度仅设置为一行。但是,上述操作仍然无法解决Rufinus所示的问题:

iiiiiiiiiiiiii

wwwwwwwwwwwwww


如果您知道浏览器使用的是哪种true type字体,则可以使用GD库中的来计算文本的宽度。然后迭代并删除文本末尾的字符,直到它适合您的div

我知道这可能不是很有效,但它确实有效。您可以针对特定的解决方案进行微调和优化

<?
    $width = 280;   // max. width in pixels that the text should have
    $font = 'C:\Windows\Fonts\verdana.TTF';
    $text = 'The quick brown fox jumps over the lazy dog';

    function getWidth($text) {
        list($x1, , $x2) = imagettfbbox(12, 0, $font, $text);
        return $x2-$x1;
    }

    while (getWidth($text.'...') > $width) $text = substr($text, 0, -1);
?>

<style type='text/css'>
    #my_div {
        font-family: Verdana; 
        font-size: 12pt; 
        border: 1px solid black; 
        width: 280px; 
        padding: 0
    }
</style>

<div id='my_div'>
    <?=$text?>...
</div>

#我的分区{
字体系列:Verdana;
字号:12号;
边框:1px纯黑;
宽度:280px;
填充:0
}
...

根据您使用的浏览器,这一行CSS可以实现以下功能:

div.string {
    word-wrap: break-word;
}

以下内容大部分有效;主要问题是“…阅读更多”通知可能会掩盖一封信的一部分。它还使用了大量的表示元素,需要JS。这让我觉得不干净

最外面的元素(class.string)用于设置整体大小。text保存要显示的文本。子层次结构中的.Between.string和.text是一个大宽度的元素。这将所有文本放在一行。JS用于显示或隐藏“…阅读更多”通知


.字符串{
高度:1米;
宽度:25%;
位置:相对;/*为子级创建包含块*/
边框:1px纯黑;
溢出:隐藏;
背景:白色;/*或其他任何颜色,只要不是“透明的”*/
}
.string.line{
宽度:5000px;/*足够长吗*/
}
.字符串.通知{
位置:绝对位置;
排名:0;
右:0;
z指数:1;
显示:无;
背景:inherit;/*这样通知就会完全掩盖下面的内容*/
}
我们更喜欢可以回答的问题,
不只是讨论。提供细节。写得清楚简单。如果你的
问题是关于这个网站,改为在meta上问它。

Lorem ipsum dolor sit amet。 功能溢出(elt){ 返回elt.offsetWidth>elt.parentNode.parentNode.clientWidth; } 函数getNotice(textElt){ 试一试{ return(textElt.parentNode.parentNode.getElementsByClassName('notice'))[0]; }捕获(e){ 返回{style:{}; } } 功能展示(elt){ elt.style.display='block'; } 函数隐藏(elt){ elt.style.display='none'; } 函数showReadMoreNotices(){ var text=document.getElementsByClassName('text');
对于(var i=0;i这是一个从smarty模板中选取的函数,它可以在不剪切字符串的情况下缩短字符串

function str_short($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
    if ($length == 0)
        return '';

    if (strlen($string) > $length) {
        $length -= min($length, strlen($etc));

        if (!$break_words && !$middle) {
            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
        }

        if(!$middle) {
            return substr($string, 0, $length) . $etc;
        } else {
            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
        }
    } else {
        return $string;
    }
}

“[…]这样它就不会转到下一行[…]”–要做到这一点,你需要知道一行的“长度”和文本显示的宽度。使用PHP很难做到这一点。你是否想过使用JavaScript来做到这一点(不幸的是,我的工作要求不允许使用javascript。但是,如果你有一个解决方案供其他人使用+1,请发布它。这是我的首选方法。永远不要为客户端问题限制服务器端变量,尤其是可能随时间变化的问题:)更改hei
<style type="text/css">
  .string {
    height: 1em;
    width: 25%;
    position: relative; /* create containing block for children */
    border: 1px solid black;
    overflow: hidden;
    background: white; /* or whatever, as long as it's not "transparent". */
  }
  .string .line {
    width: 5000px; /* long enough for you? */
  }
  .string .notice {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
    display: none;
    background: inherit; /* so that the notice will completely cover up whatever's beneath */
  }
</style>

<div class="string">
  <div class="line"><span class="text">We prefer questions that can be answered, 
    not just discussed. Provide details. Write clearly and simply. If your 
    question is about this website, ask it on meta instead.</span></div>
</div>
<hr />
<div class="string">
  <div class="line"><span class="text">Lorem ipsum dolor sit amet.</span></div>
</div>

<script>
  function isOverflowed(elt) {
      return elt.offsetWidth > elt.parentNode.parentNode.clientWidth;
  }
  function getNotice(textElt) {
       try {
           return (textElt.parentNode.parentNode.getElementsByClassName('notice'))[0];
       } catch (e) {
           return {style: {}};
       }
  }
  function show(elt) {
      elt.style.display = 'block';
  }
  function hide(elt) {
      elt.style.display = 'none';
  }
  function showReadMoreNotices() {
    var text=document.getElementsByClassName('text');
    for (var i=0; i<text.length; ++i) {
      if (isOverflowed(text[i])) {
          show(getNotice(text[i]));
      } else {
          hide(getNotice(text[i]));
      }
    }
  }

  var strings = document.getElementsByClassName('string');
  var notice = document.createElement('div');
  notice.appendChild(document.createTextNode('\u2026Read more'));
  notice.className = 'notice';
  for (var i=0; i<strings.length; ++i) {
      strings[i].appendChild(notice.cloneNode(true));
  }

  showReadMoreNotices();
  /* use your favorite event registration method here. Not that the traditional 
   * model is my favorite, it's just simple.
   */
  window.onresize = showReadMoreNotices;
</script>
function str_short($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
    if ($length == 0)
        return '';

    if (strlen($string) > $length) {
        $length -= min($length, strlen($etc));

        if (!$break_words && !$middle) {
            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
        }

        if(!$middle) {
            return substr($string, 0, $length) . $etc;
        } else {
            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
        }
    } else {
        return $string;
    }
}