Searching database with different charset - php

I have a website with a small searching script, where I use utf-8 charset.
Now on my mysql database I use the latin1_swedish_ci charset.
When I want to search for something that has the letters å,ä or ö it doesn't return any results because in the database the letter å=Ã¥, ä=ä and ö=ö.
The solution to this problem would be telling the search script to replace these letters with those that the database understands.
So when my users search for something that has the letter å in it, it should convert it to Ã¥ and return proper results.
Any idea how to achieve this?
Thanks in advance
EDIT:
Added the script that im trying to modify, but with no luck.
Any idea on how to modify it so that it "converts" the charset:
<?php
// file for database connection
include('inc/db.inc.php');
// configuration file
include('inc/config.inc.php');
if(isset($_GET['p'])) {
$page_number = $_GET['p'];
$arraySearch = $_GET['terms'];
$show_count = $_GET['count'];
settype($page_number, 'integer');
}
$nospaces = substr($_GET['terms'],0,4);
$offset = ($page_number - 1) * $records_number;
// check for an empty string and display a message.
if ($_GET['terms'] == "") {
echo '<div id="counter">ex. write ´here and´ or ´search´ without quotes.</div>';
// minim 3 characters condition
} else if(strlen($_GET['terms']) < $limitchar) {
echo '<div id="counter">'. $limitchar .' characters minimum</div>';
// no spaces in first 4 letters
} else if(preg_replace('/[a-zA-Z0-9]/', '', $nospaces)) {
echo '<div id="counter">Please use letters or numbers in first 4 characters</div>';
} else {
// explode search words into an array
$arraySearch = explode(" ", $_GET['terms']);
// table fields to search
$arrayFields = array(0 => $first_field, 1 => $second_field);
$countSearch = count($arraySearch);
$a = 0;
$b = 0;
$query = "SELECT * FROM $table_name WHERE (";
$countFields = count($arrayFields);
while ($a < $countFields)
{
while ($b < $countSearch)
{
$query = $query."$arrayFields[$a] LIKE '%$arraySearch[$b]%'";
$b++;
if ($b < $countSearch)
{
$query = $query." AND ";
}
}
$b = 0;
$a++;
if ($a < $countFields)
{
$query = $query.") OR (";
}
}
$query = $query.") LIMIT $offset, $records_number;";
$search = mysql_query($query);
// get number of search results
$arrayFields = array(0 => $first_field, 1 => $second_field);
$countSearch = count($arraySearch);
$a = 0;
$b = 0;
$query = "SELECT * FROM $table_name WHERE (";
$countFields = count($arrayFields);
while ($a < $countFields)
{
while ($b < $countSearch)
{
$query = $query."$arrayFields[$a] LIKE '%$arraySearch[$b]%'";
$b++;
if ($b < $countSearch)
{
$query = $query." AND ";
}
}
$b = 0;
$a++;
if ($a < $countFields)
{
$query = $query.") OR (";
}
}
$query = $query.")";
$count_results = mysql_query($query);
$numrows = mysql_num_rows($count_results);
// no results
if($numrows == 0) {
echo '<div id="counter">No results found</div>';
// show results
} else {
echo '<div id="results">
<div id="results_top"><p><b>'. $_GET['terms'] .'</b> - '. $numrows .' results found</p></div>
';
while($row = mysql_fetch_assoc($search)) {
$urltitle = str_replace(" ","_", $row['title']);
echo '<div class="item">
<div class="details"><img src="http://www.onlinegamez.net/files/image/'.$row['icon'].'" width="90" height="65" alt="'.$row['title'].'"/>'.$row['title'].'<br />
'.$row['description'].'</div>
<div class="played"><span>'.$row['timesplayed'].'</span>
<p>played</p></div>
<div style="clear:both;"></div></div>';
}
// pagination
$maxPage = ceil($numrows/$records_number);
$nav = '';
for($page = 1; $page <= $maxPage; $page++) {
if ($page == $page_number) {
$nav .= "$page";
}
else
{
$nav .= "$page";
}
}
if ($page_number > 1) {
$page = $page_number - 1;
$prev = "«";
$first = "First";
}
else {
$prev = '';
$first = '';
}
if ($page_number < $maxPage) {
$page = $page_number + 1;
$next = "»";
$last = "Last";
}
else {
$next = '';
$last = '';
}
echo $data;
echo "<div id=\"results_bottom\"><p>$first $prev $nav $next $last</p></div>
</div>";
}
}
?>

