2015-07-08 3 views
5

Questo è il mio primo post su questo sito, e mentre ho passato i 2 minuti. per favore guidami nella giusta direzione se questa domanda sembra fuori posto o non in linea con le regole del sito.Paging sul lato server con MySQL, PHP e AngularJS

Ho creato/modificato uno script PHP (sotto), che mette una tabella MySQL in un formato JSON. Sto lavorando con oltre 700.000 righe, quindi ho pensato che la mia migliore scommessa fosse usare l'impaginazione.

<?php 
require('connection.php'); 
header('Content-Type: application/json'); 

ini_set("max_execution_time", "-1"); 
ini_set("memory_limit", "-1"); 
ignore_user_abort(true); 
set_time_limit(0); 

// PortalActivity Table - JSON Creation 

$limit = $_POST['limit']; //the pagesize 
$start = $_POST['start']; //Offset 
$dir = $_POST['dir']; // DESC or ASC 
$sort = $_POST['sort'];// the column 

switch ($sort) { 
    case "CallerPhoneNum": $orderby = "CallerPhoneNum"; break; 
    case "Carrier": $orderby = "Carrier"; break; 
    case "TotalLookups": $orderby = "TotalLookups"; break; 
    case "TotalBlocks": $orderby = "TotalBlocks"; break; 
    case "TotalComplaints": $orderby = "TotalComplaints"; break; 
    case "ActivityRanking": $orderby = "ActivityRanking"; break; 
    case "CallerType": $orderby = "CallerType"; break; 
} 

$sql = "SELECT COUNT(*) AS count FROM portal.PortalActivity"; 
$result = $conn->query($sql); 
$row = $result->fetch(PDO::FETCH_ASSOC); 
$count = $row['count']; 

$query = "SELECT * FROM portal.PortalActivity ORDER BY $orderby $dir LIMIT $start, $limit"; 

$result = $conn->query($query); 

while ($row = $result->fetch(PDO::FETCH_ASSOC)) { 
    $PortalActivity[] = array(
     'CallerPhoneNum' => $row['CallerPhoneNum'], 
     'Carrier' => $row['Carrier'], 
     'TotalLookups' => $row['TotalLookups'], 
     'TotalBlocks' => $row['TotalBlocks'], 
     'TotalComplaints' => $row['TotalComplaints'], 
     'ActivityRanking' => $row['ActivityRanking'], 
     'CallerType' => $row['CallerType'] 
     ); 
} 

$myData = array('PortalActivity' => $PortalActivity, 'totalCount' => $count); 

echo json_encode($myData); 


?> 

Il codice mi dà i dati di tutte le righe e un conteggio totale delle righe.

Ho un framework di bootstrap che utilizza AngularJS. Vorrei mettere i dati in una tabella usando l'impaginazione. Pertanto, quando un utente fa clic su "Avanti" o fa clic su una nuova pagina, il server carica solo i record necessari per pagina (10, 25, 50 o 100).

So che ho bisogno di: 1.) Creare il paging nel mio controller 2.) Ottenere i dati dal mio controller al mio file php in modo che possa ricevere correttamente i giusti limiti e offset. 3.) Visualizza questo a mio modo di vedere

Sono nuovo in queste lingue e mi sono ritrovato in una crisi di tempo per ottenere questa demo. Come posso far funzionare questi file insieme (PHP, JS e HTML) per visualizzare correttamente il paging di cui ho bisogno?

Questo è il mio controller originale che sta semplicemente visualizzando i dati in una vista filtrata. Come mostrato di seguito, sto usando $ http.get per ottenere i dati. Questo controller funziona, ma sto bisogno di prendere un ulteriore passo avanti con la paginazione:

app.controller('counterCtrl', function($scope, $http, $filter, filterFilter) { 

    $scope.Unknown = 'UK'; 
    $scope.NonProfit = 'NP'; 
    $scope.Political = 'PL'; 
    $scope.Prison = 'PR'; 

    $scope.getCount = function(strCat) { 
     return filterFilter($scope.items, {CallerType:strCat}).length; 
    } 

    $http.get("http://xx.xxx.xx.xx/php/jsoncreatePA.php") 
     .success(function (data) { 
      $scope.items = data.PortalActivity; 
      }); 
}) 

