Multiple $_GET through links - php

I'm doing a website. There's a pagination, you click on links and they take you to the page you need, the links pass $_GET variable ( a href="?pn=2" ) and that works fine.
However when i add the category links (also contain $_GET variable
(a href="?sort=english") on the same page, which kind of sort the content on the page, and click it, the system simply overrides the url and deletes all the previous $_GET's.
For example, I'm on page 2 (http://website.com/index.php?pn=2)
and then I click this sorting link and what I'm expecting to get is this (http://website.com/index.php?pn=2&sort=english), but what I get is this:
(http://website.com/index.php?sort=english). It simply overrides the previous $_GET, instead of adding to it!

A relative URI consisting of just a query string will replace the entire existing query string. There is no way to write a URL that will add to an existing query. You have to write the complete query string that you want.
You can maintain the existing string by adding it explicitly:
href="?foo=<?php echo htmlspecialchars($_GET['foo']); ?>&bar=123"

Try using this:
$_SERVER['REQUEST_URI'];
On this link you can see examples. And on this link I have uploaded test document where you can try it yourself, it just prints out this line from above.
EDIT: Although this can help you get the current parameters in URL, I think it's not solution for you. Like Quentin said, you will have to write full link manually and maintain each parameter.

You could create a function that will iterate through your $_GET array and create a query string. Then all you would have to do is change your $_GET array and generate this query string.
Pseudocode (slash I don't really know PHP but here's a good example you should be able to follow):
function create_query_string($array) {
$kvps = array();
for ($key in $array) {
array_push($kvps, "$key=$array[$key]");
}
return "?" . implode("&", $kvps);
}
Usage:
$_GET["sort"] = "english";
$query_string = create_query_string($_GET);

You need to maintain the query parameters when you create the new links. The links on the page should be something like this:
Sort by English
The HTTP protocol is stateless -- it doesn't remember the past. You have to remind it of what the previous HTTP parameters were via PHP or other methods (cookies, etc). In your case, you need to remind it what the current page number is, as in the example above.

Related

pass a value from one page to another outside querystring and without javascript?

One solution to automatically building navigation for a site is by scanning a folder for documents like this:
foreach(glob('pages/*.pg.php') as $_SITE_NAV_filePath):
$_SITE_NAV_filePath = explode('.pg',pathinfo($_SITE_NAV_filePath,PATHINFO_FILENAME));
$_SITE_NAV_fileName = $_SITE_NAV_filePath[0];
$_SITE_NAV_qv = preg_replace('/([A-Z])/','-$1',$_SITE_NAV_fileName); $_SITE_NAV_qv = trim($_SITE_NAV_qv,'-');
$_SITE_NAV_name = preg_replace('/([A-Z])/',' $1',$_SITE_NAV_fileName);
?>
<li><?=$_SITE_NAV_name?></li>
<?php
endforeach;
This code will turn "AnAwesomePage.pg.php" into a menu item like this :
<li>An Awesome Page</li>
This might be bad practice (?).
Anyway; I don't use this method very often since most of the time the sites have a database, and with that comes better solutions...
But my question is this:
Is there a way to prefix the filename with a integer followed by and underscore (3_AnAwesomePage.pg.php), for sorting order purposes, and pass it somehow to the destination page outside of the querystring and without any async javascript?
I could just explode the filename once again on "_" to get the sort order and store it somewhere, somehow?
This is the code for handeling the page query request:
$_SITE_PAGE['qv'] = $_GET['page'];
if (empty($_SITE_PAGE['qv'])){ $_SITE_PAGE['qv'] = explode('-','Home'); }
else { $_SITE_PAGE['qv'] = explode('-',$_GET['page']); }
$_SITE_PAGE['file'] = 'pages/'.implode($_SITE_PAGE['qv']).'.pg.php';
This code turns "An-Awesome-Page" back into "AnAwesomePage.pg.php" so it's possible to include it with php.
But with a prefix, it's not so easy.
The probliem is; Now there's no way to know what prefix number there was before since it has been stripped away from the query string. So I need to send it somehow along in the "background".
One very bad solution I came up with was to transform the navigation link into a form button and just _POST the prefix interger along with the form. At fist it sounded like a nice solution, but then I realized that once a user refreshes their page, it didn't look very good. And after all, that's not what forms are for either...
Any good solutions out there?
Or some other and better way for dealing with this?
There are two ways to keep that number saved, you can use cookies or php session variables.
But in this case, if user first enter the url in the browser or in a new browser, then he should be taken to default number.
Like you have:
1_first-page.php
2_first-page.php
3_first-page.php
If user enter the url like: domain.com/?page=first-page, you have to take him to 1_first-page.php to any number which you want to be default.

How to store search conditions with php and Codeigniter?

I have small problem.
I've coded a full website in php using CodeIgniter framework. One of my modules is search module, it contains text input with keyword and three select lists with filtering criterias.
That's ok, when I'm searching something - result's listing pagination is done via URL like that:
mysite.com/$keyword/$criteria1/$criteria2/$criteria3/$offset
works like a charm.
But when I'm entering into one of my images (it's image gallery) I want to have an option to go into NEXT and PREVIOUS image from my search results - the ones which I entered this image from.
I'm solving this case now in this way - I have session table called 'search_conditions' and I'm storing values of keyword and my three criterias there, but that's quite not comfortable, because why if someone opens second window and search something else there?
Then all of his searches in another windows or tabs are getting the same criteria - because with every new search, user overwrite the session value.
My next and previous functions:
public function next($count)
{
$search = $this->session->userdata('search_conditions'); //getting session table and overwriting it
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count, 1);
}
public function previous($count)
{
$search = $this->session->userdata('search_conditions');
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count-2, 1);
}
Can you recommend me some other, more comfortable solution, because this seems not to be good...
: )
Thank you!
Add an index to the $search_conditions variable:
$search_conditions[1]['catid']
$search_conditions[1]['brandid']
...
then refer to it with a controller's or config variable. This way you can allow one session to store multiple search conditions.
But I would recommend you drop storing the search condition in session. Instead, just pass it with the URI. Session data, in the case you describe, work as an intermediary; you don't need it. Use the Pagination Class and pass the search page number, not the direction (next or previous) to the URI.
Do not worry that the URI may look ugly - it only depends on what user searches for, and it's still friendly to share. Your only concern is if the GET string does not extend the limited length.
Pull the segments from the URI in your next() and previous() functions. Use the codeigniter URL helper. That should allow you to pass the different search criterion as variables to the next page, this would also remove your need to use the session.

