How to determine the environment in a cronjob - php

I've got an issue on how to determine the application's environment during a cronjob.
I have currently have 2 environments: a production and a testing environment. They both use their own database.
I determine the current environment based on the URL. For example: dev.domain.com sets the environment to testing and domain.com sets it to production.
This works perfectly. However, this does not work for cronjobs. Because a cronjob does not get a domain.
How would I solve this and still keeping things dynamic?
This is what the code currently looks like:
if($_SERVER['SERVER_NAME'] == 'dev.domain.com' || $_SERVER['SERVER_NAME'] == 'domain.local') {
define('ENVIRONMENT', 'development');
}else if ($_SERVER['SERVER_NAME'] == 'domain.com'){
define('ENVIRONMENT', 'production');
}
Thanks in advance.

You can pass server name in cron job.
Example if your current php command look likes.
php a.php --uri="/foo"
It will become
SERVER_NAME=dev.domain.com php a.php --uri="/foo"

Related

Laravel - Multiple Production Environments

We have a Laravel 4.2 site based in the US that we're looking to whitelabel in Canada then the UK. I have a local and test environment for both (staging vs canada_staging, etc), and the problem I have with production is we have a lot of if conditions that checks if the environment is production (if (App::environment() === 'production') for instance). I could use production for both, but each site has its own specific configuration and language files (for instance they have provinces instead of states). Is there an easy way to overcome this situation?
Yes, you can create file app/bootstrap/environment.php on each server and define env.:
<?php
return 'production-us;
In app/bootstrap/start.php in detect env. section add this:
$env = $app->detectEnvironment(function ()
{
return require __DIR__.'/environment.php';
});
You will have unique env. on each server in the easiest way.
Related post here.

Cron Script Doesn't Work in Server Side