Questa è parte della vista che ho creato con il controller di lavoro:

<section id="main-content" class="animated fadeInRight"> 
    <div class="row"> 
     <div class="col-md-12"> 
       <div class="panel panel-default"> 
        <div class="panel-heading"> 
        <h3 class="panel-title">Unknown</h3> 

        </div> 
       <div class="panel-body"> 
       <table id="example" class="table table-striped table-bordered" datatable="" cellspacing="0" width="100%"> 
        <thead> 
         <tr> 
          <th>Caller Number</th> 
          <th>Total Lookups</th> 
          <th>Total Blocks</th> 
          <th>Total Complaints</th> 
          <th>Activity Percentage</th> 
         </tr> 
        </thead> 

        <tbody> 
         <tr data-ng-repeat = "x in items | filter: { CallerType : Unknown }"> 
          <td>{{x.CallerPhoneNum}}</td> 
          <td>{{x.TotalLookups}}</td> 
          <td>{{x.TotalBlocks}}</td> 
          <td>{{x.TotalComplaints}}</td> 
          <td>{{x.ActivityRanking}}</td> 
         </tr> 
        </tbody> 
       </table> 
       </div> 
      </div> 
     </div> 
    </div> 
</section> 
+1

Questo è tangente alla tua domanda, ma il vostro PHP è seriamente vulnerabile a (https://en.wikipedia.org/wiki/SQL_injection), attacchi di SQL injection []. È necessario prendere in seria considerazione la possibilità di stabilire una connessione al database usando [PDO] (http://php.net/manual/en/intro.pdo.php) API e creazione di query parametrizzate tramite [istruzioni preparate] (http://php.net/manual/en/pdo.prepared-statements.php). –

+0

Grazie per il tuo commento. Ho fatto un tentativo di usare PDO. L'esempio che stavo leggendo da mysqli usato. Sto ancora imparando come convertire questo in PDO. Esaminerò il tuo link sulle dichiarazioni preparate e aggiornerò di conseguenza. – ChaiBunnii

risposta

1

Per chiunque abbia incontrato questa domanda, ho trovato la risposta a questo problema. Prendete nota, come il Sig. DOS ha menzionato in un commento precedente, questo è vulnerabile all'iniezione SQL e modificherò il codice PHP più tardi. Ma per ora questo mi dà quello di cui ho bisogno e forse aiuterà gli altri lungo la strada.

Ci sono stati alcuni cambiamenti nella mia PHP che avevo bisogno di fare:

<?php 
require('connection.php'); 
header('Content-Type: application/json'); 

// NetworkActivity Table - JSON File Creation 

$pagenum = $_GET['page']; 
$pagesize = $_GET['size']; 
$offset = ($pagenum - 1) * $pagesize; 
$search = $_GET['search']; 

if ($search != "") { 
    $where = "WHERE Carrier LIKE '%" . $search . "%'"; 
} else { 
    $where = ""; 
} 

$sql = "SELECT COUNT(*) AS count FROM PortalActivity $where"; 
$result = $conn->query($sql); 
$row = $result->fetch(PDO::FETCH_ASSOC); 
$count = $row['count']; 

$query = "SELECT * FROM portal.PortalActivity $where ORDER BY Carrier, CallerPhoneNum LIMIT $offset, $pagesize"; 

$result = $conn->query($query); 

while ($row = $result->fetch(PDO::FETCH_ASSOC)) { 
    $PortalActivity[] = array(
     'CallerPhoneNum' => $row['CallerPhoneNum'], 
     'Carrier' => $row['Carrier'], 
     'TotalLookups' => $row['TotalLookups'], 
     'TotalBlocks' => $row['TotalBlocks'], 
     'TotalComplaints' => $row['TotalComplaints'], 
     'ActivityRanking' => $row['ActivityRanking'], 
     'CallerType' => $row['CallerType'] 
     ); 
} 

$myData = array('PortalActivity' => $PortalActivity, 'totalCount' => $count); 

echo json_encode($myData); 

?> 

Per quanto riguarda come il controller, abbiamo duplicato il paging e ottenuto il PHP $ _GET dal $ http.get nell'URL con pagina, dimensione e ricerca.

// Portal Activity Table Control 
app.controller('activityTableCtrl', function($scope, $http) { 

    $scope.currentPage = 1; 
    $scope.totalItems = 0; 
    $scope.pageSize = 10; 
    $scope.searchText = ''; 
    getData(); 

    function getData() { 
    $http.get('http://xx.xxx.xx.xx/php/jsoncreatePA.php?page=' + $scope.currentPage + '&size=' + $scope.pageSize + '&search=' + $scope.searchText) 
     .success(function(data) { 
      $scope.activity = []; 
      $scope.totalItems = data.totalCount; 
      $scope.startItem = ($scope.currentPage - 1) * $scope.pageSize + 1; 
      $scope.endItem = $scope.currentPage * $scope.pageSize; 
      if ($scope.endItem > $scope.totalCount) {$scope.endItem = $scope.totalCount;} 
      angular.forEach(data.PortalActivity, function(temp){ 
       $scope.activity.push(temp); 
      }); 
     }); 
    } 

    $scope.pageChanged = function() { 
     getData(); 
    } 
    $scope.pageSizeChanged = function() { 
     $scope.currentPage = 1; 
     getData(); 
    } 
    $scope.searchTextChanged = function() { 
     $scope.currentPage = 1; 
     getData(); 
    } 
}) 

Infine, abbiamo modificato la vista per adattare i controlli di paging.

<section id="main-content" class="animated fadeInRight"> 
    <div class="row"> 
     <div class="col-md-12" ng-controller="activityTableCtrl"> 
      <div class="panel panel-default"> 
       <div class="panel-heading"> 
       <h3 class="panel-title">Unknown</h3> 
       </div> 
       <div class="panel-body"> 
       <!-- TOP OF TABLE: shows page size and search box --> 
       <div class="dataTables_wrapper form-inline" role="grid"> 
       <div class="row"> 
        <div class="col-sm-6"> 
         <div class="dataTables_length" id="example_length"> 
          <label> 
          <select name="example_length" aria-controls="example" class="form-control input-sm" ng-model="pageSize" ng-change="pageSizeChanged()"> 
           <option value="10">10</option> 
           <option value="25">25</option> 
           <option value="50">50</option> 
           <option value="100">100</option> 
          </select> records per page</label> 
         </div> 
        </div> 
        <div class="col-sm-6"> 
         <div id="example_filter" class="dataTables_filter"> 
          <label>Search:<input type="search" class="form-control input-sm" aria-controls="example" ng-model="searchText" ng-change="searchTextChanged()"></label> 
         </div> 
        </div> 
       </div>       

       <!-- DATA TABLE: shows the results --> 
       <!-- <table id="example" class="table table-striped table-bordered" datatable="" cellspacing="0" width="100%"> --> 
       <table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%"> 
       <thead> 
        <tr> 
         <th>Caller Number</th> 
         <th>Total Lookups</th> 
         <th>Total Blocks</th> 
         <th>Total Complaints</th> 
         <th>Activity Percentage</th> 
        </tr> 
       </thead> 

       <tbody> 
        <tr ng-repeat = "x in activity"> 
         <td>{{x.CallerPhoneNum}}</td> 
         <td>{{x.TotalLookups}}</td> 
         <td>{{x.TotalBlocks}}</td> 
         <td>{{x.TotalComplaints}}</td> 
         <td>{{x.ActivityRanking}}</td> 
        </tr> 
       </tbody> 
       </table> 

       <!-- BOTTOM OF TABLE: shows record number and pagination control --> 
       <div class="row"> 
        <div class="col-sm-6"> 
         <div class="dataTables_info" ole="alert" aria-live="polite" aria-relevant="all">Showing {{startItem}} to {{endItem}} of {{totalItems}} entries</div> 
        </div> 
        <div class="col-sm-6"> 
         <div class="dataTables_paginate paging_simple_numbers"> 
         <pagination total-items="totalItems" ng-model="currentPage" ng-change="pageChanged()" items-per-page="pageSize" max-size="3" boundary-links="true" rotate="false" ></pagination> 
         </div> 
        </div> 
       </div>      
       </div> 
       </div> 
      </div> 
     </div> 
    </div> 
</section> 
+0

Ho usato il tuo codice e tutto sembra funzionare senza problemi a parte i pulsanti di impaginazione che non appaiono affatto. Più nello specifico, non ottengo nulla per questa parte del codice:

. Mi manca qualche biblioteca? – fitziano

+0

Non riesco a capire perché il mio JSON non è valido, sto ricevendo questo errore 'SyntaxError: Token inaspettato in JSON alla posizione 0', ho controllato gli spazi vuoti, e non trovo, non so perché Mi sto prendendo questo, per favore aiutami –

0

Puoi Facilmente paging utilizzando lato client causa se utilizzare lato server ogni numero di pagina pulsante clic su aggiornamento della pagina e ottenere database del modulo dati. Ora sembra di qualità completa. Quindi, risolvi questo lavoro di qualità usa la tabella di dati jQuery.

+0

Non stai rischiando di interrogare un sacco di dati inutili e anche "pesanti" dal database solo per passarlo al cliente per fare il sollevamento pesi? –

1

Spero che questo sia utile.

Angular js Searching Sorting and Pagination in Angular js ID Country Capital {{country.id}} {{country.country}} {{country.capital}}

<?php 

$DB_HOST = '127.0.0.1'; 
$DB_USER = 'root'; 
$DB_PASS = ''; 
$DB_NAME = 'YOUR DATABASE NAME'; 
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); 

