[PHP] Zeilenbegrenzer

Dieses Thema im Forum "Webentwicklung" wurde erstellt von Spo0n22, 28. März 2011 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 28. März 2011
    Zeilenbegrenzer

    Hallo Community
    ich habe hier folgenden Zeilenbegrenzer geschrieben, der nach der 5ten Zeile "...weiterlesen" anzeigt:

    Spoiler
    PHP:
    function  zeilenbegrenzer ( $text ){
        
            
    $chars  300 ;
            
    $zl          5 // Zeilenlimit
            
    $zeilen  substr_count ( $text "\n" );
            
    $laenge  strlen ( $text );
            
            
            
            if(
    $zeilen  >=  $zl  &&  $laenge  $chars ){
                
                

                
    $explode  explode ( "\n" $text );

                
    $text  '' ;
                for(
    $i  0 $i  $zl $i ++){
                    
    $text  .=  $explode [ $i ] .  "\n" ;
                }
                

                
                
    $text  .=   " ... weiterlesen" ;
                    
            }else{
                        
                if(
    $laenge  $chars ){
            
                    
    $text  substr ( $text , 0 , $chars );  
                    
    $text  substr ( $text , 0 , strrpos ( $text , ' ' ));  
                    
    $text  .=  "\n ... weiterlesen" ;
                    
                }
            
            }
            
            
            
    $text  nl2br ( htmlspecialchars ( $text ENT_QUOTES ));
            return 
    $text ;
    }

    Ich habe das Gefühl, dass die Performance dadrunter etwas leidet, gibt es eine einfachere Lösung?
    Bei dem Bereich, der als /*DIESER BEREICH*/ markiert ist.
     
  2. 28. März 2011
    AW: Zeilenbegrenzer

    PHP:
    $explode  explode ( "\n" $text $zl  1 );
    array_pop ( $explode );
            
    $text  implode ( "\n" $explode ) .  " ... weiterlesen" ;
    oder:

    PHP:
    for ( $i  0 $o  0 $i  $zl ; ++ $i )
        
    $o  strpos ( $text "\n" $o ) +  1 ;
                
    return 
    substr ( $text 0 $o ) .  " ... weiterlesen" ;
     
  3. 28. März 2011
    AW: Zeilenbegrenzer

    Meiner Meinung nach ist dein Code etwas zu aufgebläht.
    Du brauchst eigentlich keine Abfragen, denn wenn Du die Funktionen richtig anwendest, kommst Du auch ohne zum gewünschten Ergebnis. Hier einmal ein Beispiel, wie ich es gemacht hätte:

    Code:
    function shortenText($in, $rows, $size) {
     $result = explode("\n", $in, $rows); // <- preg_split, etc. ersetzt.
     $result[4] = substr($result[4], 0, strpos($result[4], "\n"));
     $result = implode("\n", $result);
     $result = substr($result, 0, $size); 
     $result = substr($result, 0, strrpos($result, ' ')); 
     $result .= "... weiterlesen"; 
    
     return nl2br(htmlspecialchars($result, ENT_QUOTES));
    }
    
     
  4. 28. März 2011
    AW: Zeilenbegrenzer

    preg_split ist um einiges langsamer als explode, zudem gibts es bei preg_split sowie explode einen parameter namens "limit" den man anwenden kann um nur eine gewisse anzahl an tokens zu erzeugen.

    PHP:
    $text  "foo\nbar\nbaz\nqrz" ;
    $split  explode ( "\n" $text 3 );

    // array ("foo", "bar", "baz\nqrz")
     
  5. 28. März 2011
    AW: Zeilenbegrenzer

    Bei dem Code werden 1 Zeilige Texte nicht bis zum Ende ausgeschrieben,
    habe den Code von Murdoc verwendet.


    Könnte man es vielleicht noch etwas apspecken oder ist das so in Ordnung.
    Es soll nach 5 Zeilen begerenzt werden oder wenn mehr als 300 Zeichen eingegeben worden sind.

    Jetziger Code:
    Spoiler
    PHP:
    function  zeilenbegrenzer ( $text ){
        
            
    $chars  300 ;
            
    $zl          5 ;
            
    $zeilen  substr_count ( $text "\n" );
            
    $laenge  strlen ( $text );
            
            
            if(
    $zeilen  >=  $zl  &&  $laenge  $chars ){
                
                
    $explode  explode ( "\n" $text $zl  1 );
                
    array_pop ( $explode );
                                
                
    $text  implode ( "\n" $explode ) .  " ... weiterlesen" ;  
                
                    
            }else{
                        
                if(
    $laenge  $chars ){
            
                    
    $text  substr ( $text , 0 , $chars );  
                    
    $text  substr ( $text , 0 , strrpos ( $text , ' ' ));  
                    
    $text  .=  "\n ... weiterlesen" ;
                    
                }
            
            }
            
            
            
    $text  nl2br ( htmlspecialchars ( $text ENT_QUOTES ));
            return 
    $text ;
    }
     
  6. 28. März 2011
    AW: Zeilenbegrenzer

    Das ist ein kleiner Fehler, einfach das letzte substr korrigieren.

    @ murdoc

    Habs mal etwas überarbeitet.

    Jetzt stellt sich mir die Frage, ob sich der Aufwand lohnt explode, substr und strpos zu nutzen und es im Vergleich dann immernoch schneller abschneidet, als ein preg_split alleine.

    Ich hab gleich mal n kleines Benchmark geschrieben:

    Spoiler
    Code:
    <?php
    
    function shortenText1($in, $rows, $size) {
     $result = explode("\n", $in, $rows);
     $result[4] = substr($result[4], 0, strpos($result[4], "\n"));
     $result = implode("\n", $result);
     $result = substr($result, 0, $size); 
     $result = substr($result, $size, strrpos($result, ' ')); 
     $result .= "... weiterlesen"; 
    
     return nl2br(htmlspecialchars($result, ENT_QUOTES));
    }
    
    function shortenText2($in, $rows, $size) { 
     $result = preg_split("/\n/", $in, $rows);
     $result = implode("\n", $result);
     $result = substr($result, 0, $size); 
     $result = substr($result, $size, strrpos($result, ' ')); 
     $result .= "... weiterlesen"; 
    
     return nl2br(htmlspecialchars($result, ENT_QUOTES));
    }
    
    $subject = "Ich mag\ngern lange\nSätze, die\neine spannende\nGeschichte vermitteln\nwollen.";
    print "Ausgabe:<br /><hr /><br />shortenText1(): <pre>".shortenText1($subject, 5, 300)."</pre><br />";
    print "shortenText2(): <pre>".shortenText2($subject, 5, 300)."</pre><br />";
    print "<br /><br />Schnelligkeit: <hr /><br />";
    
    $start = microtime(true);
    for($i=0;$i<100000;$i++)
     shortenText1($subject, 5, 300);
    
    print "shortenText() mit explode(): ".(microtime(true)-$start)." Sekunden bei 100000 Durchl&auml;ufen.<br />";
    
    $start = microtime(true);
    for($i=0;$i<100000;$i++)
     shortenText2($subject, 5, 300);
    
    print "shortenText() mit preg_split(): ".(microtime(true)-$start)." Sekunden bei 100000 Durchl&auml;ufen.<br /><br />";
    
    
    $start = microtime(true);
    for($i=0;$i<1000000;$i++)
     shortenText1($subject, 5, 300);
    
    print "shortenText() mit explode(): ".(microtime(true)-$start)." Sekunden bei 1000000 Durchl&auml;ufen.<br />";
    
    $start = microtime(true);
    for($i=0;$i<1000000;$i++)
     shortenText2($subject, 5, 300);
    
    print "shortenText() mit preg_split(): ".(microtime(true)-$start)." Sekunden bei 1000000 Durchl&auml;ufen.<br />";
    
    ?>

    Der wichtigste Teil:

    Spoiler
    Schnelligkeit:
    shortenText() mit explode(): 0.83775401115417 Sekunden bei 100000 Durchläufen.
    shortenText() mit preg_split(): 0.89412903785706 Sekunden bei 100000 Durchläufen.

    shortenText() mit explode(): 8.2323241233826 Sekunden bei 1000000 Durchläufen.
    shortenText() mit preg_split(): 8.9297339916229 Sekunden bei 1000000 Durchläufen.

    Also passt das insgesamt.
     
  7. 28. März 2011
    AW: Zeilenbegrenzer

    @terraNova: hach ja, stimmt. es ist schwer einmal verinnerlichtes wieder los zu werden, obwohl ich dieses argument von den "langsamen" regulären ausdrücken selbst auch schon einige male wiederlegt hab ^^

    PHP:
    <? php

    function  showQuoteLimit ( $text ){
        
            
    $chars  300 ;
            
    $zl     5 ;
            
            if (
    strlen ( $text ) >  $chars
                
    $text  trim ( substr ( $text 0 $chars )) .  "\n ... weiterlesen" ;
            elseif (
    substr_count ( $text "\n" ) >  $zl ) {
                
    $split  explode ( "\n" $text $zl  1 );
                
    array_pop ( $split );
                
                
    $text  implode ( "\n" $split ) .  ' ... weiterlesen' ;
                
                unset(
    $split );
            }
            
            return 
    nl2br ( htmlentities ( $text ENT_QUOTES ));
    nicht getestet
     
  8. 28. März 2011
    AW: Zeilenbegrenzer

    Naja, ich habs auch etwas umständlicher gestaltet. Wenn Du magst kannst Du ja deine Funktion nochmal zum Benchmarken reinhauen. Im Endeffekt gehts hier um Peanuts, aber interessant ist es ja trotzdem^^ Denke bei mir ist das Benutzen von substr(), strpos() ausschlaggebend. Wie gesagt, teste es mal mit deiner Funktion, bei mir wirds jetzt Zeitlich zu knapp.
     
  9. 28. März 2011
    AW: Zeilenbegrenzer

    benchmark das mal bitte (hab ein wenig experimentiert)

    PHP:
    function  showQuoteLimit ( $text ){
        
            
    $chars  30 ;
            
    $zl     5 ;
            
    $ln     strlen ( $text );
            
            
    preg_match ( '/([^\n]{'  $chars  '}(?:[ ]|[^ ]+)|(?:[^\n]+\n?){'  $zl  '})/' $text $match );
            
    $text  $match [ 1 ];
            
            unset(
    $match );
            
            if (
    $ln  strlen ( $text ))
                
    $text  .=  ' ... weiterlesen' ;
            
            return 
    nl2br ( htmlentities ( $text ENT_QUOTES ));
    }
    eben festgestellt, dass es nicht 100%ig funktioniert
    never mind
     
  10. 28. März 2011
    AW: Zeilenbegrenzer

    PHP:
    function  showQuoteLimit ( $text ){
        
            
    $chars  30 ;
            
    $zl     5 ;
            
    $ln     strlen ( $text );
            
            
    preg_match ( '/([^\n]{'  $chars  '}(?:[ ]|[^ ]+)|(?:[^\n]+\n?){'  $zl  '})/' $text $match );
            
    $text  $match [ 1 ];
            
            unset(
    $match );
            
            if (
    $ln  strlen ( $text ))
                
    $text  .=  ' ... weiterlesen' ;
            
            return 
    nl2br ( htmlentities ( $text ENT_QUOTES ));


    $subject  "Ich mag\ngern lange\nSätze, die\neine spannende\nGeschichte vermitteln\nwollen." ;


    $start  microtime ( true );
    for(
    $i = 0 ; $i < 1000000 ; $i ++)
        
    showQuoteLimit ( $subject );

    print 
    "showQuoteLimit() Murdoc: " .( microtime ( true )- $start ). " Sekunden bei 1000000 Durchl&auml;ufen.<br />" ;
    showQuoteLimit() Murdoc: 11.002024173737 Sekunden bei 1000000 Durchläufen.



    PHP:
    function  shortenText ( $in $rows $size ) {
        
    $result  explode ( "\n" $in $rows );  // <- preg_split, etc. ersetzt.
        
    $result [ 4 ] =  substr ( $result [ 4 ],  0 strpos ( $result [ 4 ],  "\n" ));
        
    $result  implode ( "\n" $result );
        
    $result  substr ( $result 0 $size );  
        
    $result  substr ( $result 0 strrpos ( $result ' ' ));  
        
    $result  .=  "... weiterlesen"

        return 
    nl2br ( htmlspecialchars ( $result ENT_QUOTES ));
    }
    gibt leider immer ... weiterlesen aus und gibt auch ab und zu mehr zeilen aus^^



    Verwende jetzt:
    PHP:
    function  showQuoteLimit ( $text ){
        
            
    $chars  300 ;
            
    $zl     5 ;
            
            if (
    strlen ( $text ) >  $chars ){ 
            
                    
    $text  substr ( $text , 0 , $chars );  
                    
    $text  substr ( $text , 0 , strrpos ( $text , ' ' ));  
                    
    $text  .=  "\n ... weiterlesen"
                    
            }elseif (
    substr_count ( $text "\n" ) >  $zl ) {
                    
    $split  explode ( "\n" $text $zl  1 );
                    
    array_pop ( $split );
                    
                    
    $text  implode ( "\n" $split ) .  ' ... weiterlesen' ;
                    
                    unset(
    $split );
            }
            
            return 
    nl2br ( htmlspecialchars ( $text ENT_QUOTES ));
    }
    showQuoteLimit(): 3.5780339241028 Sekunden bei 1000000 Durchläufen.

    zwar werden ab und zu mehr zeilen angezeigt, aber sorgt für abwechslung


    Vielleicht hat noch jemand Vorschläge?
     
  11. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.