I am working on a Laravel 4 project and I need to be able to switch between multiple configurations. So as far as I know Laravel enables me to configure envs based on URL like this in the start.php
$env = $app->detectEnvironment(array(
'local' => array('localhost'),
'stage' => array('project.stage.com'),
'prod' => array('project.production.com'),
));
And each of this configs consists of separate database connections and other configuration files. What I want is on my local environment to be able to switch between local,stage and prod, so for example if I want to connect to the prod database from my local project to test something. As far as I can understand if I want to do this I need to manualy switch the database connection strings in the local configuration. Is there any other way for switching between configurations on local level ? Hope my question was clear.
You can pass a closure to the function to determine set the environment more dynamically. You can either replicate the logic laravel uses and only use the closure in combination with gethostname() or just comment the part out and add this for testing:
$app->detectEnvironment(function(){
return 'stage';
});
Related
I am developing an API service that another site I've developed will be using. So locally when building and testing, obviously I want both local copies of the site to work. However, it seems to mix up the environment variables.
For example:
Site A has APP_URL=http://a.local
Site B has APP_URL=http://b.local
I send a GET Request (using Guzzle) from Site A code to http://b.local/test
The /test endpoing in Site B simply dumps out dump(env('APP_URL'))
Result retrieved by Site A is "http://a.local"
Expected result: "http://b.local"
So the code in Site B is running with environment variables loaded from Site A. This is an issue as Site B cannot access the correct database, it's trying to use the Site A's database.
Is this an issue with my local setup (Win10 + WAMP), PHP settings, Laravel settings?
I also encountered this issue, and it is mentioned here. The resolution for it is to run php artisan config:cache in both projects to cache configuration from .env files or patch the code from here.
are you using artisan commands to run both projects with different ports ?
php artisan serve --port=8000
php artisan serve --port=8010
You can set Environment variables in either the vhost config OR in an .htaccess file:
SetEnv APP_URL http://b.local
Apart from #Daniel Protopopov answer above there is also another way, that is also works when both Site A and Site B are Lumen.
In short just rename your DB_DATABASE variable on each side to a different name. Then change the respective variable names in the respective config/<configfilename>.php files.
So that on Site A you would have SITE_A_DB_DATABASE in .env and matching 'database' => env('API_A_DB_DATABASE', 'forge'), line in config/database.php.
Then your Site B SITE_B_DB_DATABASE will not be overwritten due to variable names are different.
The same solution applies for any .env variables which names match.
Because the command php artisan config:cache doesn't work here (closure needed in routes file config file)
LogicException : Your configuration files are not serializable.
I add phpdotenv with composer :
composer require vlucas/phpdotenv
And at the begginning of the file "/bootstrap/app.php" (after "new Illuminate\Foundation\Application"), I add :
$app->detectEnvironment(function () {
$dotenv = Dotenv\Dotenv::create(__DIR__ . '/../', '.env');
$dotenv->overload();
});
Maybe an alternative
If you are calling a Lumen 8 API from within a Laravel 6 application using GuzzleHttp and the Laravel env is being inherited to Lumen, creating config file worked for me.
In bootstrap/app.php comment below lines to prevent loading current env values from Laravel
// (new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
// dirname(__DIR__)
// ))->bootstrap();
In bootstrap/app.php add below line after $app has been created.
$app->configure('database');
Create config/database.php in lumen root folder. Return all env values needed for Lumen api in an array in the config file.
<?php
return [
'timezone' => 'UTC',
'default' => 'pdbmysql',
'connections' => [
'pdbmysql' => [
'driver' => 'mysql',
'host' => 'localhost',
'port' => '3306',
'database' => 'db2',
'username' => 'root',
'password' => 'root',
],
],
];
I am developing an API service that another site I've developed will be using. So locally when building and testing, obviously I want both local copies of the site to work. However, it seems to mix up the environment variables.
For example:
Site A has APP_URL=http://a.local
Site B has APP_URL=http://b.local
I send a GET Request (using Guzzle) from Site A code to http://b.local/test
The /test endpoing in Site B simply dumps out dump(env('APP_URL'))
Result retrieved by Site A is "http://a.local"
Expected result: "http://b.local"
So the code in Site B is running with environment variables loaded from Site A. This is an issue as Site B cannot access the correct database, it's trying to use the Site A's database.
Is this an issue with my local setup (Win10 + WAMP), PHP settings, Laravel settings?
I also encountered this issue, and it is mentioned here. The resolution for it is to run php artisan config:cache in both projects to cache configuration from .env files or patch the code from here.
are you using artisan commands to run both projects with different ports ?
php artisan serve --port=8000
php artisan serve --port=8010
You can set Environment variables in either the vhost config OR in an .htaccess file:
SetEnv APP_URL http://b.local
Apart from #Daniel Protopopov answer above there is also another way, that is also works when both Site A and Site B are Lumen.
In short just rename your DB_DATABASE variable on each side to a different name. Then change the respective variable names in the respective config/<configfilename>.php files.
So that on Site A you would have SITE_A_DB_DATABASE in .env and matching 'database' => env('API_A_DB_DATABASE', 'forge'), line in config/database.php.
Then your Site B SITE_B_DB_DATABASE will not be overwritten due to variable names are different.
The same solution applies for any .env variables which names match.
Because the command php artisan config:cache doesn't work here (closure needed in routes file config file)
LogicException : Your configuration files are not serializable.
I add phpdotenv with composer :
composer require vlucas/phpdotenv
And at the begginning of the file "/bootstrap/app.php" (after "new Illuminate\Foundation\Application"), I add :
$app->detectEnvironment(function () {
$dotenv = Dotenv\Dotenv::create(__DIR__ . '/../', '.env');
$dotenv->overload();
});
Maybe an alternative
If you are calling a Lumen 8 API from within a Laravel 6 application using GuzzleHttp and the Laravel env is being inherited to Lumen, creating config file worked for me.
In bootstrap/app.php comment below lines to prevent loading current env values from Laravel
// (new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
// dirname(__DIR__)
// ))->bootstrap();
In bootstrap/app.php add below line after $app has been created.
$app->configure('database');
Create config/database.php in lumen root folder. Return all env values needed for Lumen api in an array in the config file.
<?php
return [
'timezone' => 'UTC',
'default' => 'pdbmysql',
'connections' => [
'pdbmysql' => [
'driver' => 'mysql',
'host' => 'localhost',
'port' => '3306',
'database' => 'db2',
'username' => 'root',
'password' => 'root',
],
],
];
I have three environment folders in the config directory in Laravel: development, testing, and local. When I change the environment and hostname within the start.php file, only the production environment is recognized. Any thoughts on what I might be doing wrong here?
app/routes.php
//using this as a test to confirm that the correct environment is being used
Route::get('/', function()
{
var_dump(App::environment());
});
bootstrap/start.php:
$env = $app->detectEnvironment(array(
'development' => array('localhost'),
));
Here, the result should be "string(11) "development". Instead, it's "string(10) "production".
localhost probably isn't the real hostname of your machine.
You can find out your hostname by echoing gethostname(). Then use that instead of localhost
I've set 2 environments for my app, a local development on my machine and the production environment on the server. I set them in bootstrap/start.phplike this:
$env = $app->detectEnvironment(array(
'ariel_dev' => array('Ariels-MacBook-Pro.local'),
'production' => array('my.server.hostname'),
));
I've also set a folder under app/config/ariel_dev where I put the config files which I want to overwrite, like database.php.
I've test them, and they work pretty good. The problem is that my hostname changes when I'm home and when I'm at the office (I'm using a Mac). So the app doesn't match my dev environment and defaults to the production environment, connecting to the database of the server.
I'm doing something wrong? Doesn't it suppose to throw an error or something? Do I've to create a production folder under config?
Hope someone helps!
The default environment is always production, so you can leave it out of the array. For the other problem of having two different hostnames for you local dev, you can add them as array values of for the array local environment key.
$env = $app->detectEnvironment(array(
'ariel_dev' => array('Ariels-MacBook-Pro.local', 'myHomeHostname'),
));
Remember that production is also used as a fallback--it's pretty dangerous as you've configured it.
http://laravel.com/docs/configuration#environment-configuration states:
The default environment is always production
So try something like this:
$env = $app->detectEnvironment(array(
'productionserver' => array('my.server.hostname'),
'ariel_dev' => array('Ariels-MacBook-Pro.local'),
));
and then use productionserver as the folder instead of ariel_dev
I have Zend Framework project running on Google App Engine. Everything works great, with the exception of one thing:
I can't set an environment variable to tell Zend that I'm in development mode
Any ideas?
(I'm using PHP 5.4 in Ubuntu)
What I've tried
(Obviously I don't want to set the variable through app.yaml... I can't set it through .htaccess because it's not used. I would rather not have to add any conditions in my code to possibly set the variable that way, either)
I'm using PHPStorm (IDE), which has a nice plugin for GAE. It even has an option in the project configurations for environment variables - except that it doesn't work. I'm setting the variable in PHPStorm (Edit Configurations > Google App Engine for PHP > Command Line > Environment Variables), but if I do a
getenv()
from code, it returns
boolean false
Why
My goal in all this is to dynamically load the development configurations for my project, particuarly so I can use MySQL locally, instead of connecting up to CloudSQL while developing and testing the apps.
The solution I'm going with, based on the comments by #tim-hoffman is the following little bit of logic on my /public/index.php file, placed before the APPLICATION_ENV constant is defined:
$env = getenv("SERVER_SOFTWARE");
if ($env !== false) {
if ((bool)preg_match("/development/", strtolower($env))) {
define("APPLICATION_ENV", "development");
}
}
In development mode, SERVER_SOFTWARE will return the string "Development/X.X" (version number), and in production, it'll be "Google App Engine/X.Y.Z"