How to pick up the database name and table name from the URL in PHP?

I am new to PHP.
I need a help regarding the methods of extracting DB name and table name from the given URL name.
For example, let's say, I have an URL like the one below:
/test.php?db=...&table=.../
How to extract the DB name and table name from this URL using PHP and use the result for other query purposes.
If you mean how to parse an existing URL for it's parameters:
parse_url() and parse_str() will help you strip the components of the url. You will primarily be looking at the following
$elements = parse_url($url);
$kvps = $elements->query;
$db = parse_str($kvps['db']);
$table = parse_str($kvps['table']);
But, if you mean how to GET variables from the current page before render:
<?php
$dbname = $_GET['db'];
$tablename = $_GET['table'];
?>
And yea, there are major security risks involved in opening up 'direct' access to your database this way. Best to obfuscate / encapsulate / wrap your functions in tasks like index.php&addUser=tim instead of index.php&insert=tim&db=boofar&table=users&dbuser=root&dbpassword=secure.
If you're just learning, what you're doing is fine, as long as you realize why it's wrong. If you're coding for production, you really need an alternate solution.
There are two ways to pass variables or data to another page.
GET (via the URL)
and
POST (usually a form submission)
You can alway get via
$_GET
http://php.net/manual/en/reserved.variables.get.php
or
$_POST
http://nl.php.net/manual/en/reserved.variables.post.php

PHP Query String Manipulation

I have a small issue with manipulating the current URL query string to add an extra parameter at the end.
Per example, say there's a category layout for products, the URL would be:
index.php?category=3&type=5
Now, on that page I have a link for a layout that is either a table or a grid. In those URLs I currently have:
<a href="index.php?<?php echo preg_replace($array,'',$_SERVER['QUERY_STRING']); ?>&layout=grid" ...
Then, I do the same for the table href as well. Also in my array I have just:
$array = array ( '/&layout=table/', '/&layout=grid/' )
Is this the right way, or is there a better way for doing this? I'm asking because without preg_replace, it will continue adding that same layout parameter everytime it is clicked, so it will also show the previous parameter, then the next, then the next.. without removing the previous layout parameters.
Any insight on this will be much appreciated.
EDIT:
Thanks to the answers below, I have created a little function:
function buildQuery($key,$value) {
$params = $_GET;
$params[$key] = $value;
return http_build_query($params);
}
Then its only a matter off:
grid
this might seem pointless but i like to have my view / template files without the extra set vars. Im a clean freak. I might even return the 'index.php?' with it just so i can be more lazy, anyways something to play with now :)..
If you want to modify the query string, it's easier to simply modify the GET variables and rebuild the query string:
$params = $_GET;
$params['layout'] = 'new_layout';
Then:
...
Although you could also do:
...
Think about directly parsing the $_GET paramaters to build your url.
I think what you want to do is have the link going to index.php with all the same parameters as you have at the moment, but changing layout to grid. I'd suggest you do something like this:
<?php
// make a copy of the $_GET array with all the parameters from the query string
$params = $_GET;
// set layout=grid regardless of whether layout was set before or its value
$params['layout'] = 'grid';
// generate a query string to append to your urls.
// Note that & is used as the arg separator; this is necessary for XHTML and advised for HTML
$queryString = http_build_query($params, '', '&');
?>
href="index.php?<?php echo $queryString; ?>">
This is much easier than trying to edit and fix the $_SERVER['QUERY_STRING'] yourself.

