I'm making a web app and I'm checking for the presence of a configuration file to determine whether or not to run the installation script. However, since it is a web app, I have no idea at what URL this script will be stored.
Is there any way to redirect a page, either using PHP or HTML, to a relative file?
Thanks in advance!
You can reconstruct the URL of the currently executing script using the 'SCRIPT_NAME' variable set by mod_php. From there it's just a matter of relative path manipulation to construct the absolute URL of the script you want to redirect to.
<?php
$scheme = $_SERVER['HTTPS'] ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$basedir = dirname($_SERVER['SCRIPT_NAME']);
header("Location: {$scheme}://{$host}{$basedir}/redirect_target_page.php");
I found that I could just do this:
header('Location: ./install.php')
in PHP you can use header('Location: http://www.example.com/'); but it must be used with full url, not the relative one, so you just need to build full url from your relative url and use header
Related
I am trying to use a php script that redirects visitors based on certain criteria. I use the script succesfully on an apache server however, I am experimenting with nginx and php-fpm and the same script doesn't seem to be working as it should.
header("Location: $url");
exit();
The strange thing is it appears to be appending the URL I am trying to redirect to to the original URL so the URL it tries to forward to looks like:
originaldomain.com/redirectdomain.com.
Has anybody ever come across this before where it as appending the redirect domain to the original URL instead of redirecting straight to it?
Please let me know if you need any further information to help.
You need to make sure the URL has http:// at the beginning of it, otherwise it thinks it's going to a path on your domain, and not a redirect to an actual site.
$url has to begin with http:// or https://
if (strpos($url, 'http') === 0 ) {
$newurl = $url;
} else {
$newurl = "http://" . $url;
}
Then just use $newurl in you header request :)
If the above answers are not yet fixed header redirect, you need to check in your php.ini file output_buffering on or off or set limit.
output_buffering = On
I have a form. After the form is filled out and the user clicks the submit button the user is taken to a thank you page. On the thank you page is a link (anchor tag) for the user to get to her home page. It works fine 19 out of 20 times.
The problem is, sometimes php skips the thank you page and goes directly to the home page. How is this possible? How is php clicking the link? I've gone over the code and it's completely correct. There is no javascript, just html and css.
Like I said, it doesn't do it every time and I guess it's not a bid deal I'd just like to understand what's going on. I'm using a simple header redirect like so
$url = "thanks/";
header("Location: $url");
exit();
What do you guys think is going? Is there any way to stop it?
Thanks
The RFC for the Location header requires a single absolute URI. This is also pointed out in the PHP manual in the notes section:
HTTP/1.1 requires an absolute URI as argument to ยป Location: including
the scheme, hostname and absolute path, but some clients accept
relative URIs. You can usually use $_SERVER['HTTP_HOST'],
$_SERVER['PHP_SELF'] and dirname() to make an absolute URI from a
relative one yourself
The problem may be to do with the fact that you're passing non standard headers to the browser. Browsers interpret the malformed header string differently and don't always behave as expected. Again as demonstrated in the PHP manual you should create an absolute URI, not an absolute or relative path before passing it to the header() function.
/* Redirect to a different page in the current directory that was requested */
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'mypage.php';
header("Location: http://$host$uri/$extra");
exit;
I have a website that was written assuming http:// is one and only protocol forever. Now i bought a SSL certificate but when i visit site calling it with https:// i get info in browsers that part of site is insecure. As i found i have some JS, CSS and images and files that i refer to using http:// in the HTML of the site.
So what is best practice to enable full https? Should i change my website in every place when i refer to image, CSS or JS, check if site was loaded with http or https and load the resource with according protocol? It seems like a lot of work for me and bit error prone. Is there any other way, easier to make the whole site fully secure?
Rather than linking to your css, js, and images with http://yoursite.com/css/file.css just use relative paths such as /images/image.jpg and /css/file.css this way it will work with both http and https, also if you change domains or copy your content to another domain, you shouldn't have to change all those links either.
Use relative paths. If you are pointing to something that is on the same site as yours, then you should not be using http://
If for some reason you still need to have http:// then just switch them all to https://. An http:// will never complain because it is pointing to https:// stuff, but an https:// page will complain if it is pointing to non-https stuff.
If you are pointing to content outside of your control, on another site for example, then you need to hope that you can get at that content via https instead. If you can't, then you're hosed and you either need to live with the error, get the content from somewhere else, or proxy the content through your own https connection.
To complement #drew010 's answer, you could use other domains and still refer to the current protocol with //, something like:
<img src="/pics/home.png" />
<img src="//my-cdn.com/pics/info.png" />
The latter example will point to https://.. from https://your-site.com and http://... from http://your-site.com.
the best practice would be either using relative path rather than absolute but sometimes absolute is a better option so you can do the following :
as I can imagine you have a file called config.php or common.php (a file that stores your common used vars and you include it in every page), so put this code there :
function selfURL() {
$s = empty($_SERVER["HTTPS"]) ? ''
: ($_SERVER["HTTPS"] == "on") ? "s" : "";
$protocol = strleft(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $protocol."://".$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
}
function strleft($s1, $s2) {
return substr($s1, 0, strpos($s1, $s2));
}
and then you can assign a var called $http to get the value of the function like :
$http = selfURL();
and then whenever you want to include anything like images, css, etc do something like :
<img src="<?=$http?>images/sample.png" />
this method is reliable as it works in any situation.
I have two php pages. I want to fetch b.php in a.php.
In my a.php:
$ch = curl_init("b.php");
echo(curl_exec($ch));
curl_close($ch);
Doesn't work;
But:
$ch = curl_init("www.site.com/b.php");
echo(curl_exec($ch));
curl_close($ch);
is OK. I'm sure a.php is under www.site.com.
Why curl can't work with relative path? Is there a workaround?
Curl is a seperate library which does not really know anything about webservers and where it's coming from or (philosophicaly) why it is there. So you may 'fake' relative urls using one of the two _SERVER variables:
$_SERVER['SERVER_NAME']
The name of the server host under which the current script is executing. If the script is running on a virtual host, this will be the value defined for that virtual host.
$_SERVER['HTTP_HOST']
Contents of the Host: header from the current request, if there is one.
See: http://php.net/manual/en/reserved.variables.server.php
Edit update:
I thought a moment longer about this: do you really need to fetch it with curl?
You usually may also fetch any output of another script like this and save the overhead of loading it through a new http request:
ob_start();
require "b.php";
$output = ob_get_clean();
How about taking the domain from HTTP_HOST?
$domain = $_SERVER['HTTP_HOST'];
$prefix = $_SERVER['HTTPS'] ? 'https://' : 'http://';
$relative = '/b.php';
$ch = curl_init($prefix.$domain.$relative);
echo(curl_exec($ch));
curl_close($ch);
cUrl needs an absolute URI to operate on.
A relative URI does not work because there is no base URI given to which that relative URI is absolute to.
You can however, if you have both the base URI and the relative URI, create the absolute URI of the relative URI and use it with cUrl.
See 12.4.1 Resolving relative URIs.
A PHP class that can build an absolute URI based on a relative URI and it's base is the Net_URL2 package in Pear.
cURL would primarily be used to retrieve data from external domains, therefore it wouldn't make too much sense to allow relative paths. The easiest thing to do would just be to append your current domain to the URL.
$domain = $_SERVER['HTTP_HOST'] . "/";
$ch = curl_init($domain . "b.php");
echo(curl_exec($ch));
curl_close($ch);
CURL has absolutely no knowledge of its operating environment. There is no way for it to know where 'b.php' is. Should it turn that into example.org/b.php or some.wonky.multi.level.domain.co.uk/b.php?
Even treating it as a local file reference would be useless... CURL wouldn't know that a .php file is actually a PHP script. Even if it did a local file fetch, you'd just get PHP source, not the output of the script after PHP's run it. What if you've got a site like arstechnica.com where all its pages are actually .ars scripts? Is that .asp? .aspx? .html? PHP script? perl? ruby?
So.. simple answer: you must always specify a complete URL, with protocol, for CURL to operate on.
Basically, I want my script to output its absolute URL, but I don't want to statically program it into the script. For example, if my current URL is http://example.com/script.php I want to be able to store it as a variable, or echo it. i.e. $url = http://example.com/script.php;
But if I move the script to a different server/domain, I want it to automatically adjust to that, i.e. $url = http://example2.com/newscript.php;
But I have no idea how to go about doing this. Any ideas?
$url = "http://" . $_SERVER['HTTP_HOST'] . '/script.php';
If there's a possibility the protocol will change as well (i.e. https instead of http), use this:
$url = ($_SERVER['HTTPS'] ? "https://" : "http://") . $_SERVER['HTTP_HOST'] . '/script.php';
$_SERVER['HTTP_HOST'] and $_SERVER['SCRIPT_NAME'] contain this information.
UPDATE: As #Col. Shrapnel points out, SCRIPT_NAME returns the actual path of the script relative to the host, not the requested URL, which may be different if using URL rewrite. Also, unlike REQUEST_URI, it doesn't include the possibly appended variables.
Note that SCRIPT_NAME is equivalent in content to PHP_SELF, the difference is that:
SCRIPT_NAME is defined in the CGI 1.1
specification, and is thus a standard.
However, not all web servers actually
implement it, and thus it isn't
necessarily portable. PHP_SELF, on the
other hand, is implemented directly by
PHP, and as long as you're programming
in PHP, will always be present.
by bet (:
$_SERVER['HTTP_HOST'] and $_SERVER["REQUEST_URI"];
however, $_SERVER['HTTP_PORT'] and $_SERVER['HTTPS'] could be used in the critical case
however, most of time you do not need all of these, save for $_SERVER["REQUEST_URI"]
because browser knows the rest already: port, host and everything.
Try using
$url = "http://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}";
I have a library that helps me do this across webservers and is also agnostic to mod_rewrite.
The library is called Bombay: http://github.com/sandeepshetty/bombay
To use it you need to do this:
<?php
require '/path/to/bombay.php';
requires ('uri');
echo absolute_uri('script.php');
//prints http://example.com/script.php if hosted on example.com and accessed over http
//prints https://example2.com/script.php if hosted on example2.com and accessed over https
?>
You could also study the code, and take what you need.