First of all -- why are you using different charsets?
There are several ways to attack you problem, you could change the charset on connection;
set names 'utf8';
set character set 'utf8' collate 'utf8_swedish_ci';
You could do a collation based match;
select
`field`
from
`table`
where
cast(`field` as char character set 'utf8') collate 'utf8_swedish_ci' = '$PHP_VARIABLE'
Or you could change the charset on the variable in PHP;
$var_in_iso88591 = utf8_decode($var_in_utf8);
Look into utf8_encode()/utf8_decode() and iconv()

Related

Use PHP while loop to create advance filter

I have a problem and that is I want to create a link on a website like people can click the link to show certain products only depending on percentage. like for example, i have a column in my database with discount percentage and it will show min discount and max discount. assuming we have min and max discount. $min=12 and $max=94; and I want to put them in links to show only products with certain discounts only like filtering. below is the example of the link.
<a href="#">12% to 20%</a
21% to 30%
31% to 40% and so on until it reaches
81% to 90% and the last will be
91% to 94%
smallest and largest numbers will be coming from a column from database and they can change frequently. i came up with solution and its working fine but my code is too long and its like I took to many steps which could be done in few lines of code. I have pasted my working code below but I am sure this can be reduced to few lines of code.
$catsql25 = "SELECT MAX(down_percentage) as largest FROM hot_deals";
$catquery25 = mysqli_query($conn, $catsql25);
while ($row25 = mysqli_fetch_array($catquery25, MYSQLI_ASSOC)){
$largest_number = $row25['largest'];
}
$catsql26 = "SELECT MIN(down_percentage) as smallest FROM hot_deals";
$catquery26 = mysqli_query($conn, $catsql26);
while ($row26 = mysqli_fetch_array($catquery26, MYSQLI_ASSOC)){
$smallest_number = $row26['smallest'];
}
$array_tens = array(10,20,30,40,50,60,70,80,90,100);
foreach ($array_tens as $value){
if(($value - $smallest_number <= 10) && ($value - $smallest_number > 0)){
echo '<a href="/exp.php?fst='.$smallest_number.'&lst='.$value.'"><div class="lfmen2">';
echo $smallest_number." to ".$value."</div></a>";
$next_num = $value + 1;
$next_ten = 9;
$stop_num = floor($largest_number / 10);
$stop_num2 = $stop_num * 10;
//echo $stop_num2.'<br>';
$num_rounds = $stop_num2 - $value;
$num_rounds2 = $num_rounds / 10;
//echo $num_rounds2;
for ($i = 1; $i <= $num_rounds2; $i++){
$end_num = $next_num + $next_ten;
echo '<a href="/exp.php?fst='.$next_num.'&lst='.$end_num.'"><div class="lfmen2">';
echo $next_num;
echo " to ";
echo $end_num;
echo "</div></a>";
$next_num += 10;
$end_num += 10;
}
}
}
foreach ($array_tens as $value2){
if(($largest_number - $value2 < 10) && ($largest_number - $value2 > 0)){
$lsst = $value2 + 1;
if($lsst != $largest_number){
echo '<div class="lfmen2">'.$lsst." to ".$largest_number."</div>";
}
elseif($lsst == $largest_number){
echo '<div class="lfmen2">'.$largest_number.'</div>';
}
}
}
I know its all mess but..
Thanks.
First thing you could do is only one SQL Query :
$catsql = "SELECT MAX(down_percentage) as largest, MIN(down_percentage) as smallest FROM hot_deals";
And then you'll need only one loop :
$catquery = mysqli_query($conn, $catsql);
while ($row = mysqli_fetch_array($catquery, MYSQLI_ASSOC)){
$largest_number = $row['largest'];
$smallest_number = $row['smalest'];
}
After that, you could make only one foreach loop. The two "if" conditions could be in the same loop :
foreach ($array_tens as $value) {
if (($value - $smallest_number <= 10) && ($value - $smallest_number > 0)) {
echo '<a href="/exp.php?fst='.$smallest_number.'&lst='.$value.'"><div class="lfmen2">';
echo $smallest_number." to ".$value."</div></a>";
$next_num = $value + 1;
$next_ten = 9;
$stop_num = floor($largest_number / 10);
$stop_num2 = $stop_num * 10;
//echo $stop_num2.'<br>';
$num_rounds = $stop_num2 - $value;
$num_rounds2 = $num_rounds / 10;
//echo $num_rounds2;
for ($i = 1; $i <= $num_rounds2; $i++) {
$end_num = $next_num + $next_ten;
echo '<a href="/exp.php?fst='.$next_num.'&lst='.$end_num.'"><div class="lfmen2">';
echo $next_num;
echo " to ";
echo $end_num;
echo "</div></a>";
$next_num += 10;
$end_num += 10;
}
}
if (($largest_number - $value < 10) && ($largest_number - $value > 0)) {
$lsst = $value + 1;
if ($lsst != $largest_number) {
echo '<div class="lfmen2">'.$lsst." to ".$largest_number."</div>";
} elseif ($lsst == $largest_number) {
echo '<div class="lfmen2">'.$largest_number.'</div>';
}
}
}
To make it more readable, you could also comment your code to know what do what.
This and a good indentation and you're right.
Hope it helps.