cakePHP paginate with post data without sessions, serialization or post to get

I have created a small search and filter form with a POST action in controller/index, which POSTs to itself the conditions and fields to paginate ($this->paginate($conditions)).
That is good for the first page, however on the subsequent pages the filter conditions are lost. Pagination passedArgs supports GET variables well.
Are there an un-complex ways to pass the POST conditions to the other paginated pages?
The method I have looked at is to pass the $conditions via the session, which isn't without complexity of assigning the session and unsetting the session on submitting the form again (more refinements to the filter criteria by the user).
The other method is passing the $conditions as serialized string with url_encode as a GET parameter.
Is there a good 'cake' way to do this more like passedArgs. Sessions and url_encode do not look like cake style.
Thanks
Is there an un complex way to pass the
post conditions to the other paginated
pages?
Nope.
Is there an good cake way to do this
more like passArgs, sessions and url
encode do not look like cake style.
There is only one way, no matter, cake or not cake.
Search must be done using GET method.
Parameters being passed via QUERY STRING.
So, make your search form with method="GET" and then use http_build_query() to assemble a query string and use it to make links to other pages.
Being a little curious, you can see an example right here on SO:
http://stackoverflow.com/questions/tagged?tagnames=php&page=5&sort=newest&pagesize=50
You can use passedArgs.
in the method controller :
if ( empty($this->passedArgs['search']) ){
$this->passedArgs['search'] = $this->data['YourModel']['search'];
}
if ( empty($this->data) ){
$this->data['YourModel']['search'] = $this->passedArgs['search'];
}
in your view :
$this->Paginator->options(array('url' => $this->passedArgs));
If it was me I would run with your idea of saving the stuff into the session. Then I would add a page dimension to the session, to store each page, thus allowing users to go back and forth with ease.
$this->Session->write('Search.page.1.params',$params);
$this->Session->write('Search.page.2.params',$params2);
In order to do it in a Cake way, you'd probably want to write your own Pagination helper, or plugin. Which you could then use more effectivly in your controllers as
$this->MyPages->paginate('MyModel');
I suppose, this functionality would also give you the option to allow your users to 'Save my search' if they wanted to, as you could dump the session params into a SavedSearch model or similar.
Don't forget to $this->Session->destroy() before starting a new search though!
You can also use the Post/Redirect/Get design pattern pattern to solve this, allowing users to bookmark URLs of searches (without them expiring as a session would) and keeping URLs looking friendly. For example:
function index($searchTerms = null) {
// post/redirect/get
if (isset($this->data['SearchForm'])) {
$this->redirect(array($this->data['SearchForm']['search_terms']));
}
// your normal code here.
}
The search form data POSTs to /controller/action but the user is redirected and instead GETs /controller/action/search+terms where the terms are passed into the action as a parameter (ie. $searchTerms).
If you simply change the form submission method to GET you will instead see something like: /controller/action?data[SearchForm][search_terms]=search+terms
Thanks Deizel for the POST / REDIRECT / GET pattern.
I implemented the GET method of posting data.
For pagination used this
$urlparams = $this->params['url'];unset($urlparams['url']);
$paginator->options(array('url' => array('?' => http_build_query($urlparams))));
We had multi checkboxes and the naming convention used where :
foreach ($checkboxes as $chbox ) {
// used variable variables to generate the data grid table based on selected fields
${'_field'.$chbox} = (isset($this->params['url']['displayfields'][$chbox])?$this->params['url']['displayfields'][$chbox]:1);
$options = array('label'=>$chbox,'type'=>'checkbox','value'=> ${'_field'.$chbox});
if ( ${'_field'.$chbox} ) $options['checked'] = 'checked';
echo $form->input('Filter.displayfields['.$chbox.']',$options);
In the post method the naming convention for the checkboxs would be Filter.displayfields.checkbox name
This helps in getting an array either in $this->data or $this->params['url']
There should be an persistent pagination plugin/component for cakePHP would make life much more easier and fun to develop with cakePHP.
Thanks all.

Categories