Detect URL that app is being accessed from - php

I am currently developing a PHP application that is (hopefully) going into production use soon.
What I'm needing help with is detecting what URL the app is being accessed on ie dev.local, testing.domain.com or app.domain.com and then using the correct MySQL DB, ie app_test for dev and testing and app_prod for the production server.
Along with that, I also want to be able to modify the internal URLs to match (several emails are sent that also need to be tested with the correct URL).
I remember seeing some stuff about it before but am not able to find it any more.

Get full url of page
function request_url() {
$result = '';
$default_port = 80;
if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']=='on')) {
$result .= 'https://';
$default_port = 443;
} else {
$result .= 'http://';
}
$result .= $_SERVER['SERVER_NAME'];
if ($_SERVER['SERVER_PORT'] != $default_port) {
$result .= ':'.$_SERVER['SERVER_PORT'];
}
$result .= $_SERVER['REQUEST_URI'];
return $result;
}
I think you will be enough: $_SERVER['SERVER_NAME']

Easy way to do that ......
Define environment constants in constants.php file
// constants.php
define('ENVIRONMENT', 'development');
//define('ENVIRONMENT', 'production'); // uncomment this when your going to live your project
define general functions in general.php
// general.php
include "constants.php";
function is_production()
{
if(ENVIRONMENT == "production")
{
return TRUE;
}
return FALSE;
}
function is_development()
{
if(ENVIRONMENT == "development")
{
return TRUE;
}
return FALSE;
}
Now you can us that functions in your database connection files and select your database and base url
// in db.php
include "general.php";
if(is_production())
{
$conn = mysql_connect("host1","username1","password1");
mysql_select_db("db1",$conn);
define('BASE_URL', 'http://domain.com');
}
else if(is_development())
{
$conn = mysql_connect("host2","username2","password2");
mysql_select_db("db1",$conn);
define('BASE_URL', 'http://testing.domain.com');
}
Now You can use that BASE_URL constant and you have database connection as you want
This general overview but you can implement in your project as your standered.. :)

Related

How do i load different views?

In my MY_Controller.php, I want to detect user device and the requested domain name. Domain names I am using on same app are: www.seeme.tld and m.seeme.tld, also I am using $this->detect().
So this is what I did:
<?php
if($this->detect->isMobile() || $_SERVER['HTTP_HOST'] === MOBILE_URL){
$this->config->set_item('base_url', MOBILE_URL);
}elseif(!$this->detect->isMobile() || $_SERVER['HTTP_HOST'] != MOBILE_URL){
$this->config->set_item('base_url', WEBSITE_URL);
}
?>
I have 2 folders in application/views folder : PC(for pc users) and Mobile(for mobile users)
In order to load views, I used this code in my fetch() function:
public function fetch($view, $data = array, $other_vars = false)
{
if(base_url() === MOBILE_URL || $this->_ci->detect->isMobile()){
$f = 'Mobile/';
}elseif(!$this->_ci->detect->isMobile() || base_url() != MOBILE_URL){
$f = 'PC/';
}
return $this->_ci->load->view($f.'contents/'.$view, $data, true);
}
When I use a mobile device or the visit m.seeme.tld with a mobile device, I get mobile contents. But when I visit visit m.seeme.tld with a PC instead of getting mobile contents, I rather get PC contents. Please help me solve this issue!
Changing config array could be problematic sometimes: How to override config's array within a controller in CodeIgniter?. Also you are doing double check (in controller and in the function).
I archieve similar behaviour with doing this way:
YOURCONTROLLER.PHP __construct():
if ($this->detect->isMobile() || $_SERVER['HTTP_HOST'] === MOBILE_URL){
define('IS_MOBILE', TRUE);
}else{
define('IS_MOBILE', FALSE);
}
then you could use to load the view:
if (IS_MOBILE) {
$view_folder = 'Mobile/';
}else{
$view_folder = 'PC/';
}
$this->load->view($view_folder.$view, $data, TRUE);
Also you could add a single checkpoint to view if the if statment is working fine:
if ($this->detect->isMobile() || $_SERVER['HTTP_HOST'] === MOBILE_URL){
define('IS_MOBILE', TRUE);
log_message('debug', 'Im mobile browser: '.$this->detect->isMobile().' or the url is mobile:'.$_SERVER["HTTP_HOST"]);
}else{
define('IS_MOBILE', FALSE);
log_message('debug', 'Im pc');
}
Hope it helps to you.
// This works only replace the '===' with '='.
thanks for the help but i got it fixed. all i did was to first detect mobile users in MY_Controller.php and redirect them to MOBILE_URL then in my fetch() i did:
if($_SERVER['HTTP_HOST'] = MOBILE_URL){
$view_folder = 'Mobile/;
}else{ $view_folder = 'Frontend/;
}
and that's it,Paam it started working.

How to detect multiple strings in $_SERVER["SERVER_NAME"]?

