19

Is there a way to check if we are running a PHP script on localhost - development server or on live server - production server? Is there any PHP constant, variable, function,etc that can give me this information.

I need this to put different settings for production and development server. Now I parse the URL to see which one it is but I was wondering s there any better way to do that. My concern is that we may change the URL of the script and that may ruin my check.

I am looking few a solution with one config file and IF condition in it depending on which I will define different settings. The only problem is that I do not want to change the IF statement when there are changes on the server settings like hostname, document_root or something else that I am using to identify local/remote host.

And want to SVN update from one source without changing anything to my production server.

And I would like ideally to be able to run and CRON jobs with these settings.

Kerem
  • 11,377
  • 5
  • 59
  • 58
Yasen Zhelev
  • 4,045
  • 3
  • 31
  • 56
  • 1
    Does your local(host) testing environment use the same hostname as the production environment? – John Parker Jan 24 '11 at 16:00
  • are you using a framework where you have condensed config location? – jondavidjohn Jan 24 '11 at 16:03
  • @middaparka no, it does not,but I do not want to use hostname cause these could be changed in future and that will require manual change in code. – Yasen Zhelev Jan 24 '11 at 16:05
  • @Yasen Zhelev I was going to suggest *first* looking for a config file based on the hostname and then falling back to the "live" server defaults. If you use defines then all you need to do is a "if(!defined(..." check in the main "live" config and all should be well. (Additionally, it's not possible for the live site to use an incorrect config, as it presumbly won't respond to the "local" host names.) – John Parker Jan 24 '11 at 16:10
  • 1
    What about if you are running a CRON JOB, no hostname there. – Yasen Zhelev Jan 24 '11 at 16:13

10 Answers10

24

I use the SetEnv in my host definition to locate on which environment i am running (Dev, Stage, Production) :

<VirtualHost *:80>
(all the host info)
SetEnv SERVER_CONTEXT "dev"
</VirtualHost>

And each config file as an extra word in it : config.dev.ini, config.stage.ini, config.prod.ini, etc, ... It works like a charm.

Mikushi
  • 3,311
  • 4
  • 19
  • 22
  • 2
    What about if you are running a CRON JOB. There is no VirtualHost – Yasen Zhelev Jan 27 '11 at 09:21
  • 1
    Assuming a Unix system, i would set an environment variable (ubuntu path, might be different on other Unix system): sudo vim /etc/environment Add PHP_SERVER_CONTEXT="dev" In php: getenv("PHP_SERVER_CONTEXT"); Check your CLI php.ini file to now if PHP_ is the prefix (should be) on safe_mode_allowed_env_vars – Mikushi Jan 27 '11 at 20:28
  • good suggestion; I just put the variable into the command line, e.g. `ENVIRONMENT=dev php foo.php`, as I might run things for multiple environments on the same server, but your approach is probably easier for most setups. – El Yobo Jan 27 '11 at 21:08
  • 1
    I know I am quote annoying sometimes :) but what about Windows environment and Cron job? – Yasen Zhelev Jan 28 '11 at 12:03
  • @Yasen: Control panel->System->Advanced->Invironment Variables , that should work as well, i rarely work with PHP on Windows, but i believe PHP will read those variables, so it should work. – Mikushi Jan 28 '11 at 15:53
14
if($_SERVER["REMOTE_ADDR"]=="127.0.0.1"){
$local = True;
}else{

    $local = False;
}

EDIT

You could also check the first part of the address and see if the server is in the local network, the again assuming your server won't be in the local network when in production

armonge
  • 3,108
  • 20
  • 36
  • It is not nessesary the development server to be on my machine. – Yasen Zhelev Jan 28 '11 at 13:14
  • No, it isn't...however it is one of the most common scenarios, and that's what we actually do in my company. – armonge Jan 28 '11 at 13:15
  • This has one drawback - the remote adress may be a different one in even in your home/company network if you e.g. testing the app with your real mobile phone or ask your collegues to test the app. – Alexander Dobernig Feb 07 '21 at 08:01
6

I set an environment variable in the Apache configuration and check that. This has the advantage over using a PHP configuration file that all your application code remains exactly the same on PROD, TEST, DEV etc; no need to go and make changes after a check out, as the code just pulls the config from Apache.

To demonstrate, the following can be set in your VirtualHost configuration

SetEnv ENVIRONMENT PROD

In your PHP code, you can then check the environment with

$env = getenv('ENVIRONMENT');

