I have a HTML form that i am using to search a database, the form method is GET:
<form method="get" action="">
Then my SQL Query selects from a database using the $_GET values
i run the SQL, then have this function - (http://pastebin.com/J3RL3MxC) - that i run underneath the query
So in total, it looks like:
$sql="SELECT * FROM customer ORDER BY company";
$i=0;
$array = ShowRecords($sql, "customer");
foreach($array["results"] as $ret) {
}
and i echo my results in the foreach loop
this is working fine, however when navigating through the pages that the function creates i loose the $_GET values so i also loose what i have searched for
how can i keep the $_GET values but keep in mind that the $_GET["pagenum"] needs to be removed/changed so the page will change
I have already added this code:
$query_string = '?';
foreach($_GET as $q => $k) {
if($q == 'id' or $q == 'pagenum') {
//
} else {
if($q != '') {
$query_string = '&'.$q.'='.$k;
}
}
}
at the top of my function to try to do what is needed ($_GET["id"] also needs to be removed) but its not keeping the values
What is the best way to keep all $_GET values except the specified ones?
P.S: I know i should be using PDO which i will be as soon as i have this issue sorted, i will then change my code to use PDO
Use http_build_query to build your query string instead of doing it manually:
http://php.net/manual/en/function.http-build-query.php
I would just store all of the request vars in an array and updated it as needed. When ready to output any links just use http_build_query to generate the query string
$request = $_GET;
unset($request['id']);
$request['pagenum'] = 2;
//etc
$query_string = '?' . http_build_query($request);
$id = isset($_GET["id"]) ? $_GET["id"] : NULL;
$pagenum = isset($_GET["pagenum"]) ? $_GET["pagenum"] : NULL;
if($id) {
}
if($pagenum) {
}
Related
<?php
include('dbLink2.php');
$quizqr = $_GET['quizQR'];
$recordsID1 = $_GET['recordsID1'];
$recordsID2 = $_GET['recordsID2'];
$m_array1=array();
$m_array=array();
$sql = "SELECT quizQR, recordsID FROM `registertestactivity` WHERE (quizQR = '$quizqr' OR recordsID = '$recordsID1' OR recordsID = '$recordsID2') LIMIT 1";
$result = #mysqli_query($link, $sql) or die();
if (#mysqli_affected_rows($link) > 0) {
while($row = #mysqli_fetch_assoc($result))
{
$m_array[]=$row;
}
} else {
$m_array1 += ["quizQR" => "NoRecords"];
$m_array1 += ["recordsID" => "NoRecords"];
$m_array[0] = $m_array1;
}
echo json_encode($m_array);
#mysqli_free_result($result);
#mysqli_close($link);
?>
Can someone help me out, i have tried the mysqli_real_escape_string and it still doesnt work :(
The $quizqr value has a '#' character in the string and this is the error msg that pops when the ajax call this php:
Because you have a # in the URL you're dealing with a URL Fragment which means that everything past the # is not available in the query string. PHP offers a flag, PHP_URL_FRAGMENT for its parse_url() function which can help you get what you need from the string.
Here is one example using the URL you provided:
$fragment = parse_url($url, PHP_URL_FRAGMENT);
echo $fragment;
$fragmentSection = explode('&', $fragment);
print_r($fragmentSection);
foreach($fragmentSection AS $section) {
if(0 != strpos($section, '=')) {
$sectionParts = explode('=', $section);
$queryParts[$sectionParts[0]] = $sectionParts[1];
}
}
print_r($queryParts);
This ultimately returns two array members which could then be used in your query:
Array
(
[recordsID1] => records_001
[recordsID2] => records_002
)
The best thing to do would be to write a function to which you pass the URL to return the elements you need.
Keep in mind that this is not fool-proof. If the URL is in a different format then what I have done here will have to be modified to work as you would like it to.
Additionally you have been given some warnings and guidance in the comments you should follow to keep your code safe and efficient, so I will not repeat them here.
I have a form page in which many of the elements are saved to different tables and different rows in my db. In order to minimize db calls I would like to compare the data before and after form submission, then I can write a function which will only update data that has been changed. To accomplish this I am saving the array that I used to build the form in a session file:
$this->session->set_tempdata('form_values_'.$item['id'],json_encode($item), 86400);
On form submission I retrieve this data and compare it to the $_POST:
$pre_post = json_decode($_SESSION['form_values_'.$_POST['id']], true);
Everything works great except in a few textareas where there is a "." in my test data. For some reason these fields come back as not equal even though I'm not changing the data.
It is definitely the period that is causing the problem, when I remove it it works fine. On the other hand there are other textareas that have periods that are not causing problems.
I thought it might be codeigniter's XSS filtering, but I removed that and it made no difference.
Originally i was using serialize to encode the array for storage, but I switched to json_encode and again it made no difference.
Here is the code I am using to compare the values:
$pre_post = json_decode($_SESSION['form_values_'.$_POST['id']], true);
$post = $this->security->xss_clean($_POST);
foreach ($post as $key => $value) {
if( !isset($pre_post[$key]) || trim($value)!=trim($pre_post[$key]) ){
$post_post[$key] = $value;
}
}
Any ideas?
Try this code may be it help you
$select = "SELECT * FROM ".$table_name." WHERE ".$field_name ." = '".$value."'";
$result_latest = mysql_query($select) or trigger_error(mysql_error());
while($row = mysql_fetch_array($result_latest,MYSQL_ASSOC))
{
$data_new = array_intersect_key($row,$data);
foreach($data_new as $k=>$v)
{
if(strcmp($row[$k],$data[$k]) != 0)
{
$string .= '`'.$k.'` = "'.$data[$k].'" ,';
}
}
}
$string = rtrim($string, ",");
if($string != NULL){
$update_sql = "UPDATE ".$table_name." SET ".$string." WHERE ".$field_name." = "."'".$value."'";
$query = $CI->db->query($update_sql);
}
I've got the following code which is something like a form search engine with multiple inputs where the results are kinda absolute concerning the number of characters etc(perfect match)
.
// build array of field names=============================================================================
$fields=array('user','customer','vessel','country',
'port','eta','service_station','type_of_service',
'case_reference','status');
// initialize empty array for WHERE clauses
$wheres=array();
// loop through field names, get POSTed values,
// and build array of WHERE clauses, excluding false values
foreach ($fields as $field) {
// get existing field value from POST, mark missing or empty value as FALSE
${$field} = isset($_POST[$field]) && trim($_POST[$field])!=''
? trim($_POST[$field]) : false;
// add to array of WHERE clauses only if value is not FALSE
if (${$field}) { $wheres[]="$field='".${$field}."'"; }
}
// build SELECT statement from WHERE clauses
$sql="SELECT * FROM jobs WHERE ".
(!empty($wheres) ? implode(" AND ",$wheres) : '1=1').
";";
What i want to do is add an input in the form
<label for="special">Special Search</label>
<input type="text" name="special" id="special_search">
where the user would be able to search in the case_reference field and get the results that match the first four characters. Also i would like this new input to work the same as the others as far as the AND or OR and TRUE or FALSE statements are concerned.
All help appreciated thank you in advance:)
UPDATE : Instead of rewriting the whole thing i came up with the following code at the begining of my previous :
$joker = $_POST['special'];
$joker1 = substr($joker1, 0, 4);
if(isset($_POST['case_reference']) && !empty($_POST['case_reference'])
&& empty($_POST['special'])) {
} else { $_POST['case_reference'] = $joker1; }
It is working for now but anyone can confirm that it would be okay in future??
From the SQL:
$sql="SELECT * FROM jobs WHERE ". (!empty($wheres) ? implode(" AND ",$wheres) : '1=1').";";
Just simply add a variable for special:
$special = $_POST['special']; // this will get the data from the textbox
then add it to the sql statement
$sql="SELECT * FROM jobs WHERE LIKE $special 'aaaa%' AND ". (!empty($wheres) ? implode(" AND ",$wheres) : '1=1').";";
Rewritten avoiding variable variable names, and using mysql_real_escape_string (although you should use mysqli or pdo):-
<?php
// build array of field names=============================================================================
$fields=array('user','customer','vessel','country',
'port','eta','service_station','type_of_service',
'case_reference','status');
// initialize empty array for WHERE clauses
$wheres = array('1=1');
// loop through field names, get POSTed values,
// and build array of WHERE clauses, excluding false values
foreach ($fields as $field)
{
// get existing field value from POST, mark missing or empty value as FALSE
if (isset($_POST[$field]) && trim($_POST[$field])!='')
{
$wheres[]="`$field`='".mysql_real_escape_string(trim($_POST[$field]))."'";
}
}
if (isset($_POST['special']) && trim($_POST['special'])!='')
{
$wheres[] = " case_reference' LIKE '".mysql_real_escape_string(trim($_POST['special']))."%'";
)
// build SELECT statement from WHERE clauses
$sql="SELECT * FROM jobs WHERE (".implode(" AND ",$wheres).") ;";
?>
I asked this question before, but it got no responses, so I deleted the last question, and simplified/clarified the question, and am reposting
I have a comics site... I'm working on a SO-style tagging system. A user can select 1 or many tags which will display all associated comics.
To remember the user selections, I'm storing them in a $_SESSION array.
The issue I'm having is that one of the strings, 'business', being stored in the $_SESSION['tagnames'] array after it is chosen by the user is not being found in the array...
The way it's supposed to work is a user selects a tag, and to deselect it, they click it again... so I check if the string is in the $_SESSION... if it is, unset it... here is a snippet:
//var_dump shows these are both set fine when a user clicks on the tag they want
$tagid = (isset($_GET['tagid']) ? ($_GET['tagid']) : null);
$tagname = (isset($_GET['tagname']) ? ($_GET['tagname']) : null);
...
//Tag IDS are added and removed without issue:
//if tag id exists in $_SESSION['tags'] array, remove it
if ($key = array_search($tagid, $_SESSION['tagids'])) {
unset($_SESSION['tagids'][$key]);
}
else {
$_SESSION['tagids'][] = $tagid;
}
...
//but one of the tag names, 'business', is not being removed... and is actually added again even when I press F5 to refresh
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
This is a var_dump of the sql statement: It correctly shows the query being changed based on which tag id is selected.
Here's a var_dump of the $_SESSION['tagname']... you can see that it recognizes when tags 2 and 3 (differences and similarities) have already been added (I used array_search() to check), but it doesn't find tagid 1, 'business', even though it's clearly been added several times.
Here's the function that returns the selected tag names to the user:
function getSelectedTags() {
global $tagid, $tagname;
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
var_dump($_SESSION['tagname']);
foreach ($_SESSION['tagname'] as $tagname) {
echo '<span class="tags">' . $tagname . '</span>';
}
}
Any thoughts why tagname 'business' is the only thing causing an issue?
Even after I destroy the session, pressing F5 to refresh will automatically put tagname 'business' into the $_SESSION['tagname'] array.
EDIT: More comprehensive code:
Homepage.php: user clicks on returned tags from getDBTags() to add a tag to the $_SESSION array on imageDisplay.php
<h5>Tags</h5>
<?php echo getDBTags(); ?>
<br/>
<p>Your tags:</p>
<?php echo getSelectedTags(); ?>
imageDisplay.php: responsible for handling how images are filtered and displayed...
getDBTags() returns tag choices from the database so users can click on them:
function getDBTags() {
include 'dbconnect.php';
global $cat;
$sql = "SELECT tagid, tagname FROM tags";
$query = $mysqli->query($sql);
while ($row = $query->fetch_assoc()) {
echo '<span class="tags">'.$row['tagname'].'</span>';
}
mysqli_close($mysqli);
}
getFilters() decides how images should be filtered by having a dynamic query, then sends the query to pagination(), which displays filtered images on pages.
function getFilters() {
include 'dbconnect.php';
global $cat, $site, $table, $tagid;
$order = " ORDER BY date DESC";
//if tag id exists in $_SESSION['tags'] array, remove it
if ($key = array_search($tagid, $_SESSION['tagids'])) {
unset($_SESSION['tagids'][$key]);
}
//if it doesn't, add it
else {
$_SESSION['tagids'][] = $tagid;
}
//var_dump($_SESSION['tagids']);
if ($cat != null) $catquery = " AND catidFK = $cat";
else $catquery = null;
$sql =
"SELECT c.*, t.*
FROM comics c
INNER JOIN comictags ct ON (c.id = ct.comicID)
INNER JOIN tags t ON (t.tagid = ct.tagID)
WHERE ct.tagID IN ('" . implode(', ', $_SESSION['tagids']). "')
". $catquery ." " . $order;
if (!$mysqli->query($sql)) printf("<br /><b>Error:</b> %s\n", $mysqli->error);
$query = $mysqli->query($sql);
var_dump($sql);
mysqli_close($mysqli);
return $query;
}
getSelectedTags() returns the selected tag title back to the user so they can see what they've chosen. If they click on a tag again (returned from getDBTags() above), it will remove the tag from $_SESSION['tagname']. This is the problem area:
function getSelectedTags() {
global $tagid, $tagname;
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
//var_dump($key = array_search($tagname, $_SESSION['tagname']));
var_dump($_SESSION['tagname']);
foreach ($_SESSION['tagname'] as $tagname) {
echo '<span class="tags">' . $tagname . '</span>';
}
}
There are three issues which stand out (well two stand out, one is very subtle).
1. Open only one DB connection and leave it:
First, instead of opening and closing the connection in $mysqli in your functions, do it once at the start of the script and leave it open. You'll need to modify your functions to accept $mysqli as a parameter (preferred) or access it via global $mysqli; (not preferred). There is no need to call mysqli_close(), as that is done implicitly.
In your getFilters() function, you are actually closing the MySQLi resource $mysqli and then attempting to return $query; where $query is a result resource. Doing that will render the result resource useless.
// Pass $mysqli as a parameter
function getFilters($mysqli) {
//...
// Do alll your stuff...
// And do not call mysqli_close()!
return $query
}
2. Use strict comparison and test for FALSE with array_search():
When using array_search(), if your result is the first element in the array at key [0], that will be regarded by a surrounding if () condition as a falsy return rather than the positive result it should be. For that reason, a tag at position [0] will get repeatedly added rather than removed. This will need to be fixed in a couple of places...
// First get the key, which is an int or FALSE
$key = array_search($tagid, $_SESSION['tagids']);
// Unset if it is FALSE by strict comparison
if ($key !== FALSE) {
unset($_SESSION['tagids'][$key]);
}
else {
$_SESSION['tagids'][] = $tagid;
}
3. Global variable $tagname is ruined by a foreach:
You have accessed the global $tagname in getSelectedTags(). But in that function you have a foreach loop which does :
foreach ($_SESSION['tagname'] as $tagname)
When using $tagname as the loop's variable there, it is actually overwriting the global $tagname on each iteration. You need to change that to a different value, or whenever you call getSelectedTags(), $tagname the global will become whatever the last tag in $_SESSION['tagname'] had been, without exception.
// use a different varname in the loop
foreach ($_SESSION['tagname'] as $tn) {
// Also calling htmlspecialchars to escape here. Do this in any variable to HTML output...
echo '<span class="tags">' . htmlspecialchars($tn) . '</span>';
}
I am currently using column header's as links that when clicked will sort the results by the column name by adding a get variable to the url. Here is an example:
<a href="
<?php
// Sorts by order id. If already sorted by order id, then it will change the link to sort descending
if(!isset($_GET['sortby']) || $_GET['sortby'] != 'order_id'){
echo $_SERVER['SCRIPT_NAME'] . '?sortby=order_id'; //example: tracker.php?sortby=order_id
} elseif(isset($_GET['sortby']) || $_GET['sortby'] == 'order_id'){
echo $_SERVER['SCRIPT_NAME'] . '?sortby=order_id_desc'; //example: tracker.php?sortby=order_id_desc
}?>
">Order ID</a>
I also have a form where users can enter pick a category from a selectbox and then enter a searchterm. I am using if statements and switch statements to check if the $_GET['sortby'] variable and the $_POST['search_submit'] variable is set and if so, to run a certain sql statement based on the value of the GET variable.
There are 4 different scenarios.
1. Default: If neither sort nor search is set. This one works fine:
if(!isset($_GET['sortby']) && !isset($_POST['search_submit'])){ //Default, If no sort or search is set
$sql = 'SELECT *
FROM orders
ORDER BY order_id DESC';
}
2. If the search is set but the sort is not. This one works fine:
if(isset($_POST['search_submit'])) {
$search_string = ' WHERE ' . $_POST['searchby'] . '= "' . $_POST['search_input'] . '" ';
}
if(!isset($_GET['sortby']) && isset($_POST['search_submit']) ){ //If the search is set but no sort
$sql = "SELECT *
FROM orders"
. $search_string .
"ORDER BY order_id DESC";
}
3. If the sort is set, but the search is not. This one works fine:
if(isset($_GET['sortby']) && !isset($_POST['search_submit'])) { //If the sort is set but no search
switch ($_GET['sortby']) {
case "order_id":
$sql = "SELECT *
FROM orders
ORDER BY order_id ASC";
break;
case "order_id_desc":
$sql = "SELECT *
FROM orders
ORDER BY order_id DESC";
break;
}
}
4. If the search AND sort is set. All 3 of the above if statements work, but the last one is giving me problems.
if(isset($_GET['sortby']) && isset($_POST['search_submit'])) { //If the sort AND search is set
switch ($_GET['sortby']) {
case "order_id":
$sql = "SELECT *
FROM orders"
. $search_string .
"ORDER BY order_id ASC";
break;
case "order_id_desc":
$sql = "SELECT *
FROM orders"
. $search_string .
"ORDER BY order_id DESC";
break;
}
}
What happens is that you can search, but as soon as you click on one of the column headers and it reloads the page with the new GET variable, it will get rid of the current POST variable, thereby showing all results again. I tried to load the current POST variable into a session after the $_POST['search_submit'] isset and then make the last if statement check to see if the session variable is set, but what happens then is that the session is always set and if i try to go back to the homepage, it will keep those search results.
Perhaps I need to destroy the session somewhere? Perhaps there is an overall better approach I could be taking to combining sort and search features?
I would recommend changing the search form from a method="POST" to method="GET" and use just GET for all your requests. If you cannot change your POST requests, you are going to need to POST each request (including sorting), which will require javascript attached to your sort links.
The benefit to using GET is that your users can bookmark specific searches since all the data would be contained in the Query string.
EDIT: Retaining the search strings in subsequent requests:
I would abstract out your sorting code to something like this:
<?php
function write_sortable_header_link( $column_id, $column_name ){
if( ( isset($_GET['sortby']) && $_GET['sortby'] != $column_id ) || !isset($_GET['sortby']) )
$query = "?sortby=$column_id";
else
$query = '?sortby='.$column_id.'_desc';
if( isset($_GET['searchsubmit']) ){
$query .= '&searchsubmit=1';
$query .= '&searchby=' . urlencode( isset($_GET['searchby']) ? $_GET['searchby'] : '' );
$query .= '&search_input=' . urlencode( isset($_GET['search_input']) ? $_GET['search_input'] : '' );
}
$href = $_SERVER['SCRIPT_NAME'] . $query;
echo "<a href='$href'>$column_name</a>";
}
?>
You would then call it like this:
<?php write_sortable_header_link( 'order_id', 'Order Id' ); ?>
It would make sure your sorting URL's contain the correct query string arguments for persistence.
Try to use $_GET only, involving $_POST seems unnecessary.
Not an answer to your question, but just my 0.2
In your situation I usually do the sorting client side in the web browser using javascript. It prevents essentially the same query being run over and over again with only different ORDER BY parameters.
With jquery there are even some very nice plugins that make it pretty easy.
example: http://tablesorter.com/docs/
This is the code I ended up using to make the link rewrite with the sort and search get variables as suggested by dcneiner. I took out the urlencode, the switched & to the '&' sign and made the inline if statement read as just the get variable, since the only way those get variables can be set is if the search_submit is set since they're part of the same form. I also added the '{' and '}' back into the if and else statements. I'm guessing you're using a slightly different way of doing PHP? Do you see anything wrong or unsecure about the changes I made? I wasn't too sure why you did it your way. But thanks again.
function write_sortable_header_link( $column_id, $column_name ){ //Function that creates a link with the search query if needed
if( ($_GET['sortby'] != $column_id) || !isset($_GET['sortby']) ) { //If the GET variable is not the column id of this button or if the GET sortby variable has not been set
$query = "?sortby=$column_id"; //then add this to the end of the url
} else {
$query = '?sortby='.$column_id.'_desc'; //otherwise if the GET variable is the column id of this button, then add the descending code to the end of the variable
}
if(isset($_GET['search_submit']) ){ //If the GET variable search_submit is in the url
$query .= '&search_submit=1'; //then add this to the end of the url string
$query .= '&searchby=' . $_GET['searchby']; //add whatever is currently in the GET searchby to the end of the url string
$query .= '&search_input=' . $_GET['search_input']; //add whatever is currently in the GET search_input to the end of the url string
}
$href = $_SERVER['SCRIPT_NAME'] . $query; //this is the href part of the link
echo "<a href='$href'>$column_name</a>"; //this creates the actual link
}