Related
I have 70,000 rows in a MySQL table. I am trying to upload them in Firebase via import JSON. I have exported the table into JSON format. The output was an array. e.g., JSON is as follows -
[
{"question_id":"99","question":"What is your name?"},
{"question_id":"200","question":"What do you do?"}
]
For the correct use of Firebase in mobile apps, I need to import this JSON data as an object, along with GUID like following -
{
"-Lf64AvZinbjvEQLMzGc" : {
"question_id" : 99,
"question" : "What is your name?"
},
"-Lf64AvZinbjvEQLMzGd" : {
"question_id" : 200,
"question" : "What do you do?"
}
}
Since the number of rows are 70,000 (JSON file of this data is 110 MB); inserting individually into Firebase is not possible. So I was trying for a way to generate 70,000 GUID and editing the JSON file to add each one before every object. But, I am stuck at both places. I am using the following class (PushId.php) for generating GUID -
<?php
/**
* Fancy ID generator that creates 20-character string identifiers with the following properties:
*
* 1. They're based on timestamp so that they sort *after* any existing ids.
* 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.
* 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).
* 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the
* latter ones will sort after the former ones. We do this by using the previous random bits
* but "incrementing" them by 1 (only in the case of a timestamp collision).
*/
class PushId
{
/**
* Modeled after base64 web-safe chars, but ordered by ASCII.
*
* #var string
*/
const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
/**
* Timestamp of last push, used to prevent local collisions if you push twice in one ms.
*
* #var int
*/
private static $lastPushTime = 0;
/**
* We generate 72-bits of randomness which get turned into 12 characters and appended to the
* timestamp to prevent collisions with other clients. We store the last characters we
* generated because in the event of a collision, we'll use those same characters except
* "incremented" by one.
*
* #var array
*/
private static $lastRandChars = [];
/**
* #return string
*/
public static function generate()
{
$now = (int) microtime(true) * 1000;
$isDuplicateTime = ($now === static::$lastPushTime);
static::$lastPushTime = $now;
$timeStampChars = new SplFixedArray(8);
for ($i = 7; $i >= 0; $i--) {
$timeStampChars[$i] = substr(self::PUSH_CHARS, $now % 64, 1);
// NOTE: Can't use << here because javascript will convert to int and lose the upper bits.
$now = (int) floor($now / 64);
}
static::assert($now === 0, 'We should have converted the entire timestamp.');
$id = implode('', $timeStampChars->toArray());
if (!$isDuplicateTime) {
for ($i = 0; $i < 12; $i++) {
$lastRandChars[$i] = floor(rand(0, 64));
}
} else {
// If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.
for ($i = 11; $i >= 0 && static::$lastRandChars[$i] === 63; $i--) {
static::$lastRandChars[$i] = 0;
}
static::$lastRandChars[$i]++;
}
for ($i = 0; $i < 12; $i++) {
$id .= substr(self::PUSH_CHARS, $lastRandChars[$i], 1);
}
static::assert(strlen($id) === 20, 'Length should be 20.');
return $id;
}
/**
* #param bool $condition
* #param string $message
*/
private static function assert($condition, $message = '')
{
if ($condition !== true) {
throw new RuntimeException($message);
}
}
}
Following is the PHP code that I wrote to generate 70,000 GUID but it showed error (while the same code is working if I use it to generate 1 GUID only)
require_once('PushId.php');
$vars = new PushId();
$my_file = 'TheGUIDs.txt';
$handle = fopen($my_file, 'w') or die('Cannot open file: '.$my_file);
$i=1;
while($i <= 70000){
$data = $vars->generate();
fwrite($handle, $data);
echo $data;
$i++;
}
fclose($handle);
Edit -1
The error I am getting in generating GUID is -
Notice: Undefined offset: 11 in C:\wamp64\www\firebase-json\PushId.php on line 65
Notice: Undefined variable: lastRandChars in C:\wamp64\www\firebase-json\PushId.php on line 71
The first GUID is complete, e.g. in last run I got -Lf8WPlkkNTUjYkIP4WT, but then I got incomplete GUID -Lf8WPlk------------
First, you forgot to prepend static:: to $lastRandChars in some places:
for ($i = 0; $i < 12; $i++) {
$lastRandChars[$i] = floor(rand(0, 64)); // << here
}
for ($i = 0; $i < 12; $i++) {
$id .= substr(self::PUSH_CHARS, $lastRandChars[$i], 1); // << and here
}
Next:
When incrementing previous ID, you missed that you should increment not only last char, but all previous chars as well if they are more than 63.
Sample IDs sequence:
...
-Lf64AvZinbjvEQLMzGw
-Lf64AvZinbjvEQLMzGx
-Lf64AvZinbjvEQLMzGy
-Lf64AvZinbjvEQLMzGz
-Lf64AvZinbjvEQLMzH- <<< on this step last char is reset, and previous one is incremented by one
-Lf64AvZinbjvEQLMzH0
-Lf64AvZinbjvEQLMzH1
...
-Lf64AvZinbjvEQLMzzw
-Lf64AvZinbjvEQLMzzx
-Lf64AvZinbjvEQLMzzw
-Lf64AvZinbjvEQLMzzz
-Lf64AvZinbjvEQLN--- <<< on this step last three chars are reset, and previous one is incremented by one
-Lf64AvZinbjvEQLN--0
-Lf64AvZinbjvEQLN--1
...
Modified increment logic:
// If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.
for ($i = 11; $i >= 0; $i--) {
$previousIncremented = false;
for ($j = $i; $j > 0; $j--) {
if (!$previousIncremented) {
static::$lastRandChars[$j]++;
}
if (static::$lastRandChars[$j] == 64) {
static::$lastRandChars[$j] = 0;
static::$lastRandChars[$j - 1]++;
$previousIncremented = true;
} else {
break 2;
}
}
}
I'm working on a class whose purpose is to restrict users to making only 10 requests within any 30 second period. It utilizes a file to maintain IP addresses, last request time. and the number of tries they've made. The problem is that, no matter what I try, I can't get the filesize. I've tried using clearstatcache(), and I've tried using a function I found in the comments on the filesize() page of the PHP manual.
Here's the code, in it's current debugging state.
// Makes sure user can only try to generate a coupon x number of times over x amount of seconds
class IpChecker{
const WAIT_TIME = 30; //seconds until user can try again
const MAX_TRIES = 10; // maximum tries
const COUPON_IP = 0;
const COUPON_TIME = 1;
const COUPON_TRIES = 2;
private $ip_data;
private $path;
private $fh;
private $safe;
public function __construct(){
clearstatcache();
$this->path = realpath(dirname(__FILE__))."/ips/.ips";
$this->fh = fopen($this->path,'w+');
$this->filesize = $this->realfilesize($this->fh);
echo "fs: ".$this->filesize; exit;
$this->getIPs();
$this->checkIP();
$this->logRequest();
fclose($this->fh);
$this->safe || die(json_encode("You have exhausted all available tries. Please try again later."));
}
private function logRequest(){
$str = "";
foreach($this->ip_data as $data){
foreach($data as $col){
if(self::WAIT_TIME < (time() - $col[self::COUPON_TIME])) $str .= $col."\t";
}
$str = rtrim($str, '\t');
$str .= "\n";
}
$str = rtrim($str, '\n');
try{
$fw = fwrite($this->fh, $str) || die(json_encode("Unable to check IP"));
}catch(Exception $e){
die(json_encode($e));
}
}
private function checkIP(){
$IP = $_SERVER['REMOTE_ADDR'];
$TIME = time();
$safe = true;
$user_logged = false;
echo "<pre>"; var_dump($this->ip_data); exit;
foreach($this->ip_data as $key=>$data){
echo "<prE>"; var_dump($data); exit;
// if($data[$key][self::COUPON_IP] == $IP){
// $user_logged = true;
// if(
// (($TIME - $data[$key][self::COUPON_TIME]) < self::WAIT_TIME) ||
// (self::MAX_TRIES >= $data[$key][self::COUPON_TRIES])
// ) $safe = false;
// $this->ip_data[$key][self::COUPON_TRIES] = $this->ip_data[$key][self::COUPON_TRIES]+1;
// $this->ip_data[$key][self::COUPON_TIME] = $TIME;
// }
}
if(!$user_logged){
die("user not logged");
$this->ip_data[] = array(
self::COUPON_IP => $IP,
self::COUPON_TIME => $TIME,
self::COUPON_TRIES => 1
);
}
$this->safe = $safe;
}
private function getIPs(){
$IP_DATA = array();
echo file_get_contents($this->path); exit;
// this always returns 0.
$size = filesize($this->path);
echo "filesize: ".$size; exit;
if($size){
$IPs = fread($this->fh,$size);
$IP_ARR = explode("\n",$IPs);
foreach($IP_ARR as $line) $IP_DATA[] = explode("\t",$line);
}
$this->ip_data = $IP_DATA;
}
// Copied from the comments in the PHP Manual for filesize()
public function realfilesize($fp) {
$return = false;
if (is_resource($fp)) {
if (PHP_INT_SIZE < 8) {
// 32bit
if (0 === fseek($fp, 0, SEEK_END)) {
$return = 0.0;
$step = 0x7FFFFFFF;
while ($step > 0) {
if (0 === fseek($fp, - $step, SEEK_CUR)) {
$return += floatval($step);
} else {
$step >>= 1;
}
}
}
} elseif (0 === fseek($fp, 0, SEEK_END)) {
// 64bit
$return = ftell($fp);
}
}
return $return;
}
}
How can I get the real filesize? I'm on PHP 5.2.
I wasn;t able to figure out what was wrong with my code, if anythign, but I worked around it like this:
/**
* Makes sure user can only access a given page
* x number of times over x amount of seconds.
* If multiple instances of this class are used, the $namespace
* properties for each should be unique.
* Default wait time is 90 seconds while default request limit
* is 10 tries.
*
* -+ Usage +-
* Just create the object with any parameters, no need to assign,
* just make sure it's initialized at the top of the page:
* new RequestThrottler;
*
* -+- Parameters -+-
* null RequestThrottler ( [ string $namespace [, int $WaitTime [, int $MaxTries ] ] ] )
*/
class RequestThrottler{
// settings
private static $WAIT_TIME; // seconds until count expires
private static $MAX_TRIES; // maximum tries
// used to keep session variables unique
// in the event that this class is used in multiple places.
private $namespace;
// for debugging
const DBG = false;
// array index constants
const _TIME = 0;
const _TRIES = 1;
// defines whether or not access is permitted
private $safe;
// seconds until reset
private $secs;
/**
* -+- Constructor -+-
* #param String $namespace - A unique prefix for SESSION data
* #param Int $WaitTime - Total seconds before user can try again
* #param Int $MaxTries - Total tries user can make until their request is denied
*/
public function __construct($namespace='Throttler', $WaitTime=90, $MaxTries=10){
// make sure a session is available
if(!headers_sent() && !isset($_SESSION)) session_start();
if(!isset($_SESSION)) die(json_encode("No session available"));
// save settings
$this->namespace = $namespace;
self::$MAX_TRIES = $MaxTries;
self::$WAIT_TIME = $WaitTime;
// do the footwork
$this->checkHistory();
// if set to debug mode, print a short helpful string
if(self::DBG) die(json_encode(
"You are ".($this->safe ? 'SAFE' : 'NOT SAFE')."! "
. "This is try number {$_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES]} of ".self::$MAX_TRIES.". "
. $this->secs." seconds since last attempt. "
. (self::$WAIT_TIME - $this->secs)." seconds until reset."
));
// if not safe, kill the script, show a message
$this->safe || die(json_encode("You're going too fast. Please try again in ".(self::$WAIT_TIME - $this->secs)." seconds."));
}
/**
* -+- checkHistory -+-
* Does the footwork to determine whether
* or not to throttle the current user/request.
*/
private function checkHistory(){
$TIME = time();
$safe = true;
// make sure session is iniitialized
if( !isset($_SESSION[$this->namespace.'_ATTEMPTS']) ||
!isset($_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES]) ||
!isset($_SESSION[$this->namespace.'_ATTEMPTS'][self::_TIME]) )
$_SESSION[$this->namespace.'_ATTEMPTS'] = array(
self::_TIME =>$TIME,
self::_TRIES => 1
);
else $_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES] =
$_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES]+1;
// get seconds since last attempt
$secondSinceLastAttempt = $TIME - $_SESSION[$this->namespace.'_ATTEMPTS'][self::_TIME];
// reset the counter if the wait time has expired
if($secondSinceLastAttempt > self::$WAIT_TIME){
$_SESSION[$this->namespace.'_ATTEMPTS'][self::_TIME] = $TIME;
$_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES] = 1;
$secondSinceLastAttempt = 0;
}
// finally, determine if we're safe
if($_SESSION[$this->namespace.'_ATTEMPTS'][self::_TRIES] >= self::$MAX_TRIES) $safe=false;
// log this for debugging
$this->secs = $secondSinceLastAttempt;
// save the "safe" flag
$this->safe = $safe;
}
}
I'm using xampp 1.77 version, codeigniter 1.7.2 with flexigrid.
I follow step by step this tutorial https://gembelzillonmendonk.wordpress.com/2010/06/28/flexigrid-and-codeigniter-with-advanced-searching-with-example/#comment-353 but I don't understand which code must have flexigrid.php in CI_Folder\system\application\controllers\flexigrid.php.
My flexigrid.php code is this:
<?php
class Flexigrid extends Controller {
function Flexigrid ()
{
parent::Controller();
$this->load->helper('flexigrid');
}
function index()
{
//ver lib
$this->load->model('ajax_model');
$records = $this->ajax_model->get_select_countries();
$options = '';
foreach( $records as $v ) {
$options .= $v['name'] . ';';
}
$options = substr($options, 0, -1);
/*
* 0 - display name
* 1 - width
* 2 - sortable
* 3 - align
* 4 - searchable (2 -> yes and default, 1 -> yes, 0 -> no.)
*/
$colModel['id'] = array('ID',40,TRUE,'center',2);
$colModel['iso'] = array('ISO',40,TRUE,'center',0);
$colModel['name'] = array('Name',180,TRUE,'left',1);
$colModel['printable_name'] = array('Printable Name',120,TRUE,'left',1,'options' => array('type' => 'date'));
$colModel['iso3'] = array('ISO3',130, TRUE,'left',1, 'options' => array('type' => 'select', 'edit_options' => $options));
$colModel['numcode'] = array('Number Code',80, TRUE, 'right',1, 'options' => array('type' => 'select', 'edit_options' => ":All;AND:AND;KK:KK;RE:RE"));
$colModel['actions'] = array('Actions',80, FALSE, 'right',0);
/*
* Aditional Parameters
*/
$gridParams = array(
'width' => 'auto',
'height' => 400,
'rp' => 15,
'rpOptions' => '[10,15,20,25,40]',
'pagestat' => 'Displaying: {from} to {to} of {total} items.',
'blockOpacity' => 0.5,
'title' => 'Hello',
'showTableToggleBtn' => true
);
/*
* 0 - display name
* 1 - bclass
* 2 - onpress
*/
$buttons[] = array('Delete','delete','test');
$buttons[] = array('separator');
$buttons[] = array('Select All','add','test');
$buttons[] = array('DeSelect All','delete','test');
$buttons[] = array('separator');
//Build js
//View helpers/flexigrid_helper.php for more information about the params on this function
$grid_js = build_grid_js('flex1',site_url("/ajax"),$colModel,'id','asc',$gridParams,$buttons);
$data['js_grid'] = $grid_js;
$data['version'] = "0.36";
$data['download_file'] = "Flexigrid_CI_v0.36.rar";
$this->load->view('flexigrid',$data);
}
function example ()
{
$data['version'] = "0.36";
$data['download_file'] = "Flexigrid_CI_v0.36.rar";
$this->load->view('example',$data);
}
}
?>
When i type http://127.0.0.1/flexiadvanced/index.php/flexigrid browser give me a error:
Fatal error: Call to a member function query() on a non-object in C:\xampp\htdocs\flexiadvanced\system\application\models\ajax_model.php on line 34
this is the code of ajax_model.php
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Eye View Design CMS module Ajax Model
*
* PHP version 5
*
* #category CodeIgniter
* #package EVD CMS
* #author Frederico Carvalho
* #copyright 2008 Mentes 100Limites
* #version 0.1
*/
class Ajax_model extends Model
{
/**
* Instanciar o CI
*/
public function Ajax_model()
{
parent::Model();
$this->CI =& get_instance();
}
public function get_select_countries()
{
//Select table name
$table_name = "country";
//Build contents query
$separator = (string) ',';
//$this->db->select('concat(iso3, concat('. addcslashes($separator) .', iso3))')->from($table_name);
$query = $this->db->query("select concat(iso3, concat(':', iso3)) as name from country where iso3 is not null");
//Get contents
return $query->result_array();
}
public function get_countries()
{
//Select table name
$table_name = "country";
//Build contents query
$this->db->select('id,iso,name,printable_name,iso3,numcode')->from($table_name);
$this->CI->flexigrid->build_query();
//Get contents
$return['records'] = $this->db->get();
//echo $this->db->last_query();
//Build count query
$this->db->select('count(id) as record_count')->from($table_name);
$this->CI->flexigrid->build_query(FALSE);
$record_count = $this->db->get();
$row = $record_count->row();
//Get Record Count
$return['record_count'] = $row->record_count;
//Return all
return $return;
}
/**
* Remove country
* #param int country id
* #return boolean
*/
public function delete_country($country_id)
{
$delete_country = $this->db->query('DELETE FROM country WHERE id='.$country_id);
return TRUE;
}
}
?>
My database is called country and database table is called also country. This is information in CI_Folder\system\application\config
$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "";
$db['default']['database'] = "country";
$db['default']['dbdriver'] = "mysql";
Can you help me to write correct code inside flexigrid.php?
This is my code for CI_Folder\system\application\helpers\flexigrid_helper.php but is correct?
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Flexigrid CodeIgniter implementation
*
* PHP version 5
*
* #category CodeIgniter
* #package Flexigrid CI
* #author Frederico Carvalho (frederico#eyeviewdesign.com)
* #version 0.3
* Copyright (c) 2008 Frederico Carvalho (http://flexigrid.eyeviewdesign.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*/
if (! function_exists('build_grid_js'))
{
/**
* Build Javascript to display grid
*
* #param grid id, or the div id
* #param url to make the ajax call
* #param array with colModel info:
* * 0 - display name
* * 1 - width
* * 2 - sortable
* * 3 - align
* * 4 - searchable (2 -> yes and default, 1 -> yes, 0 -> no.)
* * 5 - hidden (TRUE or FALSE, default is FALSE. This index is optional.)
* #param array with button info:
* * 0 - display name
* * 1 - bclass
* * 2 - onpress
* #param default sort column name
* #param default sort order
* #param array with aditional parameters
* #return string
*/
function build_grid_js($grid_id,$url,$colModel,$sortname,$sortorder,$gridParams = NULL,$buttons = NULL)
{
//Basic propreties
$grid_js = '<script type="text/javascript">$(document).ready(function(){';
$grid_js .= '$("#'.$grid_id.'").flexigrid({';
$grid_js .= "url: '".$url."',";
$grid_js .= "dataType: 'json',";
$grid_js .= "sortname: '".$sortname."',";
$grid_js .= "sortorder: '".$sortorder."',";
$grid_js .= "usepager: true,";
$grid_js .= "useRp: true,";
//Other propreties
if (is_array($gridParams))
{
//String exceptions that dont have ' '. Must be lower case.
$string_exceptions = array("rpoptions");
//Print propreties
foreach ($gridParams as $index => $value) {
//Check and print with or without ' '
if (is_numeric($value)) {
$grid_js .= $index.": ".$value.",";
}
else
{
if (is_bool($value))
if ($value == true)
$grid_js .= $index.": true,";
else
$grid_js .= $index.": false,";
else
if (in_array(strtolower($index),$string_exceptions))
$grid_js .= $index.": ".$value.",";
else
$grid_js .= $index.": '".$value."',";
}
}
}
$grid_js .= "colModel : [";
//Get colModel
foreach ($colModel as $index => $value) {
$grid_js .= "{display: '".$value[0]."', ".($value[2] ? "name : '".$index."', sortable: true," : "")." width : ".$value[1].", align: '".$value[3]."'".(isset($value[5]) && $value[5] ? ", hide : true" : "")."},";
//If item is searchable
if ($value[4] != 0)
{
//Start searchitems var
if (!isset($searchitems))
$searchitems = "searchitems : [";
$options = '';
if (isset($value['options'])) {
if (isset($value['options']['type'])) {
$options = ", type : '".$value['options']['type']."'";
switch($value['options']['type']) {
case 'select' : $options .= ", editoptions : { value : '" . $value['options']['edit_options'] . "' }"; break;
case 'date' :
case 'radio' :
case 'checkbox' :
default :
}
}
}
if ($value[4] == 2)
$searchitems .= "{display: '".$value[0]."', name : '".$index."', isdefault: true " .$options. "},";
else if ($value[4] == 1)
$searchitems .= "{display: '".$value[0]."', name : '".$index."' " .$options. "},";
}
}
//Remove the last ","
$grid_js = substr($grid_js,0,-1).'],';
$searchitems = substr($searchitems,0,-1).']';
//Add searchitems to grid
$grid_js .= $searchitems;
//Get buttons
if (is_array($buttons))
{
$grid_js .= ",buttons : [";
foreach ($buttons as $index => $value) {
if ($value[0] == 'separator')
$grid_js .= "{separator: true},";
else
$grid_js .= "{name: '".$value[0]."', bclass : '".$value[1]."', onpress : ".$value[2]."},";
}
//Remove the last ","
$grid_js = substr($grid_js,0,-1).']';
}
//Finalize
$grid_js .= "}); })</script>";
return $grid_js;
}
}
?>
I solve looking here: https://github.com/sameersemna/ci-flexigrid
Just download codeigniter-flexigrid project, import database and set database credentials in database.php.
This is the live example from github project:
http://ci-flexigrid.sameershemna.com/countries
I like this solution because you do not need grocery-crud library but just simply codeigniter
cheers
I am looking for a php pagination class, I have used a rather simple one in the past and it is no longer supported.
I was wondering if anyone had any recommendations ?
It seems pointless to build my own when there are probably so many good ones out there.
After more searching I decided that before I use a frameworked version I should fully understand what is involved in a paginator. So I built one myself. Thanks for the suggestions though!
I would suggest Zend_Paginator for the following reasons
It's loosely coupled and doesn't require the entire library.
The ZF community is larger than the PEAR community and is actively running security audits on code, and releasing maintenance versions.
It separates data sources by using the Adapter Pattern, and there are numerous examples of front end UI pattern implementations in the documentation.
Have you tried PEAR::Pager? Usage examples here.
you can try this:
Zebra_Pagination, a generic, Twitter Bootstrap compatible, pagination class written in PHP
check the link below:
http://stefangabos.ro/php-libraries/zebra-pagination
// pagination class
class Pagination
{
// database handle
private $dbh;
// total records in table
private $total_records;
// limit of items per page
private $limit;
// total number of pages needed
private $total_pages;
// first and back links
private $firstBack;
// next and last links
private $nextLast;
// where are we among all pages?
private $where;
public function __construct($dbh) {
$this->dbh = $dbh;
}
// determines the total number of records in table
public function totalRecords($query, array $params)
{
$stmt = $this->dbh->prepare($query);
$stmt->execute($params);
$this->total_records = $stmt->fetchAll(PDO::FETCH_COLUMN)[0];
if (!$this->total_records) {
echo 'No records found!';
return;
}
}
// sets limit and number of pages
public function setLimit($limit)
{
$this->limit = $limit;
// determines how many pages there will be
if (!empty($this->total_records)) {
$this->total_pages = ceil($this->total_records / $this->limit);
}
}
// determine what the current page is also, it returns the current page
public function page()
{
$pageno = (int)(isset($_GET['pageno'])) ? $_GET['pageno'] : $pageno = 1;
// out of range check
if ($pageno > $this->total_pages) {
$pageno = $this->total_pages;
} elseif ($pageno < 1) {
$pageno = 1;
}
// links
if ($pageno > 1) {
// backtrack
$prevpage = $pageno -1;
// 'first' and 'back' links
$this->firstBack = "<div class='first-back'><a href='$_SERVER[PHP_SELF]?pageno=1'>First</a> <a href='$_SERVER[PHP_SELF]?pageno=$prevpage'>Back</a></div>";
}
$this->where = "<div class='page-count'>(Page $pageno of $this->total_pages)</div>";
if ($pageno < $this->total_pages) {
// forward
$nextpage = $pageno + 1;
// 'next' and 'last' links
$this->nextLast = "<div class='next-last'><a href='$_SERVER[PHP_SELF]?pageno=$nextpage'>Next</a> <a href='$_SERVER[PHP_SELF]?pageno=$this->total_pages'>Last</a></div>";
}
return $pageno;
}
// get first and back links
public function firstBack()
{
return $this->firstBack;
}
// get next and last links
public function nextLast()
{
return $this->nextLast;
}
// get where we are among pages
public function where()
{
return $this->where;
}
}
Use:
$pagination = new Pagination($dbh);
$pagination->totalRecords('SELECT COUNT(*) FROM `photos` WHERE `user` = :user', array(':user' => $_SESSION['id']));
$pagination->setLimit(12);
$pagination->page();
echo $pagination->firstBack();
echo $pagination->where();
echo $pagination->nextLast();
Result:
<div class='first-back'><a href='/xampp/web_development/new_study_2014/imagebox2016/app/public/test.php?pageno=1'>First</a> <a href='/xampp/web_development/new_study_2014/imagebox2016/app/public/test.php?pageno=3'>Back</a></div>
<div class='page-count'>(Page 4 of 6)</div>
<div class='next-last'><a href='/xampp/web_development/new_study_2014/imagebox2016/app/public/test.php?pageno=5'>Next</a> <a href='/xampp/web_development/new_study_2014/imagebox2016/app/public/test.php?pageno=6'>Last</a></div>
public function make_pagination()
{
$total = 0;
$query = "SELECT COUNT(downloads.dn_id) FROM downloads WHERE downloads.dn_type = 'audios'";
$stmt = $this->conn->prepare($query);
$stmt->execute();
$total = $stmt->fetchColumn();
//echo 'row_count = ' . $total;
// How many items to list per page
$limit = 11;
// How many pages will there be
$pages = ceil($total / $limit);
// What page are we currently on?
$page = min($pages, filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
'options' => array(
'default' => 1,
'min_range' => 1,
),
)));
// Calculate the offset for the query
$offset = ($page - 1) * $limit;
// Some information to display to the user
$start = $offset + 1;
$end = min(($offset + $limit), $total);
// The "back" link
$prevlink = ($page > 1) ? '« ‹' : '<span class="disabled">«</span> <span class="disabled">‹</span>';
// The "forward" link
$nextlink = ($page < $pages) ? '› »' : '<span class="disabled">›</span> <span class="disabled">»</span>';
// Display the paging information
echo '<div id="paging"><p>'.$prevlink.' Page '.$page.' of '.$pages. ' pages'. $nextlink.' </p></div>';
//prepare the page query
$query2 = "
SELECT * FROM downloads, map_artists, song_artists
WHERE map_artists.dn_id = downloads.dn_id
AND song_artists.artist_id = map_artists.artist_id
AND downloads.dn_type = 'audios' GROUP BY downloads.dn_id
ORDER BY downloads.dn_time DESC LIMIT :limit OFFSET :offset ";
$stmt2 = $this->conn->prepare($query2);
$stmt2->bindParam(':limit', $limit, PDO::PARAM_INT);
$stmt2->bindParam(':offset', $offset, PDO::PARAM_INT);
$stmt2->execute();
// Do we have any results?
if ($stmt2->rowCount() > 0) {
// Define how we want to fetch the results
$stmt2->setFetchMode(PDO::FETCH_ASSOC);
$iterator = new IteratorIterator($stmt2);
// Display the results
foreach ($iterator as $row) {
echo '<p>'. $row['dn_title'].' - '. $row['artist_name'].'</p>';
}
} else {
echo '<p>No results could be displayed.</p>';
}
}
Its Very possible that your SQL SELECT statement query may 1000 result into thousand of records. But its is not good idea to display all the results on one page. So we can divide this result into many pages as per requirement as pagination Class .
PAGINATE DATA WITH PAGINATION CLASS VERY EASY
pagination Class helps to generate paging
How To Use Pagination Class
visit this link for more info
http://utlearn.com/2017/02/15/pagination-class-use-pagination-class/
<?php
/**
* #package pagination class
* #version 1.0
*/
/*
#class Name: pagination
#Author: Ahmed Mohamed
#Version: 1.0
#Author URI: https://www.fb.com/100002349977660
#Website URI: http://www.utlearn.com
#class page URI: http://utlearn.com/2017/02/15/pagination-class-use-pagination-class
*/
include_once 'libs/config.php';
include_once 'libs/Database.php';
include_once 'libs/Model.php';
include_once 'libs/pagination.php';
if(!empty($_GET["page"]) and is_numeric($_GET["page"])){
$page = htmlspecialchars(strip_tags($_GET["page"]));
} else {
$page = 1;
}
// news = table name / you page URL / current page / true or false for full query
// its false i just use table name
$pag = new pagination("news", URL."?page=", 3, $page, false);
$pagination = $pag->pagination();
$data = $pag->data();
?>
<news>
<?php foreach($data as $news){ ?>
<header><h1><?=$news->title ?></h1> | <span><?=$news->date ?></span></header>
<div>
<?=$news->content ?>
</div>
<?php } ?>
</news>
<?=$pagination ?>
I found this awesome code online to help with pagination, and it's working well, the only problem is: each page displays the same 4 rows.
Any ideas will be much appreciated
<?php
//Include the PS_Pagination class
include('includes/ps_pagination.php');
//Connect to mysql db
$conn = mysql_connect("localhost", "root", "root");
mysql_select_db('database',$conn);
$sql = "SELECT * FROM studies WHERE niche = '{$_GET['niche']}'";
//Create a PS_Pagination object
$pager = new PS_Pagination($conn,$sql,4,5);
//The paginate() function returns a mysql
//result set for the current page
$rs = $pager->paginate();
//Loop through the result set
while($row = mysql_fetch_assoc($rs)) {
$a=0;
while ($a < $num) {
$id=mysql_result($result,$a,"id");
$title=mysql_result($result,$a,"title");
$strategies=mysql_result($result,$a,"strategies");
$client=mysql_result($result,$a,"client");
$copy=mysql_result($result,$a,"copy");
$thumbmedia=mysql_result($result,$a,"thumbmedia");
$niche=mysql_result($result,$a,"niche");
echo '<div class="container"><p class="subheadred">'.$title.'</p></div>';
echo '<div class="containerstudy"><div class="column1"><p class="subheadsmall">Strategies</p><p class="sidebarred">'.$strategies.'</p>';
echo '<p class="subheadsmall">Client</p><p class="sidebargrey">'.$client.'</p></div>';
echo '<div class="column2"><p class="bodygrey">'.substr($copy, 0, 300).'...more</p></div>';
echo '<div class="column3"><img src="images/'.$thumbmedia.'" height="160" /></div></div>';
$a++;
}
}
//Display the navigation
echo $pager->renderNav();
?>
This is the included file:
<?php
/**
* PHPSense Pagination Class
*
* PHP tutorials and scripts
*
* #package PHPSense
* #author Jatinder Singh Thind
* #copyright Copyright (c) 2006, Jatinder Singh Thind
* #link http://www.phpsense.com
*/
// ------------------------------------------------------------------------
class PS_Pagination {
var $php_self;
var $rows_per_page; //Number of records to display per page
var $total_rows; //Total number of rows returned by the query
var $links_per_page; //Number of links to display per page
var $sql;
var $debug = false;
var $conn;
var $page;
var $max_pages;
var $offset;
/**
* Constructor
*
* #param resource $connection Mysql connection link
* #param string $sql SQL query to paginate. Example : SELECT * FROM users
* #param integer $rows_per_page Number of records to display per page. Defaults to 10
* #param integer $links_per_page Number of links to display per page. Defaults to 5
*/
function PS_Pagination($connection, $sql, $rows_per_page = 1, $links_per_page = 5) {
$this->conn = $connection;
$this->sql = $sql;
$this->rows_per_page = $rows_per_page;
$this->links_per_page = $links_per_page;
$this->php_self = htmlspecialchars($_SERVER['PHP_SELF']);
if(isset($_GET['page'])) {
$this->page = intval($_GET['page']);
}
}
/**
* Executes the SQL query and initializes internal variables
*
* #access public
* #return resource
*/
function paginate() {
if(!$this->conn) {
if($this->debug) echo "MySQL connection missing<br />";
return false;
}
$all_rs = #mysql_query($this->sql);
if(!$all_rs) {
if($this->debug) echo "SQL query failed. Check your query.<br />";
return false;
}
$this->total_rows = mysql_num_rows($all_rs);
#mysql_close($all_rs);
$this->max_pages = ceil($this->total_rows/$this->rows_per_page);
//Check the page value just in case someone is trying to input an aribitrary value
if($this->page > $this->max_pages || $this->page <= 0) {
$this->page = 1;
}
//Calculate Offset
$this->offset = $this->rows_per_page * ($this->page-1);
//Fetch the required result set
$rs = #mysql_query($this->sql." LIMIT {$this->offset}, {$this->rows_per_page}");
if(!$rs) {
if($this->debug) echo "Pagination query failed. Check your query.<br />";
return false;
}
return $rs;
}
/**
* Display the link to the first page
*
* #access public
* #param string $tag Text string to be displayed as the link. Defaults to 'First'
* #return string
*/
function renderFirst($tag='First') {
if($this->page == 1) {
return $tag;
}
else {
return ''.$tag.'';
}
}
/**
* Display the link to the last page
*
* #access public
* #param string $tag Text string to be displayed as the link. Defaults to 'Last'
* #return string
*/
function renderLast($tag='Last') {
if($this->page == $this->max_pages) {
return $tag;
}
else {
return ''.$tag.'';
}
}
/**
* Display the next link
*
* #access public
* #param string $tag Text string to be displayed as the link. Defaults to '>>'
* #return string
*/
function renderNext($tag=' >>') {
if($this->page < $this->max_pages) {
return ''.$tag.'';
}
else {
return $tag;
}
}
/**
* Display the previous link
*
* #access public
* #param string $tag Text string to be displayed as the link. Defaults to '<<'
* #return string
*/
function renderPrev($tag='<<') {
if($this->page > 1) {
return ''.$tag.'';
}
else {
return $tag;
}
}
/**
* Display the page links
*
* #access public
* #return string
*/
function renderNav() {
for($i=1;$i<=$this->max_pages;$i+=$this->links_per_page) {
if($this->page >= $i) {
$start = $i;
}
}
if($this->max_pages > $this->links_per_page) {
$end = $start+$this->links_per_page;
if($end > $this->max_pages) $end = $this->max_pages+1;
}
else {
$end = $this->max_pages;
}
$links = '';
$niche = $_GET['niche'];
for( $i=$start ; $i<$end ; $i++) {
if($i == $this->page) {
$links .= " $i ";
}
else {
$links .= ' '.$i.' ';
}
}
return $links;
}
/**
* Display full pagination navigation
*
* #access public
* #return string
*/
function renderFullNav() {
return $this->renderFirst().' '.$this->renderPrev().' '.$this->renderNav().' '.$this->renderNext().' '.$this->renderLast();
}
/**
* Set debug mode
*
* #access public
* #param bool $debug Set to TRUE to enable debug messages
* #return void
*/
function setDebug($debug) {
$this->debug = $debug;
}
}
?>
Just at first glance i see your query is repeating itself from the beginning every time you run it, so that means every time you run it it searches from the beggining. you need a counter to tell it where to start from on the next page. something like:
$sql = "SELECT * FROM studies WHERE niche = '{$_GET['niche']}' limit $startPoint, $offset";
that way the offset is the same as the number of items you want per page and the $startPoint is the point at which the search beggins at the next iteration.
somehting like this would work:
if(!$startPoint){$startPoint = 0;}else{$startPoint = {$_GET['$startPoint'];}
within your code pass the start point back to the query and increasing it by the offset after each iteration.
Please bear in mind i've not taking into consideration stuff like injection, and the fact that the variable $num doesn't seem to come from anywhere in the 1st file. I cant see where you initialized it so as to test $a against it.
After looking at your code more in depth i found a few things that need to be changed to get it work in the least here is the changed code:
<?php
//Include the PS_Pagination class
include('includes/ps_pagination.php');
//Connect to mysql db
$conn = mysql_connect("localhost", "root", "root");
mysql_select_db('database',$conn);
$sql = "SELECT * FROM studies";// WHERE niche = '{$_GET['niche']}'";
//Create a PS_Pagination object
$pager = new PS_Pagination($conn,$sql,4,5);
//The paginate() function returns a mysql
//result set for the current page
$rs = $pager->paginate();
//Loop through the result set
while($row = mysql_fetch_assoc($rs)) {
// $a=0;
// while ($a < $num) {
// $id=mysql_result($result,$a,"id");
// $title=mysql_result($result,$a,"title");
// $strategies=mysql_result($result,$a,"strategies");
// $client=mysql_result($result,$a,"client");
// $copy=mysql_result($result,$a,"copy");
// $thumbmedia=mysql_result($result,$a,"thumbmedia");
// $niche=mysql_result($result,$a,"niche");
$id=$row['id'];
$title=$row['title'];
$strategies=$row['strategies'];
$client=$row['client'];
$copy=$row['copy'];
$thumbmedia=$row['thumbmedia'];
$niche=$row['niche'];
echo '<div class="container"><p class="subheadred">'.$title.'</p></div>';
echo '<div class="containerstudy"><div class="column1"><p class="subheadsmall">Strategies</p><p class="sidebarred">'.$strategies.'</p>';
echo '<p class="subheadsmall">Client</p><p class="sidebargrey">'.$client.'</p></div>';
echo '<div class="column2"><p class="bodygrey">'.substr($copy, 0, 300).'...more</p></div>';
echo '<div class="column3"><img src="images/'.$thumbmedia.'" height="160" /></div></div>';
// $a++;
// }
}
//Display the navigation
echo $pager->renderNav();
?>
Notice i have commented out some part that where not necessary
the variable $a was meaningless as it compared to $num which doesn't exist therefore nothing would show. Now these lines:
// $id=mysql_result($result,$a,"id");
// $title=mysql_result($result,$a,"title");
// $strategies=mysql_result($result,$a,"strategies");
// $client=mysql_result($result,$a,"client");
// $copy=mysql_result($result,$a,"copy");
// $thumbmedia=mysql_result($result,$a,"thumbmedia");
// $niche=mysql_result($result,$a,"niche");
where also wrong as you are trying to get the result set from $result. at no place had you put the result set into $result the class you have imported does that and puts the result set into an identifier called $rs.
Since you are using $row = mysql_fetch_assoc($rs) to read through the result set then to get the variables all you need to do is get the column row through an array like this
$id=$row['id'];
and so on. once you do that then the code should work as expected. However this brings us back to this:
$sql = "SELECT * FROM studies WHERE niche = '{$_GET['niche']}'";
i had to get the last part out in that this variable is not getting passed back into the query string (seeing you are using get), the other problem is the 1st time you load the page this variable 'niche' doesn't exist so the 1st time you run the code you will get a blank page, unless this script is accessed through a link that passes in this variable. at this point i have left it commented out as am not sure what you were trying to do through niche.
Hope that helps.
Do you have page set in your query string?
I think that if you changed the paginate function, so that it would have one parameter $page and you would set $this->page = $page at the begining of the function, it would work.
You would also have to change the calling of this function in your code to $pager->paginate($_GET['page']).
The pager is also very inefficient, it gets the whole query just to find out, how many rows does the response have. I would use something like:
$all_rs = #mysql_query('SELECT COUNT(*) FROM (' . $this->sql . ')');
if(!$all_rs) {
if($this->debug) echo "SQL query failed. Check your query.<br />";
return false;
}
$this->total_rows = mysql_result($all_rs, 0, 0);
#mysql_close($all_rs);
I'm not sure what this pagination library does with the index of the rows, but you are always setting $a to 0. Perhaps the index is not relative to the page but to the overall recordset being returned?
In other words, what if you set $a to 0 on page 1, 4 on page 2, etc.
You should be able to use $rows_per_page and $page to calculate it. Or perhaps that is the $offset value, so that you set $a to offset and loop it until you hit $rows_per_page additional rows.
Edit clarifying solution:
So what I see you could do is:
$a=0;
while ($a < $pager->rows_per_page) {
$row = $a + $pager->offset;
$id=mysql_result($result,$row,"id");
$title=mysql_result($result,$row,"title");
$strategies=mysql_result($result,$row,"strategies");
$client=mysql_result($result,$row,"client");
$copy=mysql_result($result,$row,"copy");
$thumbmedia=mysql_result($result,$row,"thumbmedia");
$niche=mysql_result($result,$row,"niche");
...
$a++;
}