If you feel the need to make this available everywhere, you can then use define, but I don't find it necessary (I use the specified environment to load the appropriate configuration files and create a read-only Singleton configuration, which is then used to check any configuration options; better than if ($env == 'PROD') {} type code, as all that logic is in the config, not in your code).

El Yobo
  • 14,823
  • 5
  • 60
  • 78
  • What about if you are running a CRON JOB. There is no VirtualHost configuration – Yasen Zhelev Jan 27 '11 at 09:22
  • 1
    Even easier, you prefix your script like `ENVIRONMENT=PROD php foo.php`. This also defines an environment variable using bash, and it's picked up with exactly the same PHP code, so no changes required in your application code. – El Yobo Jan 27 '11 at 11:23
  • No, windows makes it much more difficult; you can't define it on the fly like you can with most Linux shells. It is still possible to set environment variables, however, and I assume that they will be picked up (you'll need to check it though). Check out http://support.microsoft.com/kb/310519 or http://support.microsoft.com/kb/310519 for examples (seems OS version dependent). – El Yobo Jan 28 '11 at 12:53
  • You are incredible,. +1. You really saved my day. Is this solution 100% safe? I mean not the probability of same flag exists elsewhere, but some kind of getenv spoofing? Thanks! – Jacek Kowalewski Aug 08 '15 at 17:06
  • Well, nothing is entirely safe, but generally the loading your application configuration is going to happen pretty early in the process so there isn't huge scope for faking it. If you check that the value you get is one of the expected ones (e.g. development, production) and fall back to using a sane default if covered you should be fine. – El Yobo Aug 09 '15 at 07:26
  • I think this the best overall solution, as you only have to change your dev machine. – Rohit Gupta Mar 03 '22 at 00:43
5

Use a config file you include with a define in it

define("DEBUG",true); //set to false for live

and use that in your code, e.g.:

if(DEBUG){}
Nanne
  • 64,065
  • 16
  • 119
  • 163
4

You can try and use the global $_SERVER['SERVER_NAME'] This should tell you the host name of the system that's running the script. You could use this to determine what settings to use (depending on the system).

I don't know that this will output 'localhost' however and you may need to know your actual host name of your development machine.

Muhammad Hassaan
  • 7,296
  • 6
  • 30
  • 50
pseudoramble
  • 2,541
  • 22
  • 28
  • What about if the host name is changed, I will have to change it in all application? I am trying to avoid that. – Yasen Zhelev Jan 24 '11 at 16:16
  • Yes - If the hostname changes, you'll have to update it. It's unfortunate but true. Another thing that may help is if you keep two different versions of configuration files. Have one version be on the production machine and your own on yours. Assuming you've got some kind of version control, simply don't check your version in. This would help keep them isolated. – pseudoramble Jan 24 '11 at 16:44
2

The server has no idea what environment it is unless you tell it to. What I do is use DEFINE to set the environment. My application code is the same on every instance but the my configuration files change. That way you can use .htaccess file include the configuration files on every script and check to see what they settings are.

Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
2

I know this word may sound strange to PHP developer, but have you considered build of your project?

In PHP there's nothing to compile, however changing copied files is one of features of any build process. You could specify 2 targets: production and dev. There would be no need for any conditionals, that should work, or may work, but under some circumstances won't.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
  • This sounds like what I do. For any project requiring multiple environments, I supply a tool that generates settings in a predictable location that my application will read. The application itself does not know which environment it's deployed to. – Chris Aug 16 '16 at 05:50
1

i always make "config.php" wich i include to other php files...

it contains something like (home file):

$CONFIG['server']="dev";
$CONFIG['db_user']="root";

and thing like that... so at home i have this one up there and at server where site is running i have another one wich i dont update if not changes to it...

so on server i have something like:

$CONFIG['server']="prod";
$CONFIG['db_user']="lwu9918_admin";

and then in other php files:

include("config.php");
if($CONFIG['server']=="dev"){echo "Development";}

thing like that!

FeRtoll
  • 1,247
  • 11
  • 26
1

On dev server

* * * * * php -r cronjob.php this_is_dev

On production server

* * * * * php -r cronjob.php this_is_live

In your script

switch ($argv[1])
  case 'this_is_dev':
    // load your dev configuration
    break;

  case 'this_is_live':
    // load your live configuration
    break;

  default:
    die('invalid server');
    break;
}

since is meant for cronjob, the $argv is exist

good luck with Windows :(

ajreal
  • 46,720
  • 11
  • 89
  • 119
0

you better put the cli running program outside www directory ,for example

c:\iis\www is the public html directory

the cli file should be put under c:\iis instead

chings228
  • 1,859
  • 24
  • 24