【问题标题】:Cut strings short PHP缩短字符串 PHP
【发布时间】:2020-03-21 19:14:29
【问题描述】:

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

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

我希望最好将其显示为

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

我想用 PHP 把字符串剪短,但是你遇到了以下问题

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ... 阅读更多

你可以看到上面的字符串仍然可以扩展一点。任何方式都可以做到这一点,提前致谢

【问题讨论】:

  • “[...] 所以它不会转到下一行 [...]” - 为此,您需要知道一行的“长度”以及文本将显示的宽度。使用 PHP 很难做到这一点。
  • 您是否考虑过使用 JavaScript 来做到这一点?
  • :( 不幸的是,我的工作要求不允许使用 javascript。但如果您有其他人可以使用的解决方案,请发布它

标签: php string


【解决方案1】:

如何缩短字符串已得到解答,但您的主要问题是:

你会如何将字符串剪短这样它就不会转到 div 标签中的下一行

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

例如:

iiiiiiiiiiii

wwwwwwwww

你看到问题了吗?

这仅适用于您的字符具有相同宽度的情况,例如:

iiiiiiiiii
wwwwwwwwww

【讨论】:

    【解决方案2】:

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

    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;
    }
    

    【讨论】:

      【解决方案3】:

      以下主要是有效的;主要问题是“...阅读更多”通知可以掩盖一封信的一部分。它还使用了一堆表现元素并且需要 JS。这让我觉得不干净。

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

      <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>
      

      【讨论】:

      • 我第一次发布的代码不适合发布;缺少创建通知元素的部分。现在已经修好了。
      【解决方案4】:

      检查大小,如果大小大于您的最大值,则取最左边的字符。

      最左边的 # = 总大小 - 大小(“...阅读更多”)。 然后将 read more 添加到最左边的字符。

      雅各布

      【讨论】:

        【解决方案5】:

        这是取自http://snippetdb.com/php/truncate-string的示例:

        函数截断 ($str, $length=10, $trailing='...') { // 去掉尾随的字符 $length-=strlen($trailing); 如果 (strlen($str) > $length) { // 字符串超出长度,截断并添加尾随点 返回 substr($str,0,$length).$trailing; } 别的 { // 字符串已经足够短,返回字符串 $res = $str; } 返回 $res; }

        【讨论】:

          【解决方案6】:

          哦,我想出了一些可行但不完全可行的东西......我想分享一下

          div.string{
              
              height:15px;        
              overflow:hidden;
          }
          

          它解决了由于溢出和高度仅设置为一行而将不适合行尾的整个单词隐藏的问题。但是上面仍然没有解决Rufinus显示的问题:

          iiiiiiiiiiiiiii

          wwwwwwwwwwwwwww

          【讨论】:

          • +1 这是我的首选方法。永远不要为客户端问题限制服务器端变量,尤其是可能随时间变化的变量:)
          • 将高度改为“1em”,你会得到+1。
          • oo 谢谢我想知道是否有这样的事情:D
          【解决方案7】:

          这是从 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;
              }
          }
          

          【讨论】:

            【解决方案8】:

            这完全取决于字体。当然,您可以使用等宽字体,但这不是解决方案。无论如何,你为什么要这样做?即使您设法使其适用于某种字体,也可能是用户没有它。然后将使用不同的字体,一切都可能会中断......

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

                根据您使用的浏览器,这行 CSS 可以解决问题:

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

                【讨论】:

                  【解决方案11】:

                  如果您知道浏览器使用的是什么 true-type 字体,则可以使用 GD 库中的imagettfbbox() 来计算文本的宽度。然后迭代并从文本末尾删除字符,直到它适合您的 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>
                  

                  【讨论】:

                  • 我不推荐使用图像来限制文本宽度。我建议使用优雅的 CSS!
                  猜你喜欢
                  • 2011-04-28
                  • 1970-01-01
                  • 2017-11-11
                  • 2013-04-23
                  • 1970-01-01
                  • 2019-10-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-08-11
                  相关资源
                  最近更新 更多