2015-03-22 21 views
9

W laravel 4.0, używam poniższy kod do kompresji wyjść odpowiedzi HTML laravel do przeglądarki, jednak nie działa w laravel 5.Jak mogę skompresować HTML w laravel 5

App::after(function($request, $response) 
{ 
    if($response instanceof Illuminate\Http\Response) 
    { 
     $buffer = $response->getContent(); 
     if(strpos($buffer,'<pre>') !== false) 
     { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/"     => '<?php ', 
       "/\r/"      => '', 
       "/>\n</"     => '><', 
       "/>\s+\n</"     => '><', 
       "/>\n\s+</"     => '><', 
      ); 
     } 
     else 
     { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/"     => '<?php ', 
       "/\n([\S])/"    => '$1', 
       "/\r/"      => '', 
       "/\n/"      => '', 
       "/\t/"      => '', 
       "/ +/"      => ' ', 
      ); 
     } 
     $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer); 
     $response->setContent($buffer); 
    } 
}); 

proszę jak zrobić dokonać tej pracy w laravel 5.

LUB

Proszę podać lepszy sposób kompresji HTML w laravel 5 jeśli dowolny. Z góry dzięki.

NB: Nie chcę używać żadnego pakietu laravel do kompresji html, wystarczy prosty kod, który wykonuje pracę bez utraty wydajności.

+1

Wiem, że powiedziałeś, że nie chcesz pacakge - ale https://github.com/GrahamCampbell/Laravel-HTMLMin jest idealnym rozwiązaniem. A to nie "zabije osiągów" inaczej niż gdybyś zrobił to sam. – Laurence

+1

Odradzam to, co próbujesz zrobić _at all_ - element 'pre' nie jest jedyną rzeczą, w której biała przestrzeń może mieć znaczenie, ale także wewnątrz' textarea'/'input' lub zasadniczo w _any_ elemencie, jeśli pojawi się później na _formatted_ przez CSS ('white-space'). Po prostu __GZip__ dane wyjściowe przed wysłaniem go do klienta, jest o wiele bardziej skuteczne niż zakłócanie samego kodu HTML. – CBroe

+0

@ cbroe Jak korzystać z GZip? każdy przykład pracy – Digitlimit

Odpowiedz

6

Zalecanym sposobem wykonania tej czynności w Larvel 5 jest przepisanie funkcji jako middleware. Jak stwierdzono w docs:

..this middleware będzie wykonywać swoje zadanie po żądanie jest obsługiwane przez aplikację:

<?php namespace App\Http\Middleware; 

class AfterMiddleware implements Middleware { 

    public function handle($request, Closure $next) 
    { 
     $response = $next($request); 

     // Perform action 

     return $response; 
    } 
} 
+0

Nice. Jak tego używać? Czy uruchamiam to przy każdym żądaniu? – Digitlimit

+1

Tak, uruchomiłbyś to na każdym żądaniu http. Możesz zarejestrować go globalnie, dodając swoją klasę w 'app/Http/Kernel.php' – darronz

11

Kompletny kod jest to (z włączonym zwyczaj GZip):

<?php 

namespace App\Http\Middleware; 

use Closure; 

class OptimizeMiddleware 
{ 
    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * @return mixed 
    */ 
    public function handle($request, Closure $next) 
    { 
     $response = $next($request); 
     $buffer = $response->getContent(); 
     if(strpos($buffer,'<pre>') !== false) 
     { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/"     => '<?php ', 
       "/\r/"      => '', 
       "/>\n</"     => '><', 
       "/>\s+\n</"     => '><', 
       "/>\n\s+</"     => '><', 
      ); 
     } 
     else 
     { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/"     => '<?php ', 
       "/\n([\S])/"    => '$1', 
       "/\r/"      => '', 
       "/\n/"      => '', 
       "/\t/"      => '', 
       "/ +/"      => ' ', 
      ); 
     } 
     $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer); 
     $response->setContent($buffer); 
     ini_set('zlib.output_compression', 'On'); // If you like to enable GZip, too! 
     return $response; 
    } 
} 

Proszę sprawdzić pasek narzędzi przeglądarki sieci dla nagłówka Content-Length przed/po zaimplementować ten kod.

Ciesz się tym ... :) ...

2

To jest prawie kopia odpowiedzi Vahid's, ale rozwiązuje dwa problemy.

