How can I trim my URL - php

A have a delete link which goes to another page, call a function, if the function is successful, then I sent the user back to the page where they clicked delete.
I use this to go back:
if ($booking->deleteBooking($_GET['id']))
{
header('Location: ' . $_SERVER['HTTP_REFERER']);
}
My link would look something like this:
/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true
Can I trim the link and remove &reserved=true when it's sent back?

Rather than performing string manipulations that could be prone to error, I suggest that you use PHP's URL functions to parse the HTTP_REFERER header and adjust it accordingly:
// parse the referrer
$referer = parse_url($_SERVER['HTTP_REFERER']);
// parse the querystring part
parse_str($referer['query'], $querystring);
// unset the reserved parameter (only if value is 'true'?)
if ($querystring['reserved'] === 'true') unset($querystring['reserved']);
// reconstruct the revised querystring
$referer['query'] = http_build_query($querystring);
// redirect to the adjusted URL
header('Location: ' . http_build_url($referer));

I suggest you avoid regex and str_replace because they will quickly fall flat when your URL structure changes.
I would put this in a class now because this is not the last time you'll need to do this (I just had to do it last week) or some other URL related thing. So, you should go ahead and encapsulate the functionality in one place now rather than later. You can always change the implementation later in one place if you find a better or more correct way to handle the task.
A few fairly important caveats regarding your script and possible solutions...
HTTP_REFERER can't really be relied upon. Browsers are not required to send it and many do not. You can get around that by sending the URL yourself in the query string (properly escaped) or possibly via a hidden form field. Otherwise, your redirect and script is going to fail in a lot of cases! See HTTP Referer not always being passed
You should always exit after sending a Location header if you want an immediate redirect... otherwise your script will keep chugging along happily doing stuff. (database queries, etc, etc) To that end, I would encapsulate your redirect code as well and have done so in my example solution.
http_build_url is not available by default in PHP. It's a pecl_http thing. Ultimately, it's not really required in this case and my example solution works without it.
Example Class Usage:
$referrer = 'http://example.com/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true';
$url = new URL($referrer);
$url->remove_param('reserved');
$url->redirect();
Class Code:
class URL
{
public $url = '';
function __construct ($url)
{
$this->url = $url;
}
function redirect ($response_code = 301)
{
header('Location: ' . $this->url, true, $response_code);
exit;
}
function remove_param ($param)
{
// Do nothing to URL without a Query String (hat tip #eggyal)
if (strpos($this->url, '?') === false) return $this->url;
// Split URL into base URL and Query String
list($url, $query) = explode('?', $this->url, 2);
// Parse Query String into array
parse_str($query, $params);
// Remove the parameter in question
unset($params[$param]);
// Rebuild Query String
$query = http_build_query($params);
// Piece URL back together and save to object
$this->url = $url . ($query ? "?$query" : '');
// Return URL in case developer really just wants an instant result
return $this->url;
}
}
Caveat: This will not retain any URL fragments (ie #fragment) In the case of HTTP_REFERER this should not matter as most browsers won't send that anyway. If that is functionality you decide you need, then it can easily be coded in at a later time.
Namespacing: For simplicity's sake, the code examples are not namespaced. However, for real life implementations, I suggest getting in the habit of using "namespace App;" at the top of any in-house class files and calling the class as such "new App\Class();" Especially if you're using or might ever use any third-party code in your project.
Performance Note: Don't worry about performance until it becomes a problem... your time is always the biggest bottleneck... not PHP. Value your time more than PHP's time! PHP will always be faster than spending your time copy pasta coding. Encapsulate your code (in classes or functions) and have time left to go outside and enjoy the weather now and in the future when you need to re-factor.

use preg_replace
preg_replace('/^&reserved=true/', '', $_SERVER['HTTP_REFERER']);

Related

Hand over "data/params" on reroute(); in "fat free framework"

Im looking for an elegant way to hand over data/params when using $f3->reroute();
I have multiple routes configured in a routes.ini:
GET #sso: /sso/first [sync] = Controller\Ccp\Sso->first, 0
GET #map: /map [sync] = Controller\MapController->second, 3600
Now I reroute(); to #map route, from first();
class Sso {
public function first($f3){
$msg = 'My message!';
if( !empty($msg) ){
$f3->reroute('#map');
}
}
}
Is there any "elegant" way to pass data (e.g. $msg) right into $MapController->second(); ?
I don´t want to use $SESSION or the global $f->set('msg', $msg); for this.
This isn't an issue specific to fat-free-framework, but web in general. When you reroute, you tell the browser to redirect the user's browser page using a 303 header redirect code.
Take a minute to read the doc regarding re-routing: http://fatfreeframework.com/routing-engine#rerouting
There seems to be some contradicting information in your question, which leads me to question the purpose of what you are trying to achieve.
If you are rerouting, you can either use the session, cookies, or use part of the url to pass messages or references to a message.
If you do not need to redirect, but just want to call the function without changing the passed parameters, you could abstract the content of the function and call that function from both routes. You could also use the $f3 globals, which are a great way of passing data between functions in cases where you don't want to pass the data using the function call. is there a reason why you don't want to to use this? The data is global for the single session, so there is no security concern, and the data gets wiped at the end of the request, so there is very little extra footprint or effect on the server.
If you're alright with not using #map_name in re-routes you can do something like this:
$f3->reroute('path/?foo=bar');
Not the prettiest I'll admit. I wish $f3->reroute('#path_name?foo=bar') would work.

How to remove any given $_GET variable from URL with PHP?

I'm puttings filters in links with GET variables like this: http://example.com/list?size=3&color=7 and I'd like to remove any given filter parameter from URL whenever a different value for that particular filter is selected so that it doesn't, for example, repeat the color filter like so:
http://example.com/list?size=3&color=7&color=1
How can I if(isset($_GET['color'])) { removeGet('color'); } ?
You can use parse_url and parse_str to extract parameters like in example below:
$href = 'http://example.com/list?size=3&color=7';
$query = parse_url( $href, PHP_URL_QUERY );
parse_str( $query, $params );
// set custom paramerets
$params['color'] = 1;
// build query string
$query = http_build_query( $params );
// build url
echo explode( '?', $href )[0] . '?' . $query;
In this example explode() is used to extract the part of the url before the query string, and http_build_query to generate query string, you can also use PECL http_build_url() function, if you cannot use PECL use alternative like in this question.
You can't remove variables from GET request, just redirect to address without this var.
if (isset($_GET['color'])) {
header ('Location: http://www.example.com/list?size=' . $_GET['size']);
exit;
}
Note: in URL http://example.com/list?size=3&color=7&color=1 is just one $_GET['color'], not two. Only one of them is taken. You can check, is $_GET['key'] exists, but you don't know how many of them you have in your URL
So, assuming I'm understanding your question correctly.
Your situation is as follows:
- You are building URLs which you put into a webpage as a link ( <a href= )
- You are using the GET syntax/markup (URL?key=value&anotherkey=anothervalue) as a way to assign filters of some sort which the user then receives when they click on a given link
What you want is to be able to modify one of the items in your GET parameter list (http://example.com/list?size=3&color=7&color=1) so you have only one filter key but you can modify the filter value. So instead of the above you would start with: (http://example.com/list?size=3&color=7) but after changing the color 'filter' you would instead have http://example.com/list?size=3&color=1).
Additionally you want to do the above in PHP, (as opposed to JavaScript etc...).
There are a lot of ways to implement the change and the most effective way to do it depends on what you are already doing, most likely.
First, if you are dynamically producing the HTML markup which includes the links with the filter text, (which is what it sounds like), then it makes the most sense to create a PHP array to hold your GET parameters, then write a function that would turn those parameters into the GET string.
New filters would appear when a user refreshed the page, (because, if you are dynamically producing the HTML then a server request is required to rebuild the page).
IF, however, you want to update the link URLs on a live page WITHOUT a reload look into doing it with JavaScript, it will make your life easier.
NOTE: It is likely possible to modify the page, assuming the links are hard coded, & the page is hard coded markup, by opening the page as a file in PHP & making the appropriate change. It's my opinion that this would be a headache and not worth the time & effort AND it would still require a page reload (which you could NOT trigger yourself).
Summary
If you are writing dynamic pages with PHP it shouldn't be a big deal, just create a structure (class or array) and a method/function to write that structure out as a GET string. The structure could then be modified according to your desire before generating the page.
If, however, you are dealing with a static page, I recommend JavaScript (either creating js structures to allow a user to dynamically select filters or utilizing AJAX to build new GET parameter lists with PHP and send that back to the javascript).
(NOTE: I am reminded that I have done something along the lines of modifying links on-the-fly for existing pages by intercepting them before they are displayed to the user [using PHP] but my hands were tied in other areas and I would not recommend it if you have a choice AND it should be noted that this still required a reload...)
Try doing something like this in your back-end script:
$originalValues=array();
foreach($_GET as $filter=>$value)
{
if(empty($originalValues[$filter]))
$originalValues[$filter] = $value;
}
This may do what you want, but it feels hackish. You may want to revise your logic.
Good luck!
just put a link/button send the user to index... like this.
<a class="btn btn-primary m-1" href="http:yoururl/index.php" role="button">Limpar</a>

Using URL as a condition on php

I want to show on my site an element depending on my site's url.
Currently i have the following code:
<?php
if(URL matches)
{
echo $something;
}
else
{
echo $otherthing;
}
?>
I wanted to know how do I get the URL on the if condition, because I need to have only one php archive to show on many diferent pages
EDIT: The solution provided by Rixhers Ajazi doesnt work for me, when i use ur code i get the same URI for both of my pages, so the if sentence always goes by the else side, is any way to get the exact string u can see on the browser to the PHP code
http://img339.imageshack.us/img339/5774/sinttulocbe.png
This is the place where it changes but, the URL i get on both sides is equal, im a little bit confused
To get the URL, use:
$url = http://$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Use following syntax with URL
http://mysite.com/index.php?var1=val&var2=val
Now you can get the values of variables in your $_GET variable and use in if condition like
if($_GET['var1'])
You can do so by using the $_SERVER method like so :
$url = $_SERVER['PHP_SELF']; or $url = $_SERVER['SERVER_NAME'];
Read up on this more here
if($url == 'WHATEVER')
{
echo $something;
}
else
{
echo $otherthing;
}
?>
You can use different variables, e.g., $_SERVER["PHP_SELF"], or $_SERVER["REQUEST_URI"]. The first one contains the path after the server name and until a possible ? in the URL (the part with the GET parameters is excluded). The second one contains also the GET parameters. You can also retrieve the hostname used to connect to the server (in case you have a virtual host situation) using $_SERVER["HTTP_HOST"]. Therefore by concatenating all these you can reconstruct the full URL (if you really need it, maybe the script name is enough).

How to encode a URL as a CakePHP parameter

I would like to create a bookmarklet for adding bookmarks. So you just click on the Bookmark this Page JavaScript Snippet in your Bookmarks and you are redirected to the page.
This is my current bookmarklet:
"javascript: location.href='http://…/bookmarks/add/'+encodeURIComponent(document.URL);"
This gives me an URL like this when I click on it on the Bookmarklet page:
http://localhost/~mu/cakemarks/bookmarks/add/http%3A%2F%2Flocalhost%2F~mu%2Fcakemarks%2Fpages%2Fbookmarklet
The server does not like that though:
The requested URL /~mu/cakemarks/bookmarks/add/http://localhost/~mu/cakemarks/pages/bookmarklet was not found on this server.
This gives the desired result, but is pretty useless for my use case:
http://localhost/~mu/cakemarks/bookmarks/add/test-string
There is the CakePHP typical mod_rewrite in progress, and it should transform the last part into a parameter for my BookmarksController::add($url = null) action.
What am I doing wrong?
I had a similar problem, and tried different solutions, only to be confused by the cooperation between CakePHP and my Apache-config.
My solution was to encode the URL in Base64 with JavaScript in browser before sending the request to server.
Your bookmarklet could then look like this:
javascript:(function(){function myb64enc(s){s=window.btoa(s);s=s.replace(/=/g, '');s=s.replace(/\+/g, '-');s=s.replace(/\//g, '_');return s;} window.open('http://…/bookmarks/add/'+myb64enc(window.location));})()
I make two replacements here to make the Base64-encoding URL-safe. Now it's only to reverse those two replacements and Base64-decode at server-side. This way you won't confuse your URL-controller with slashes...
Bases on poplitea's answer I translate troubling characters, / and : manually so that I do not any special function.
function esc(s) {
s=s.replace(/\//g, '__slash__');
s=s.replace(/:/g, '__colon__');
s=s.replace(/#/g, '__hash__');
return s;
}
In PHP I convert it back easily.
$url = str_replace("__slash__", "/", $url);
$url = str_replace("__colon__", ":", $url);
$url = str_replace("__hash__", "#", $url);
I am not sure what happens with chars like ? and so …
Not sure, but hope it helps
you should add this string to yout routs.php
Router::connect (
'/crazycontroller/crazyaction/crazyparams/*',
array('controller'=>'somecontroller', 'action'=>'someaction')
);
and after that your site will able to read url like this
http://site.com/crazycontroller/crazyaction/crazyparams/http://crazy.com

translate from ASP to PHP

I am being forced to work with a database company that only support ASP.NET, despite my employers being well aware that I only code in PHP and the project doesn't have the time to learn the new syntax.
Documentation is scant, and meaning in thin on the ground. Can someone help translate what is happening in this script, so that I can think about doing it in PHP
<%
QES.ContentServer cs = new QES.ContentServer();
string state = "";
state = Request.Url.AbsoluteUri.ToString();
Response.Write(cs.GetXhtml(state));
%>
QES.ContentServer cs = new QES.ContentServer();
the code instantiates the class method ContentServer()
string state = "";
Explicit the type var state as string
state = Request.Url.AbsoluteUri.ToString();
here you get the REQUEST URI (as in php) the path and convert it to one line string and put in the before mentioned string statte var
Response.Write(cs.GetXhtml(state));
and here return the message without refresh the page (ajax).
The Request object wraps a bunch of information regarding the request from the client i.e. Browser capabilities, form or querystring parameters, cookies etc. In this case it is being used to retrieve the absolute URI using Request.Url.AbsoluteUri.ToString(). This will be the full request path including domain, path, querystring values.
The Response object wraps the response stream sent from the server back to the client. In this case it is being used to write the return of the cs.GetXhtml(state) call to the client as part of the body of the response.
QES.ContentServer appears to be a third party class and is not part of the standard .NET framework so you would have to get access to the specific API documention to find out what is for and what the GetXhtml method does exactly.
So, in a nutshell, this script is taking the full URI of the request from the client and returning the output from the GetXhtml back in the response.
It would look like this in PHP:
<?php
$cs = new QES_ContentServer(); //Not a real php class, but doesn't look like a native ASP.NET class either, still, it's a class instantiation, little Google shows it's a class for Qwam E-Content Server.
$state = ""; //Superfluous in PHP, don't need to define variables before use except in certain logic related circumstances, of course, the ASP.NET could have been done in one line like "string state = Request.Url.AbsoluteUri.ToString();"
$state = $_SERVER['REQUEST_URI']; //REQUEST_URI actually isn't the best, but it's pretty close. Request.Url.AbsoluteUri is the absolute uri used to call the page. REQUEST_URI would return something like /index.php while Request.Url.AbsoluteUri would give http://www.domain.com/index.php
//$state = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; or something similar might be better in this case given the above
echo $cs->GetXhtml($state); //GetXhtml would be a method of QES.ContentServer, Response.Write is like echo or print.
?>

Categories