$pageSize = (isset($_GET['pageSize']) ? $_GET['pageSize'] : ""); 
$currentPage = (isset($_GET['currentPage']) ? $_GET['currentPage'] : 1); 
$offset = ($currentPage -1) * $pageSize; 
$sql = "select * from countries"; 
$count_set = $mysqli->query($sql) or die($mysqli->error . __LINE__); 

$query = "select distinct id,country,capital from countries LIMIT $offset,$pageSize"; 
$result = $mysqli->query($query) or die($mysqli->error . __LINE__); 



$arr = array(); 
if ($result->num_rows > 0) { 
    while ($row = $result->fetch_assoc()) { 
     $arr[] = $row; 
    } 
} 
$myData = array('result' => $arr, 'totalItems' => $count_set->num_rows); 

echo $json_response = json_encode($myData); 
?> 


app.js 

var app = angular.module('angularjsTable', ['angularUtils.directives.dirPagination']); 
app.controller('listdata', function ($scope, $http) { 
// var vm = this; 
    $scope.countries = []; //declare an empty array 
    $scope.currentPage = 1; // initialize page no to 1 
    $scope.totalItems = 0; 
    $scope.pageSize = 10; //this could be a dynamic value from a drop down 

    $scope.getData = function (pageno) { // This would fetch the data on page change. 
     //In practice this should be in a factory. 
     $scope.countries = []; 
     $http.get("your host path/your file name.php?pageSize=" + $scope.pageSize + "&currentPage=" + pageno).success(function (response) { 
      //ajax request to fetch data into vm.data 
      $scope.countries = response.result; // data to be displayed on current page. 
      $scope.totalItems = response.totalItems; // total data count. 
     }); 
    }; 
    $scope.getData($scope.currentPage); 
// 
    $scope.sort = function (keyname) { 
     $scope.sortBy = keyname; //set the sortBy to the param passed 
     $scope.reverse = !$scope.reverse; //if true make it false and vice versa 
    } 
});