1) Sprawdza, czy odpowiedź jest BinaryFileResponse, ponieważ każda próba zmodyfikowania tego typu odpowiedzi spowoduje zgłoszenie wyjątku.

2) Zachował znaki nowej linii, ponieważ całkowite wyeliminowanie nowych linii prowadzi do złego kodu JavaScript w liniach z komentarzem jednoliniowym.

Na przykład, kod poniżej

var a; //This is a variable 
var b; //This will be commented out 

Czy stać

var a; //This is a variable var b; //This will be commented out 

Uwaga: W czasie tej odpowiedzi nie mogłem dostać w swoje ręce dobrym regex dopasować komentarzy pojedynczy wiersz bez komplikacji lub raczej ignoruj ​​nowe linie tylko na liniach z komentarzem w jednym wierszu, więc mam nadzieję na lepszą naprawę.

Oto zmodyfikowana wersja.

<?php 

namespace App\Http\Middleware; 

use Closure; 

class OptimizeMiddleware { 

/** 
* Handle an incoming request. 
* 
* @param \Illuminate\Http\Request $request 
* @param \Closure $next 
* @return mixed 
*/ 
public function handle($request, Closure $next) 
{ 
    $response = $next($request); 
    if ($response instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse) { 
     return $response; 
    } else { 
     $buffer = $response->getContent(); 
     if (strpos($buffer, '<pre>') !== false) { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/" => '<?php ', 
       "/\r/" => '', 
       "/>\n</" => '><', 
       "/>\s+\n</" => '><', 
       "/>\n\s+</" => '><', 
      ); 
     } else { 
      $replace = array(
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
       "/<\?php/" => '<?php ', 
       "/\n([\S])/" => '$1', 
       "/\r/" => '', 
       "/\n+/" => "\n", 
       "/\t/" => '', 
       "/ +/" => ' ', 
      ); 
     } 
     $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer); 
     $response->setContent($buffer); 
     ini_set('zlib.output_compression', 'On'); //enable GZip, too! 
     return $response; 
    } 
    } 
} 
+1

Miał również ten problem! dzięki za wskazanie. –

0

to najlepszy sposób .. nie musimy używać laravel packeges .thanks ..

<?php 
 

 
namespace App\Http\Middleware; 
 

 
use Closure; 
 

 
class OptimizeMiddleware 
 
{ 
 
    /** 
 
    * Handle an incoming request. 
 
    * 
 
    * @param \Illuminate\Http\Request $request 
 
    * @param \Closure $next 
 
    * @return mixed 
 
    */ 
 
    public function handle($request, Closure $next) 
 
    { 
 
     $response = $next($request); 
 
     $buffer = $response->getContent(); 
 
     if(strpos($buffer,'<pre>') !== false) 
 
     { 
 
      $replace = array(
 
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
 
       "/<\?php/"     => '<?php ', 
 
       "/\r/"      => '', 
 
       "/>\n</"     => '><', 
 
       "/>\s+\n</"     => '><', 
 
       "/>\n\s+</"     => '><', 
 
      ); 
 
     } 
 
     else 
 
     { 
 
      $replace = array(
 
       '/<!--[^\[](.*?)[^\]]-->/s' => '', 
 
       "/<\?php/"     => '<?php ', 
 
       "/\n([\S])/"    => '$1', 
 
       "/\r/"      => '', 
 
       "/\n/"      => '', 
 
       "/\t/"      => '', 
 
       "/ +/"      => ' ', 
 
      ); 
 
     } 
 
     $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer); 
 
     $response->setContent($buffer); 
 
     ini_set('zlib.output_compression', 'On'); // If you like to enable GZip, too! 
 
     return $response; 
 
    } 
 
}

+1

Wydaje się, że fragment kodu nie działa. – clearlight

2

Nie jest to bardzo dobre rozwiązanie do minify HTML middleware, jak można spędzają na nim dużo czasu procesora i działają na każde żądanie.

Zamiast tego lepiej jest użyć htmlmin pakiet (https://github.com/HTMLMin/Laravel-HTMLMin):

composer require htmlmin/htmlmin 
php artisan vendor:publish 

minifying HTML na poziomie szablonu ostrze i buforowanie go w magazynach powinny być znacznie bardziej skuteczne.