I would like to detect an array of strings in $_SERVER["SERVER_NAME"] to define a constant for environment like dev/prod.
Basically, if localhost or .dev is in the URL, that would set the constant to "prod".
Here is my try but I always got "prod" even if my current url is "localhost:3000" or "site.dev":
// Define environment
$dev_urls = array(".dev", "localhost");
if (str_ireplace($dev_urls, "", $_SERVER["SERVER_NAME"]) == $_SERVER["SERVER_NAME"]){
define("ENV", "dev");
} else {
define("ENV", "prod");
}
Finally used this code which works like a charm
// Define environment
$dev_urls = array(".dev", "localhost", "beta.");
if (str_ireplace($dev_urls, "", $_SERVER["HTTP_HOST"]) != $_SERVER["HTTP_HOST"]){
define("ENV", "dev");
} else {
define("ENV", "prod");
}
The SERVER_NAME is defined in the server config, it never changes no matter what URL you use to reach that page.
I believe you want to use HTTP_HOST instead.
if ($_SERVER['HTTP_HOST'] == 'localhost' || substr($_SERVER['HTTP_HOST'], -4) == '.dev')
define('ENV', 'dev');
else
define('ENV', 'prod');
You can use array_filter() and an anonymous function to do what you're looking for.
$dev_urls = [".dev", "localhost"];
$host = $_SERVER["HTTP_HOST"];
$result = array_filter($dev_urls, function($e) use ($host) {
return strpos($host, $e) !== false;
});
if ($result) {
//development URL
} else {
//production URL
}
However, this is a substring search, which is potentially inaccurate. I'd suggest doing a full match instead.
$dev_urls = ["foo.dev", "localhost"];
$host = $_SERVER["HTTP_HOST"];
$result = array_filter($dev_urls, function($e) use ($host) {
return $host === $e;
});
if ($result) {
//development URL
} else {
//production URL
}

PHP Template Engine built by url

I am searching for a kind of dynamic template engine which I want to built by the url. So if my url is like localhost/root/this/is/the/path/to/signup.php the php code should watch for the file signup.php in the directory this/is/the/path/to/
For this time I am using arrays of the url like the following code shows:
$url = isset($_GET['url']) ? $_GET['url'] : null;
$url = rtrim($url, '/');
$url = explode('/', $url);
if (empty($url[0])) {
$url[0] = "path/startpage.php";
}
if (isset($url[2])) {
require "path/error.php";
} else if (isset($url[1])) {
$file1 = 'path/' .$url[0].'/'.$url[1].'/'.$url[1].'.php';
if (file_exists($file1)) {
require $file1;
} else {
require "error.php";
}
} else if (isset($url[0])) {
$file0 = 'path/'.$url[0].'/'.$url[0].'.php';
if (file_exists($file0)) {
require $file0;
} else {
require "path/error.php";
}
}
But with this script I have to do this for every case and this is not so nice. I want to have a solution where the code is looking for the whole url, goes to the directory and require an error or the file, if it exists.
Could you help me please?
The Titon\View library handles this quite easily: https://github.com/titon/View
If an array of paths is passed in for the template, it will generate dynamic lookup paths. https://github.com/titon/View/blob/master/src/Titon/View/View.php#L127
Example:
$view = new Titon\View\View();
$view->addPath('/path/to/views/');
$parsed = $view->run(['path', 'to', 'lookup/folder', 'templateName]);
Can also take a look at the tests to see it in action: https://github.com/titon/View/blob/master/tests/Titon/View/ViewTest.php

Geographically change domain keeping URL same

i am using this script to redirect users according to their IP.
But the problem is it redirects to homepage or only to URL i specify in the script. how can i just change the domain keeping the URL same? for example site.com/whateverpage redirected to site.au/whateverpage.
<?php
// Next two lines are for Beyond Hosting
// Don't forget to change your-domain
require_once '/home/your-domain/php/Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('/home/your-domain/php/Net/GeoIP.dat');
// Next two lines are for HostGator
require_once 'Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('GeoIP.dat');
try {
$country = $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
switch((string)$country) {
case 'AU':
$url = "http://www.site.au";
break;
case 'CA':
$url = "http://www.site.ca";
break;
default:
$url = "http://site.com";
}
if (strpos("http://$_SERVER[HTTP_HOST]", $url) === false)
{
header('Location: '.$url);
}
} catch (Exception $e) {
// Handle exception
}
?>
Add $_SERVER['REQUEST_URI'] to your redirection.
header("Location: $url/$_SERVER[REQUEST_URI]");

Functions not working on IIS

I am using this function to redirect to portfolio after user log in...
function redirect($destination)
{
//handle url
if (preg_match("/^https?:\/\//", $destination))
{
header("Location: " . $destination);
}
// handle absolute path
else if (preg_match("/^\//", $destination))
{
$protocol = (isset($_SERVER["HTTPS"])) ? "https" : "http";
$host = $_SERVER["HTTP_HOST"];
header("Location: $protocol://$host$destination");
}
// handle relative path
else
{
// adapted from http://www.php.net/header
$protocol = (isset($_SERVER["HTTPS"])) ? "https" : "http";
$host = $_SERVER["HTTP_HOST"];
$path = rtrim(dirname($_SERVER["PHP_SELF"]), "/\\");
header("Location: $protocol://$host$path/$destination");
}
// exit immediately since we're redirecting anyway
exit;
}
On using it produces SSL connection error in chrome:
Error 107 (net::ERR_SSL_PROTOCOL_ERROR): SSL protocol error.
in firefox
An error occurred during a connection to localhost:63077.
SSL received a record that exceeded the maximum permissible length.
(Error code: ssl_error_rx_record_too_long
Please don't tell me the problem...
tell me solutions or alternative
I am having a windows azure account...
It's not even working there....
Kind Regards
Vishal
PS:I know it's going to cost a lot of time ....
I really need this for my imagine cup project ..
Seems you are having issues getting the correct protocol. I'm not sure if this will work on IIS, but I generally use the following on Linux - can't imagine why it wouldn't work:
function getProtocol()
{
return $_SERVER['SERVER_PORT']=='443'?'https://':'http://';
}
That should remove most of the complexity in your code?

Categories