Script paginare cu filtrare si sortare

Ai o întrebare legată de PHP? Incercăm să îi găsim soluţie. Sau poate doar vrei să publici un cod interesant.

Moderatori: Zamolxe, Moderatori

clickymedia
Junior Member
Mesaje: 41
Membru din: Mie Iun 17, 2015 2:11 pm
Contact:

Script paginare cu filtrare si sortare

Mesajde clickymedia » Vin Ian 13, 2017 11:56 pm

Salut,

Am creat o clasa pentru afisare produse in categorie, filtrare produse, paginare si ordonare.

Asi vrea sa stiu daca este bine securizat acest script si daca se poate imbunatati timpul de incarcare deoarece la numar mare de produse si filtre crapa.

Baza de date:

products => id, title, url, filters
product_category => id, product_id, category_id
categories => id, parent, title, url

filters = [;]Brand[;]Nike[;][;]Culoare[;]Rosu[;][;]Marime[;]XXL[;]
url categorie = http://www.site.ext/nume-categorie/bran ... easc/pg-1/

-----------------------

Cod: Selectaţi tot

<?php

$CONF
['SITEPATH'] = "http://www.site.ext/";

function 
arrLink() {
    global 
$CONF;
    
$pregReplace preg_replace("@http://(.*)/@iUs""/"$CONF['SITEPATH']);
    
$strReplace str_replace($pregReplace'/'$_SERVER['REQUEST_URI']);
    
$parseUrl parse_url(str_replace(array('"'"'"), array(''''), urldecode($strReplace)), PHP_URL_PATH);
    return 
array_filter(explode("/"$parseUrl));
}

function 
cleanStr($str) {
    global 
$db;
    
$str = @trim($str);
    if (
get_magic_quotes_gpc()) {
        
$str stripslashes($str);
    } return 
$db->real_escape_string($str);
}

function 
sefUrl($string$sep '-') {
    
$sefurl preg_replace("/([^a-zA-Z0-9]+)/"$sep$string);
    
$sefurl trim($sefurl$sep);
    return 
strtolower($sefurl);
}

$link arrLink();

class 
browse {

    private 
$category_id;
    private 
$keywords;
    private 
$sql;
    private 
$limstart;
    private 
$limit;
    private 
$pagina_curenta;
    private 
$total_pagini;
    private 
$url;

    function 
__construct($limit 20$url$category_id 0) {

        global 
$CONF$db$link;

        
$this->limit $limit;
        
$this->category_id = (int) $category_id;

        
$this->url['path'] = $url;
        
$this->url['filters'] = array();
        
$this->url['sort'] = '';
        
$this->url['pg'] = '';

        if (isset(
$_GET['keywords'])) {

            
$this->keywords trim(strip_tags($_GET['keywords']));
        } else {

            
$this->keywords '';
        }

        if (
is_array($link) AND count($link) < 45) {

            foreach (
$link AS $k => $v) {

                
$array explode("-"$v);

                if (
count($array) == 2) {

                    
$_GET[$array[0]] = $array[1];
                }
            }
        }

        
$product_filters $this->product_filters();

        if (isset(
$_GET) AND is_array($_GET) AND count($_GET) < 45) {

            foreach (
$_GET AS $k => $v) {

                if (
array_key_exists($k$product_filters)) {

                    
$this->sql .= " AND a.filters LIKE '%[;]" cleanStr(str_ireplace('_'' '$_GET[$k]), true) . "[;]%'";

                    
$this->url['filters'][] = $k '-' sefUrl($_GET[$k], '_');
                    
$CONF['METATITLE'] .= ', ' sefUrl($k' ') . ' ' sefUrl($_GET[$k], ' ');
                }
            }
        } 
sort($this->url['filters']);

        if (isset(
$_GET['sort'])) {

            if (
$_GET['sort'] == 'iddesc') {

                
$this->sql .= " ORDER BY a.id DESC";
                
$this->url['sort'] = 'sort-iddesc/';
                
$CONF['METATITLE'] .= ', cele mai noi';
            } elseif (
$_GET['sort'] == 'priceasc') {

                
$this->sql .= " ORDER BY a.price ASC";
                
$this->url['sort'] = 'sort-priceasc/';
                
$CONF['METATITLE'] .= ', pret crescator';
            } elseif (
$_GET['sort'] == 'pricedesc') {

                
$this->sql .= " ORDER BY a.price DESC";
                
$this->url['sort'] = 'sort-pricedesc/';
                
$CONF['METATITLE'] .= ', pret descrescator';
            } else {

                
$this->sql .= " ORDER BY a.ordine ASC";
            }
        } else {

            
$this->sql .= " ORDER BY a.ordine ASC";
        }

        if (isset(
$_GET['pg']) AND is_numeric($_GET['pg']) AND $_GET['pg'] >= 2) {

            
$this->pagina_curenta = (int) $_GET['pg'];
            
$this->url['pg'] = 'pg-' $this->pagina_curenta '/';
            
$CONF['METATITLE'] .= ', pagina ' $this->pagina_curenta;
        } else {

            
$this->pagina_curenta 1;
        }

        
$url $this->url['path'];

        if (isset(
$this->url['filters'][0])) {

            
$url .= implode('/'$this->url['filters']) . '/';
        }

        
$url .= $this->url['sort'];
        
$url .= $this->url['pg'];

        if (
$url != trim($CONF['SITEPATH'], '/') . $_SERVER['REQUEST_URI']) {

            
header('Location: ' $url);
            exit;
        }

        if (
$this->category_id 1) {

            
$result $db->query("SELECT COUNT(a.id) FROM products a WHERE a.title LIKE '%" cleanStr($this->keywordstrue) . "%'" $this->sql);
        } else {

            
$result $db->query("SELECT COUNT(a.id) FROM products a, product_category b WHERE b.category_id='" $this->category_id "' AND b.product_id=a.id" $this->sql);
        }

        
$row $result->fetch_row();
        
$this->total_pagini ceil($row[0] / $this->limit);
        
$this->limstart = ($this->pagina_curenta 1) * $this->limit;
    }

    public function 
get_products() {

        if (
$this->category_id 1) {

            return @
DB::fetch_object("SELECT a.title FROM products a WHERE a.title LIKE '%" cleanStr($this->keywordstrue) . "%' " $this->sql " LIMIT " $this->limstart ", " $this->limit);
        } else {

            return @
DB::fetch_object("SELECT a.title FROM products a, product_category b WHERE b.category_id='" $this->category_id "' AND b.product_id=a.id " $this->sql " LIMIT " $this->limstart ", " $this->limit);
        }
    }

    public function 
get_pagination() {

        global 
$CONF;

        
$url $this->url['path'];

        if (isset(
$this->url['filters'][0])) {

            
$url .= implode('/'$this->url['filters']) . '/';
        } 
$url .= $this->url['sort'];

        echo 
"<ul class=\"pagination\">";

        for (
$x 1$x <= $this->total_pagini$x++) {

            if (
$x == $this->pagina_curenta) {

                echo 
"<li><span>$x</span></li>";
            } else {

                echo 
"<li><a href=\"{$url}pg-{$x}/\">$x</a></li>";
            }
        } echo 
"</ul>";
    }

    public function 
get_order_by() {

        global 
$CONF;

        
$url $this->url['path'];

        if (isset(
$this->url['filters'][0])) {

            
$url .= implode('/'$this->url['filters']) . '/';
        }

        echo 
"<ul class=\"filters-list\">";
        echo 
"<li class=\"" . ( (!isset($_GET['sort']) OR $_GET['sort'] == '' ) ? 'filter-checked' 'filter-unchecked' ) . "\"><a href=\"" $url "\">Ordonare initiala</a></li>";
        echo 
"<li class=\"" . ( ( isset($_GET['sort']) AND $_GET['sort'] == 'iddesc' ) ? 'filter-checked' 'filter-unchecked' ) . "\"><a href=\"" $url "sort-iddesc/\">Cele mai noi</a></li>";
        echo 
"<li class=\"" . ( ( isset($_GET['sort']) AND $_GET['sort'] == 'priceasc' ) ? 'filter-checked' 'filter-unchecked' ) . "\"><a href=\"" $url "sort-priceasc/\">Pret crescator</a></li>";
        echo 
"<li class=\"" . ( ( isset($_GET['sort']) AND $_GET['sort'] == 'pricedesc' ) ? 'filter-checked' 'filter-unchecked' ) . "\"><a href=\"" $url "sort-pricedesc/\">Pret descrescator</a></li>";
        echo 
"</ul>";
    }

    public function 
get_product_filters() {

        global 
$CONF;

        
$url $this->url['path'];

        if (isset(
$this->url['filters'][0])) {

            
$url .= implode('/'$this->url['filters']) . '/';
        } 
$url .= $this->url['sort'];

        
$product_filters $this->product_filters();

        foreach (
$product_filters AS $sefParam => $array) {

            echo 
"<div class=\"filters-subsection\">{$array['param_name']}</div><ul class=\"filters-list\">";

            if (isset(
$_GET[$sefParam])) {

                foreach (
$array['param_values'] AS $k => $v) {

                    if (
$_GET[$sefParam] == sefUrl($k'_')) {

                        echo 
"<li class=\"filter-checked\"><a href=\"" str_ireplace('/' $sefParam '-' $_GET[$sefParam], ''$url) . "\" style=\"color:red\">$k ($v)</a></li>";
                    }
                }
            } else {

                foreach (
$array['param_values'] AS $k => $v) {

                    
$arr = array();
                    
$arr $this->url['filters'];
                    
$arr[] = $sefParam '-' sefUrl($k'_');
                    
sort($arr);

                    echo 
"<li class=\"filter-unchecked\"><a href=\"" $this->url['path'] . implode('/'$arr) . '/' $this->url['sort'] . "\">$k ($v)</a></li>";
                    unset(
$this->url['filters']['100']);
                }
            }

            echo 
"</ul>";
        }
    }

    private function 
product_filters() {

        
$param_and_values = array();

        if (
$this->category_id 1) {

            @
$items = @DB::fetch_object("SELECT a.filters FROM products a WHERE a.title LIKE '%" cleanStr($this->keywordstrue) . "%' " $this->sql);
        } else {

            @
$items DB::fetch_object("SELECT a.filters FROM products a, product_category b WHERE b.category_id='" $this->category_id "' AND b.product_id=a.id " $this->sql);
        }

        if (
$items) {

            foreach (
$items AS $k => $v) {

                
$array explode("[;][;]"trim(trim($v->filters), '[;]'));

                foreach (
$array AS $k => $v) {

                    
$arr explode("[;]"$v);

                    if (isset(
$arr[1]) AND $arr[0] != '' AND $arr[1] != '') {

                        
$sef sefUrl($arr[0], '_');

                        
$param_and_values[$sef]['param_name'] = $arr[0];
                        
$param_and_values[$sef]['param_values'][] = $arr[1];
                    }
                }
            }
        }

        
uksort($param_and_values'strcasecmp');

        
$product_filters = array();

        foreach (
$param_and_values AS $k => $v) {

            
$product_filters[$k]['param_name'] = $param_and_values[$k]['param_name'];
            
$product_filters[$k]['param_values'] = array_count_values($param_and_values[$k]['param_values']);

            
uksort($product_filters[$k]['param_values'], 'strcasecmp');
        }

        return 
$product_filters;
    }

}

$item $db->query("SELECT id, title FROM `categories` WHERE url='" cleanStr($link[1]) . "'")->fetch_object();

if (!
$item) {

//404
} else {

    
$CONF['METATITLE'] = $item->title;

    
$browse = new browse(10$CONF['SITEPATH'] . $link[1] . '/'$item->id);
    
$get_products $browse->get_products();
}

if (!
$get_products) {

//404
} else {

    
$browse->get_order_by();
    
$browse->get_product_filters();

    foreach (
$get_products AS $k => $v) {
        echo 
$v->title "<br>";
    }

    
$browse->get_pagination();
}  


Recent am creat 1 site cu mobila second hand si canapele second hand in Bucuresti.

nevvermind
Senior Member
Mesaje: 1242
Membru din: Mar Iun 22, 2010 3:17 pm

Re: Script paginare cu filtrare si sortare

Mesajde nevvermind » Lun Ian 16, 2017 4:42 pm

N-ai depus niciun efort sa ne faci treaba usoara. Ai plesnit niste spaghetti carbonara in editor si gata. Nici macar n-ai indentat codul. Noi de ce ne-am pierde timpul sa-ti face review?

Dar iti dau un sfat: Nu mai folosi globale (global, $_SERVER, magic_quotes etc.). PHP-ul ala arata foarte vechi.

Nu te mai obosi cu paginare si filtrare in mysql; e de sec. 19. Foloseste ElasticSearch sau Solr.

PS: Sa nu crezi ca o clasa inseamna OOP. Codul e cat se poate de procedural.
Facusi un canal de php pe freenode - ##php-ro : https://webchat.freenode.net/

clickymedia
Junior Member
Mesaje: 41
Membru din: Mie Iun 17, 2015 2:11 pm
Contact:

Re: Script paginare cu filtrare si sortare

Mesajde clickymedia » Joi Ian 19, 2017 12:38 pm

Imi poti da te rog 1 exemplu de clasa OOP pentru paginare , filtrare si sortare pentru a studia.
Recent am creat 1 site cu mobila second hand si canapele second hand in Bucuresti.

nevvermind
Senior Member
Mesaje: 1242
Membru din: Mar Iun 22, 2010 3:17 pm

Re: Script paginare cu filtrare si sortare

Mesajde nevvermind » Joi Ian 19, 2017 5:12 pm

Facusi un canal de php pe freenode - ##php-ro : https://webchat.freenode.net/

Avatar utilizator
vectorialpx
Senior Member
Mesaje: 4830
Membru din: Mar Mar 01, 2005 9:48 am
Localitate: Bucuresti
Contact:

Re: Script paginare cu filtrare si sortare

Mesajde vectorialpx » Mie Ian 25, 2017 11:03 pm

Ca un sfat, pentru ceea ce gasesti pe packagist.org ar fi indicat sa folosesti un composer.
Multe clase pot fi luate si independent dar composerul iti face un autoload frumos.

Asa cum ti-a sugerat si nevvermind, ar trebui sa faci o refactorizare serioasa.
Iti recomand un update la PHP 5.6 (cel putin) si vei scapa de get_magic_quotes_gpc (trebuie, ca nu mai e suportat) si de mylsq - treci pe PDO si prepared statements (gasesti exemple prin manual - http://php.net/manual/ro/pdo.prepare.php)

Referitor la cod, vezi ca LIKE "%stuff%" este foarte costisitor si vad ca il folosesti din plin.
Pune macar niste conditii care sa evite atunci cand este posibil.

Si, pune-ti indecsi pe tabele, daca nu ai (google "mysql index recommendations").

Referitor la securitate, scapa de extensia mysql si treci pe PDO, nu o sa mai ai probleme
(atentie, si PDO-ul il poti folosi gresit - trebuie folosit cu prepared statements)


Înapoi la “Cod PHP”

Cine este conectat

Utilizatori ce ce navighează pe acest forum: Niciun utilizator înregistrat și 2 vizitatori