automatic number increase in php based web form [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
So I have created an html form which then posts the results to a php file that overlays them on a PDF and then emails that PDF to myself and the email that was put in the form. All I want to do now is find a simple way to make it so that the PDF includes a sequential number.
For example: When the form is filled out for the first time the number 0001 is input automatically into the PDF and 0002 for the second time and so on.
Is there an easy PHP function to accomplish this?
Essentially I am creating an online invoicing form so when I do service calls I can create an invoice on the spot from a web browser which is then emailed to my office and the client.
Any help would be greatly appreciated.
For an incrementing number, you could keep a number in a database and then extract it, add 1 to it, use it, and then put it back in the DB for next time, but this seems complicated. Somebody in the comments mentioned using the timestamp, which would be done like so:
$invoicenumber = time(); //This number will always be unique
The time function works like so (copied from w3schools):
The time() function returns the current time in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
Since actual seconds can only go up (increment), this number will never be the same twice.
I hope this is helpful.
-Edit
You can also display this date/time in a readable format like so:
$time = time();
echo date("Y-m-d H:i:s",$time);
-Edit 2
If you want an incrementing number, you basically need a very simple database to save it, which might be as simple as a table called invoices, with a column called invoicenumber, which stores your invoice number in it. You could / probably should use this to store other invoice information in it too, so you'd have each invoice number saved (which means we want to only get the highest one)
Then your code would look like this, for each time you want to use it:
Firstly you'd have a database information file (settings.php or something similar) with your database definitions in it, which might look like this:
define('DB_HOST', 'localhost');
define('DB_USER', 'db_username');
define('DB_PASS', 'db_password');
define('DB_NAME', 'database_name');
Your code would look like this:
//Establish a mysql connection
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
//Set up a query to get the highest number
$query = "SELECT invoicenumber FROM invoices ORDER BY invoicenumber DESC LIMIT 1";
//Get the result
$result = $mysqli->query($query);
$row = $result->fetch_assoc();
//If we have a record
if($row){
//New invoice number
$invoicenumber = $row['invoicenumber']++;
//Else (database is empty, so start at the beginning)
}else{
$invoicenumber = 1;
}
//Now we have our invoice number, so do whatever you want with it
/**
* Code here to use the number
* */
//Now we wanna add the new invoice to the database, so
/**
* Add any other info to this statement if you want.
* If any of it is user submitted data, be sure to use prepared statements
* (just look at php.net's documentation on prepared statements)
* w3schools also has some nice tutorials on how to safely insert stuff
* in to a database, so check it all out :)
* */
$query = "INSERT INTO invoices(invoicenumber) VALUES($invoicenumber)";
//Execute the query
if($mysqli->query($query)){
//Show success
echo "Invoice $invoicenumber has been added to the database.";
}else{
//Show error
echo "Unfortunately we could not add invoice $invoicenumber to the database.";
}
//Now we can clear up our resources
$stmt->free_result(); $stmt->close(); $mysqli->close();
Please note: this is a very basic example. Yours will have additions and enhanced security if you are using user submitted data, so please do your homework and make sure that you fully understand each line of this code before you proceed to use it.
I do exactly the same with patient accession numbers on patient reports.
include('/home/user/php/class.pdf2text.php');
$p2t = new PDF2Text();
$p2t->setFilename($pdf);
$p2t->decodePDF();
$data = $p2t->output();
$len = strlen($data);
$pos = strpos($data,$accession);
if (pos){
$in .= "$accession,";
$checked++;
}
else{
$missingPDF += 1;echo "\n<p> <span class='bold red'>INCORRECT ACCESSION NUMBER c=$row[0] p=$row[1]</span>\n";
}
if ($checked > 0){
$in = substr($in,0,-1) . ')';
$sql = "UPDATE `Patient` SET `PDF`=1 WHERE $in";
}
pdf2text.php
class PDF2Text {
// Some settings
var $multibyte = 4; // Use setUnicode(TRUE|FALSE)
var $convertquotes = ENT_QUOTES; // ENT_COMPAT (double-quotes), ENT_QUOTES (Both), ENT_NOQUOTES (None)
var $showprogress = true; // TRUE if you have problems with time-out
// Variables
var $filename = '';
var $decodedtext = '';
function setFilename($filename) {
// Reset
$this->decodedtext = '';
$this->filename = $filename;
}
function output($echo = false) {
if($echo) echo $this->decodedtext;
else return $this->decodedtext;
}
function setUnicode($input) {
// 4 for unicode. But 2 should work in most cases just fine
if($input == true) $this->multibyte = 4;
else $this->multibyte = 2;
}
function decodePDF() {
// Read the data from pdf file
$infile = #file_get_contents($this->filename, FILE_BINARY);
if (empty($infile))
return "";
// Get all text data.
$transformations = array();
$texts = array();
// Get the list of all objects.
preg_match_all("#obj[\n|\r](.*)endobj[\n|\r]#ismU", $infile . "endobj\r", $objects);
$objects = #$objects[1];
// Select objects with streams.
for ($i = 0; $i < count($objects); $i++) {
$currentObject = $objects[$i];
// Prevent time-out
#set_time_limit ();
if($this->showprogress) {
// echo ". ";
flush(); ob_flush();
}
// Check if an object includes data stream.
if (preg_match("#stream[\n|\r](.*)endstream[\n|\r]#ismU", $currentObject . "endstream\r", $stream )) {
$stream = ltrim($stream[1]);
// Check object parameters and look for text data.
$options = $this->getObjectOptions($currentObject);
if (!(empty($options["Length1"]) && empty($options["Type"]) && empty($options["Subtype"])) )
// if ( $options["Image"] && $options["Subtype"] )
// if (!(empty($options["Length1"]) && empty($options["Subtype"])) )
continue;
// Hack, length doesnt always seem to be correct
unset($options["Length"]);
// So, we have text data. Decode it.
$data = $this->getDecodedStream($stream, $options);
if (strlen($data)) {
if (preg_match_all("#BT[\n|\r](.*)ET[\n|\r]#ismU", $data . "ET\r", $textContainers)) {
$textContainers = #$textContainers[1];
$this->getDirtyTexts($texts, $textContainers);
} else
$this->getCharTransformations($transformations, $data);
}
}
}
// Analyze text blocks taking into account character transformations and return results.
$this->decodedtext = $this->getTextUsingTransformations($texts, $transformations);
}
function decodeAsciiHex($input) {
$output = "";
$isOdd = true;
$isComment = false;
for($i = 0, $codeHigh = -1; $i < strlen($input) && $input[$i] != '>'; $i++) {
$c = $input[$i];
if($isComment) {
if ($c == '\r' || $c == '\n')
$isComment = false;
continue;
}
switch($c) {
case '\0': case '\t': case '\r': case '\f': case '\n': case ' ': break;
case '%':
$isComment = true;
break;
default:
$code = hexdec($c);
if($code === 0 && $c != '0')
return "";
if($isOdd)
$codeHigh = $code;
else
$output .= chr($codeHigh * 16 + $code);
$isOdd = !$isOdd;
break;
}
}
if($input[$i] != '>')
return "";
if($isOdd)
$output .= chr($codeHigh * 16);
return $output;
}
function decodeAscii85($input) {
$output = "";
$isComment = false;
$ords = array();
for($i = 0, $state = 0; $i < strlen($input) && $input[$i] != '~'; $i++) {
$c = $input[$i];
if($isComment) {
if ($c == '\r' || $c == '\n')
$isComment = false;
continue;
}
if ($c == '\0' || $c == '\t' || $c == '\r' || $c == '\f' || $c == '\n' || $c == ' ')
continue;
if ($c == '%') {
$isComment = true;
continue;
}
if ($c == 'z' && $state === 0) {
$output .= str_repeat(chr(0), 4);
continue;
}
if ($c < '!' || $c > 'u')
return "";
$code = ord($input[$i]) & 0xff;
$ords[$state++] = $code - ord('!');
if ($state == 5) {
$state = 0;
for ($sum = 0, $j = 0; $j < 5; $j++)
$sum = $sum * 85 + $ords[$j];
for ($j = 3; $j >= 0; $j--)
$output .= chr($sum >> ($j * 8));
}
}
if ($state === 1)
return "";
elseif ($state > 1) {
for ($i = 0, $sum = 0; $i < $state; $i++)
$sum += ($ords[$i] + ($i == $state - 1)) * pow(85, 4 - $i);
for ($i = 0; $i < $state - 1; $i++) {
try {
if(false == ($o = chr($sum >> ((3 - $i) * 8)))) {
throw new Exception('Error');
}
$output .= $o;
} catch (Exception $e) { /*Dont do anything*/ }
}
}
return $output;
}
function decodeFlate($data) {
return #gzuncompress($data);
}
function getObjectOptions($object) {
$options = array();
if (preg_match("#<<(.*)>>#ismU", $object, $options)) {
$options = explode("/", $options[1]);
#array_shift($options);
$o = array();
for ($j = 0; $j < #count($options); $j++) {
$options[$j] = preg_replace("#\s+#", " ", trim($options[$j]));
if (strpos($options[$j], " ") !== false) {
$parts = explode(" ", $options[$j]);
$o[$parts[0]] = $parts[1];
} else
$o[$options[$j]] = true;
}
$options = $o;
unset($o);
}
return $options;
}
function getDecodedStream($stream, $options) {
$data = "";
if (empty($options["Filter"]))
$data = $stream;
else {
$length = !empty($options["Length"]) ? $options["Length"] : strlen($stream);
$_stream = substr($stream, 0, $length);
foreach ($options as $key => $value) {
if ($key == "ASCIIHexDecode")
$_stream = $this->decodeAsciiHex($_stream);
elseif ($key == "ASCII85Decode")
$_stream = $this->decodeAscii85($_stream);
elseif ($key == "FlateDecode")
$_stream = $this->decodeFlate($_stream);
elseif ($key == "Crypt") { // TO DO
}
}
$data = $_stream;
}
return $data;
}
function getDirtyTexts(&$texts, $textContainers) {
for ($j = 0; $j < count($textContainers); $j++) {
if (preg_match_all("#\[(.*)\]\s*TJ[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
elseif (preg_match_all("#T[d|w|m|f]\s*(\(.*\))\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
elseif (preg_match_all("#T[d|w|m|f]\s*(\[.*\])\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, array(#implode('', $parts[1])));
}
}
function getCharTransformations(&$transformations, $stream) {
preg_match_all("#([0-9]+)\s+beginbfchar(.*)endbfchar#ismU", $stream, $chars, PREG_SET_ORDER);
preg_match_all("#([0-9]+)\s+beginbfrange(.*)endbfrange#ismU", $stream, $ranges, PREG_SET_ORDER);
for ($j = 0; $j < count($chars); $j++) {
$count = $chars[$j][1];
$current = explode("\n", trim($chars[$j][2]));
for ($k = 0; $k < $count && $k < count($current); $k++) {
if (preg_match("#<([0-9a-f]{2,4})>\s+<([0-9a-f]{4,512})>#is", trim($current[$k]), $map))
$transformations[str_pad($map[1], 4, "0")] = $map[2];
}
}
for ($j = 0; $j < count($ranges); $j++) {
$count = $ranges[$j][1];
$current = explode("\n", trim($ranges[$j][2]));
for ($k = 0; $k < $count && $k < count($current); $k++) {
if (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+<([0-9a-f]{4})>#is", trim($current[$k]), $map)) {
$from = hexdec($map[1]);
$to = hexdec($map[2]);
$_from = hexdec($map[3]);
for ($m = $from, $n = 0; $m <= $to; $m++, $n++)
$transformations[sprintf("%04X", $m)] = sprintf("%04X", $_from + $n);
} elseif (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+\[(.*)\]#ismU", trim($current[$k]), $map)) {
$from = hexdec($map[1]);
$to = hexdec($map[2]);
$parts = preg_split("#\s+#", trim($map[3]));
for ($m = $from, $n = 0; $m <= $to && $n < count($parts); $m++, $n++)
$transformations[sprintf("%04X", $m)] = sprintf("%04X", hexdec($parts[$n]));
}
}
}
}
function getTextUsingTransformations($texts, $transformations) {
$document = "";
for ($i = 0; $i < count($texts); $i++) {
$isHex = false;
$isPlain = false;
$hex = "";
$plain = "";
for ($j = 0; $j < strlen($texts[$i]); $j++) {
$c = $texts[$i][$j];
switch($c) {
case "<":
$hex = "";
$isHex = true;
$isPlain = false;
break;
case ">":
$hexs = str_split($hex, $this->multibyte); // 2 or 4 (UTF8 or ISO)
for ($k = 0; $k < count($hexs); $k++) {
$chex = str_pad($hexs[$k], 4, "0"); // Add tailing zero
if (isset($transformations[$chex]))
$chex = $transformations[$chex];
$document .= html_entity_decode("&#x".$chex.";");
}
$isHex = false;
break;
case "(":
$plain = "";
$isPlain = true;
$isHex = false;
break;
case ")":
$document .= $plain;
$isPlain = false;
break;
case "\\":
$c2 = $texts[$i][$j + 1];
if (in_array($c2, array("\\", "(", ")"))) $plain .= $c2;
elseif ($c2 == "n") $plain .= '\n';
elseif ($c2 == "r") $plain .= '\r';
elseif ($c2 == "t") $plain .= '\t';
elseif ($c2 == "b") $plain .= '\b';
elseif ($c2 == "f") $plain .= '\f';
elseif ($c2 >= '0' && $c2 <= '9') {
$oct = preg_replace("#[^0-9]#", "", substr($texts[$i], $j + 1, 3));
$j += strlen($oct) - 1;
$plain .= html_entity_decode("&#".octdec($oct).";", $this->convertquotes);
}
$j++;
break;
default:
if ($isHex)
$hex .= $c;
elseif ($isPlain)
$plain .= $c;
break;
}
}
$document .= "\n";
}
return $document;
}
}

PHP pagination function

public function paging($limit,$numRows,$page){
$allPages = ceil($numRows / $limit);
$start = ($page - 1) * $limit;
$querystring = "";
foreach ($_GET as $key => $value) {
if ($key != "page") $paginHTML .= "$key=$value&";
}
$paginHTML = "";
$paginHTML .= "Pages: ";
for ($i = 1; $i <= $allPages; $i++) {
$paginHTML .= "<a " . ($i == $page ? "class=\"selected\" " : "");
$paginHTML .= "href=\"?{$querystring}page=$i";
$paginHTML .= "\">$i</a> ";
}
return $paginHTML;
}
This is my pagination function for MVC pattern implementation.But this function has not displayed next and prev links.
I need to return HTML variable for pagination with previous and next link to controller.
I passed these variable to this function from controller.
$limit,$numRows,$page
How can I get next and prev links to above function.
I have added some conditions in the loop itself.
Hope they work.
Try the following:
<?php
public function paging($limit,$numRows,$page){
$allPages = ceil($numRows / $limit);
$start = ($page - 1) * $limit;
$querystring = "";
foreach ($_GET as $key => $value) {
if ($key != "page") $paginHTML .= "$key=$value&";
}
$paginHTML = "";
$paginHTML .= "Pages: ";
for ($i = 1; $i <= $allPages; $i++) {
if ($i>1) {
$prev = $i-1;
$paginHTML .= 'Previous';
}
$paginHTML .= "<a " . ($i == $page ? "class=\"selected\" " : "");
$paginHTML .= "href=\"?{$querystring}page=$i";
$paginHTML .= "\">$i</a> ";
if ($i<$allPages) {
$next = $i+1;
$paginHTML .= 'Next';
}
}
return $paginHTML;
}
?>
I'm using this pagination class like bellow inside my controller
case '' :
$page = isset ( $_REQUEST ['page'] ) ? $_REQUEST ['page'] : 1;
$limit = 5;
$allStudent = $student->getAllStudents();
$numRows = count($allStudent);
$start = ($page - 1) * $limit;
$students = $student->getStudentsWithLimit($start,$limit);
$paginHTML = $pagin->paging($limit,$numRows,$page);
$view->render('view/allStudent.php', array('allStudent' => $students,'pagin' => $paginHTML ));
break;
Get record function in Model class
public function getStudentsWithLimit($start,$limit){
$stmt = $this->db->con->query("SELECT * FROM student LIMIT $start, $limit");
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
This should page with next and previous links with a max of 5 on either side of current page.
Pass in a function if you want the link formatted differently.
I've only given this very limited testing, and its been pulled out of a class, so you could replace some hard coded values in here with parameters of references to $this
function get_paging_links($result_count, callable $format_function=null)
{
if(!$format_function){
$format_function = function($url,$page,$qs){
$qs['page'] = $page;
return $url.'?'.http_build_query($qs);
};
}
$per_page = 5;
$total_pages = ceil($result_count / $per_page);
$return = [];
parse_str($_SERVER['QUERY_STRING'],$qs);
$url = $_SERVER['REQUEST_URI'];
//Remove existing query_string.
if($pos = strpos($url,'?')){
$url = substr($url,0,$pos);
}
$current_page = isset($qs['page']) ? $qs['page'] : 1;
$previous = $current_page -1;
if ($previous) {
$return['previous'] = $format_function($url,$previous,$qs);
}
for($i = max(1,$current_page-5); $i <= min($total_pages,$current_page+5); $i++) {
$return["$i"] = $format_function($url,$i,$qs);
}
$next_page = $current_page + 1;
if ($next_page < $total_pages){
$return['next'] = $format_function($url,$next_page,$qs);
}
return $return;
}

Optimized Logic to find high score

Basically this is related to a squash application where we have 2 scores. One is from winner point of view and another from loser point of view.
eg.
Score1: 11-5,11-5,11-5 (Winner point of view)
Score2: 5-11, 5-11,5-11 (Loser point of view)
Now in my logic i want to find which is the winner score and which is the loser score.
I have written my logic in the below way and it does work. But i want to know if their is any other better/optimized way of writing this.
$high1 = 0;
$high2 = 0;
$score1 = "2-11,5-11,4-11,4-4";
$score2 = "11-2,11-5,11-4,4-4";
$score1Array = explode(",",$score1);
$size = sizeof($score1Array);
for($i = 0; $i < $size; $i++) {
$checkscore1 = explode("-",$score1Array[$i]);
if($checkscore1[0] < $checkscore1[1]) {
$high1++;
}else if($checkscore1[0] > $checkscore1[1]) {
$high2++;
}
}
if($high1 > $high2) {
$winningScore = $score2;
$losingScore = $score1;
}else{
$winningScore = $score1;
$losingScore = $score2;
}
echo $winningscore;
echo $losingscore;
What about something like this:
function is_winning($score) {
$split_scores = preg_split('/(-|,)/', $score);
$wins = $losses = 0;
for($i = 0; $i < count($split_scores) / 2; $i += 2) {
if($split_scores[$i] > $split_scores[$i + 1])
$wins++;
if($split_scores[$i] < $split_scores[$i + 1])
$losses++;
}
return $wins > $losses;
}
Assuming $score is formatted as in your question. You can then use it like this:
$score1 = "2-11,5-11,4-11,4-4";
$score2 = "11-2,11-5,11-4,4-4";
if(is_winning($score1)) {
$winning_score = $score1;
$losing_score = $score2;
} else {
$winning_score = $score2;
$losing_score = $score1;
}
echo $winning_score;
echo $losing_score;
The idea is to split the score into an array where the even numbered indexes have the left score and the odd numbered indexes the right score. We then count the number of wins and the number of losses. If there's more wins then losses then we return true since the score was a winning score. If there's not more wins then losses we simply return false.
This should work
$score1 = "2-11,5-11,4-11,4-4";
$score2 = "11-2,11-5,11-4,4-4";
$l = $r = 0;
$score1_sets_arr = explode(',', $score1);
foreach ($score1_sets_arr as $set_score) {
$set_score_arr = explode('-', $set_score);
if ($set_score_arr[0] > $set_score_arr[1]) {
$l++;
} else {
$r++;
}
}
if ($l > $r) {
$winning_score = $score1;
$losing_score = $score2;
} else {
$winning_score = $score2;
$losing_score = $score1;
}
you can use this :
<?php
$high1 = 0;
$high2 = 0;
$score1 = "2-11,5-11,4-11,4-4";
$score2 = "11-2,11-5,11-4,4-4";
$explode = explode(",",$score1);
for($i=0;$i< sizeof($explode);$i++){
$explode2= explode("-", $explode[$i]);
if($explode2[0] <= $explode2[1]){
echo $explode2[0]."-";
echo $explode2[1]." ";
}
}
echo "<br />";
for($i=0;$i< sizeof($explode);$i++){
$explode2= explode("-", $explode[$i]);
if($explode2[1] >= $explode2[0]){
echo $explode2[1]."-";
echo $explode2[0]." ";
}
}
?>
for Winner point of view, all big score in left,otherwise in right. so u can just detect the first score.
$score1Array = explode(",",$score1);
$checkscore1 = explode("-",$score1Array[$i]);
if($checkscore1[0] < $checkscore1[1]) {
echo $score2;
echo $score1;
}else{
echo $score1;
echo $score2;
}
Fix: above code is wrong,try this:
$score1value = eval(str_replace(",","+",$score1));
$score2value = eval(str_replace(",","+",$score2));
if($score1value < $score2value) {
echo $score2;
echo $score1;
}else{
echo $score1;
echo $score2;
}

Pagination not working because of two select statements

$today = date('D, d M, Y');
$sql = "SELECT * FROM table WHERE date = '$today'";
if ($_POST!="") {
$mydate = mysql_real_escape_string($_POST['datepicker']);
if ($mydate != "") {
$sql = "SELECT * FROM table WHERE date = '$mydate'";
}
}
$num_results_per_page = 8;
$num_page_links_per_page = 5;
$pg_param = "";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
pagination($sql, $num_results_per_page, $num_page_links_per_page, $pg_param);
if($pg_error == '')
{
if(mysql_num_rows($pg_result) > 0)
{
while($data = mysql_fetch_assoc($pg_result))
{
echo "";
}
echo "</br>". $pagination_output;
}
else
{
echo "No Data.";
}
}
else
{
echo $pg_error;
}
For the above code the pagination is not working properly. I am thinking that it is because of two select statements. It will be OK if we can combine those two. Any suggestions? How can I combine those two select statements?
Pagination is working correctly for select $today, but not working properly for select $mydate. For example if the user clicks page number two in select $mydate, its again going to select $today.
pagination.php
$pg_error = '';
$pg_result = '';
$pagination_output = '';
$max_pages = '';
$page_id = '';
$page_numbers_per_page = '';
$pg_user_param = '';
function pagination($sql, $num_results_per_page, $num_page_links_per_page, $pg_param)
{
global $pg_error, $pg_result, $max_pages, $page_id, $page_numbers_per_page, $pg_user_param;
$user_sql = $sql;
$page_numbers_per_page = $num_page_links_per_page;
$results_per_page = $num_results_per_page;
$pg_user_param = $pg_param;
$all_results = mysql_query($user_sql);
if($all_results)
{
if(empty($all_results))
{
$total_results = 0;
}
else
{
$total_results = mysql_num_rows($all_results);
}
$max_pages = ceil($total_results / $results_per_page);
if(isset($_GET['page_id']))
{
$page_id = (int) $_GET['page_id'];
if($page_id > $max_pages || empty($page_id))
{
$page_id = 1;
}
}
else
{
$page_id = 1;
}
$page_id_temp = ($page_id - 1) * $results_per_page;
$sql_offset = $page_id_temp;
$user_sql .= " limit $sql_offset, $results_per_page";
$pg_result = mysql_query($user_sql);
Create_Links();
}
else
{
$pg_error = 'Error with the sql query you entered: '.mysql_error();
}
}
function Create_Links()
{
global $pagination_output, $max_pages, $page_id, $page_numbers_per_page, $pg_user_param;
$pg_page_name = htmlspecialchars($_SERVER['PHP_SELF'] );
if($max_pages > 1)
{
if($page_id > 1)
{
$first_link = 'First ';
}
if($page_id < $max_pages)
{
$last_link = 'Last ';
}
$pre_id = $page_id - 1;
if($pre_id != 0)
{
$pre_link = 'Previous ';
}
$next_id = $page_id + 1;
if($next_id <= $max_pages)
{
$next_link = 'Next ';
}
if($page_id >= $page_numbers_per_page)
{
$start_point = ($page_id - $page_numbers_per_page) + 2;
}
else
{
$start_point = 1;
}
$loop_num = ($start_point + $page_numbers_per_page) - 1;
if($loop_num > $max_pages)
{
$loop_num = $max_pages;
}
$pagination_output = '<div class="pagination"> ';
$pagination_output .= $first_link;
$pagination_output .= $pre_link;
for($i = $start_point; $i <= $loop_num; $i++)
{
if($i == $page_id)
{
$pagination_output .= '<a class="current">'.$i.'</a> ';
}
else
{
$pagination_output .= ''.$i.' ';
}
}
$pagination_output .= $next_link;
$pagination_output .= $last_link;
$pagination_output .= '</div><br />';
}
}
?>
If pagination is working for "$today" then it must be the POST input value - are you making sure you're getting a proper date that mysql can understand?
the format should basically match what's in "$today".
I'd imagine that the second click is not POSTing myDate to the next page. The next page then sees nothing in POST and uses today.
To avoid this you could also check for GETs of the datepicker and then pass myDate using GET.
Edit: Clarification on updating the code to use GET
The check on mydate should be changed to something like:
if ($_REQUEST!="") {
$mydate = mysql_real_escape_string($_REQUEST['datepicker']);
if ($mydate != "") {
$sql = "SELECT * FROM table WHERE date = '$mydate'";
}
}
Which means that if the datepicker is from a GET request we still grab it.
Create_Links() should be changed to add "&datepicker=$mydate" (note that you will need to pass in $myDate to ths function.

Categories