i have some cron files. And it was in under httpdocs. But i decided to move under cron folder. And i change the script.
config.php to ../config.php
When i call script from browser every thing works fine. But when i call from ssh i got en error undefined index : SERVER_NAME
I couldn't run cronjob. What can i do that ?
stock.php file
include_once '../config.php';
require_once CLASS_PATH.'class.product.php';
include_once INC_PATH.'functions.php';
....
config.php file
if ( !defined('ABSPATH') ) {
define('ABSPATH', dirname(__FILE__).'/');
}
define('PROTOCOL',(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? 'https' : 'http');
define('HOST', PROTOCOL.'://'.$_SERVER['SERVER_NAME']);
define('CLASS_PATH',ABSPATH.'includes/class/');
define('INC_PATH',ABSPATH.'includes/');
//if (isset($_SERVER['SERVER_NAME'])){
define('PRODUCT_IMG_PATH', 'images/product/');
//}
define('HEAD_META',ABSPATH.'view/head-meta.php');
define('NAVBAR', ABSPATH.'view/navbar.php');
define('HEADER', ABSPATH.'view/header.php');
define('FOOTER', ABSPATH.'view/footer.php');
The reason is that when you are running through ssh or command line you are in CLI mode, therefore none of those CGI variables can be used. It's recommended to use getenv() command instead which supports some of defined variables in CLI mode. However you need to configure and define them in you php.ini
You may need to look at Command line usage documentation for more details
How are you running it from cron? It seems that the server variables aren't being found when you run from terminal - which would make sense if you were php-running the file on the server. The SERVER-variables in php are set by the webserver - i.e. what answers a request over port 80 to the files in a specific location.
Here's php's documentation on server variables.
http://www.php.net/manual/en/reserved.variables.server.php
You web server is the one who fills the php $_SERVER array. I quote from the manual (http://www.php.net/manual/en/reserved.variables.server.php):
The entries in this array are created by the web server. There is no
guarantee that every web server will provide any of these; servers may
omit some, or provide others not listed here.
Obviously, if you call your script from the command line, there's no web servers to fill the $_SERVER array, and that's the reason of your problem.
To solve it, you can modify your config.php to load predefined values to the variables you need in case they don't exist. It would be something like this for every undef var:
if (!isset($_SERVER['SERVER_NAME'])) $_SERVER['SERVER_NAME']="localhost";

Environment detection in Laravel 4.1+

Laravel 4.1 removed the feature to use the domain for detecting what environment the app is running in. Reading the docs they now suggest using host names. However, to me that seems cumbersome if you are working in a team. Should everyone change the bootstrap/start.php file and add their own host name to be able to run the app in a dev environment? Also, what if you want to have two different environments on the same machine?
How to best detect the environment if you are working in a team in Laravel 4.1+?
Here is my settings from bootstrap/start.php file:
$env = $app->detectEnvironment(function() use($app) {
return getenv('ENV') ?: ($app->runningInConsole() ? 'local' : 'production');
});
Instead of default array, this method in my case is returning closure with ternary. That way I got more flexibility in choosing desired environment. You can use switch statement also. Laravel will read return value and configure itself.
With getenv native function, I am just listening for a given environment. If my app is on the server, then it will "pick" server configurations. If locally, then it will pick local (or development)
And don't forget to create custom directories for you environemnts in app/config
There is also testing env, which is choosen automatically, every time you are unit testing app.
Laravel makes working with environments really fun.
UPDATE:
With environments we are mostly cencerned about db credentials.
For production I use Fortrabbit, so when configuring new app on server, fortrabbit is generating those values for me. I just need to declare them. e.g. DB of just database or db... Or DB_HOST or HOST ...
Locally, those values are the one you use for your localhost/mysql settings.
Update:
In Laravel 5.0 environment detection is no longer needed in the same way. In the .env file you can simply have a variable for which environment the app should run in.
Old answer for Laravel <= 4.2
What I ended up doing is very close to what carousel suggested. Anyway, thought I would share it. Here is the relevant part of our bootstrap/start.php file:
$env = $app->detectEnvironment(function ()
{
if($app->runningInConsole())
return "development";
$validEnvironments = array("development", "staging", "production");
if (in_array(getenv('APP_ENV'), $validEnvironments)) {
return getenv('APP_ENV');
}
throw new Exception("Environment variable not set or is not valid. See developer manual for further information.");
});
This way all team members have to declare an environment variable somewhere. I haven't really decided if throwing an exception if the environment variable is not set or just default to production is the best thing. However, with the above, it's easy to change.
For me, I just use 'dev' => '*.local' and it works. I haven't 100% tested in a team situation but I think it'd work (big assumption alert:) assuming you're on OSX and get the default Alexs-iMac.local-like hostname.
As for faking an environment, I'm not sure it's really supported. It'll be doable, but in general the whole point of environments is that dev has entirely different needs to production and the two are mutually exclusive. Having the ability to switch on one physical environment seems counter to that goal.
Laravel 4.1 and 4.2 detects the environments through the machine names specified in the "bootstrap/start.php" file.
For example, in my case the config becomes:
$env = $app->detectEnvironment(array(
'local' => array('Victor.local', 'Victor-PC'),
));
This means that Laravel will use the 'local' environment settings for both machines: 'Victor.local' (a Mac) and 'Victor-PC' (Windows).
This way you can regsiter several machines to work as local environment. Other environments can be registered too.
In order to know the current machine name, you can use the following PHP code:
<?php echo gethostname(); ?>
Hope it helps!
You can use something like this:
$env = $app->detectEnvironment(function(){
if($_SERVER['HTTP_HOST'] == 'youdomain_local')
{
return 'local';
}elseif($_SERVER['HTTP_HOST'] == 'youdomain_team')
{
return 'team';
}else{
return 'production';
}
});
what i did is, make dir app/config/local and use code
$env = $app->detectEnvironment(function(){
return $_SERVER['HTTP_HOST']=="localhost"?"local":"production";
});
For localhost and online.
I didn't like that production was default, so I made it anything other than live server will go to local configs:
in bootstrap/start.php :
$env = $app->detectEnvironment(function(){
if (gethostname() !== 'live_server_hostname'){
return 'local';
} else {
return 'production';
}
});
In bootstrap/start.php define this:
$env = $app->detectEnvironment(function() use($app) {
$enviromentsHosts = [
'localhost',
'local',
];
if ($app->runningInConsole() || in_array($app['request']->getHost(), $enviromentsHosts)) {
return 'local';
} else {
return 'production';
}
});
I believe it is better to use only the resources of Laravel 4

How to know or ensure that a php page is only called by localhost?

Should we check $_SERVER['REMOTE_SERVER'] or what?
This will do the trick:
if($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
// do something
}
Be careful you don't rely on X_FORWARDED_FOR as this header can be easily (and accidentally) spoofed.
The correct way to do this would be to set an environmental variable in your server configuration and then check that. This will also allow you to toggle states between a local environment, staging and production.
This code will help you.
<?php
if($_SERVER['SERVER_NAME'] == 'localhost')
{
echo 'localhost';
}
?>
Check
$_SERVER['REMOTE_ADDR']=='127.0.0.1'
This will only be true if running locally. Be aware that this means local to the server as well. So if you have any scripts running on the server which make requests to your PHP pages, they will satisfy this condition too.
refered from :
How to check if the php script is running on a local server?

How to check if the php script is running on a local server?

Is it possible to check if the website (php) is running locally or on a hosted server?
I want to enable some logs if the website is running locally and I don't want these to appear on the site online..
I can set a variable $local=1; but I'll have to change that before uploading.. is there anyway to automate this task?
Local Server : WampServer 2.0 / Apache
WebServer: Apache
Check $_SERVER['REMOTE_ADDR']=='127.0.0.1'. This will only be true if running locally. Be aware that this means local to the server as well. So if you have any scripts running on the server which make requests to your PHP pages, they will satisfy this condition too.
I believe the best approach is to 'fake' a testing mode, which can be done by creating a file in your local environment.
When I used this approach I created an empty text file called testing.txt and then used the following code:
if (file_exists('testing.txt')) {
// then we are local or on a test environment
} else {
// we are in production!
}
This approach is 100% compatible with any Operating System and you can use several test files in case you want a more granular approach (e.g. development.txt, testing.txt, staging.txt, or production.txt) in order to customise your deployment process.
You should automate deployment
This is not directly the answer to your question, but in my opinion the better way. In an automated deployment process, setting a variable like $local = true, like other configuration values (for example your db-connection), would be no manual, error prone, task.
Checking for 'localness' is in my opinion the wrong way: you dont want to show your logs to every local visitor (a Proxy may be one), but only when deployed in a testing environment.
A popular tool for automated deployment is Capistrano, there should be PHP-Centric tools too.
Just in case this is useful to anybody, I made this function as the above answers didn't really do what I was looking for:
function is_local() {
if($_SERVER['HTTP_HOST'] == 'localhost'
|| substr($_SERVER['HTTP_HOST'],0,3) == '10.'
|| substr($_SERVER['HTTP_HOST'],0,7) == '192.168') return true;
return false;
}
$whitelist = array(
'127.0.0.1',
'::1'
);
if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
// not valid
}
I have build this function that checks if current server name has name server records, normally local server don't has.
<?php
function isLocal ()
{
return !checkdnsrr($_SERVER['SERVER_NAME'], 'NS');
}
?>
Your remote server is unlikely to have a C drive! So I run with this:
//Local detection
$root = $_SERVER["DOCUMENT_ROOT"];
$parts = explode("/",$root);
$base = $parts[0];
$local = false;
if ($base == "C:") {
$local = true; //Change later for if local
}

Categories