To use PHP to check if the page was accessed without SSL you can check the port number.
// Most encrypted web sites use port 443
if ($_SERVER['SERVER_PORT']==443) {
// Tell browser to always use HTTPS
header('strict-transport-security: max-age=126230400');
}
elseif (isset($_SERVER['SERVER_PORT'])) {
// Redirect current page to https with 301 Moved Permanently response
header('location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
exit;
}
This assumes your server is configured with the SERVER_PORT environment variable and that the encrypted version of your web site is hosted on port 443. It also assumes your server is not behind a load balancer. If your server is behind a load balancer, you might need a more advanced solution such as this one that does not rely on custom HTTP headers which can vary from one load balancer to the next:
// Set secure cookie to detect HTTPS as cookie will not exist otherwise.
header('set-cookie: __Secure-https=1; expires='.substr(gmdate('r', ($_SERVER['REQUEST_TIME']?: time())+126230400), 0, -5).'GMT; path=/; secure', false);
// Tell browser to always use HTTPS
header('strict-transport-security: max-age=126230400');
if (!isset($_COOKIE['__Secure-https']) && !isset($_GET['https'])) {
// Redirect to secure version of site and add https=1 GET variable in case cookies are blocked
header('location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].(strpos($_SERVER['REQUEST_URI'], '?')===false? '?': '&').'https=1', true, 307);
exit;
}
If the above solution is problematic because it adds ?https=1 to your URL then you can always use JavaScript. Add this to the top of your page right after <head>:
<script>
// This will redirect all requests from http to https
if (location.protocol=='http:') {
location.replace('https://'+location.host+location.pathname+location.search)
document.write('<noscript>');// hack to stop page from displaying
}
</script>
Then add the following to your PHP script if you want browsers to remember to always use HTTPS when accessing your site:
header('strict-transport-security: max-age=126230400');
or if you want browsers to have your preferences preloaded use:
header('strict-transport-security: max-age=126230400; preload');// HTTPS will always be used!
If you use the preload feature you will need to submit your web site to be included in Chrome's HSTS preload list so that browsers come preloaded with your web site preferences. If you use preload, it's also advisable to host your site on the naked domain without the www. This is because it's usually easier for most people to type in your domain without the www, and with preload your web site loads without the need of a tedious redirect since https is already the default.