Update .env value using PHP - php

I know some of your might think that this will lead to security issue. 🔐 🐞
But ...
I only want to update only 2 specific flags, because sometimes, I want to see the reports, and sometimes, I don't. If I have a way to update those flags -- I can just hook up a route to toggle that functionality - via Apple iPhone Shortcut whenever I want to see reports via EMAIL or SMS.
I've tried
created a route
Route::get('/env/{flag}/{value}','GeneralController#envUpdate');
called it
http://localhost/env/MAIL_REPORT/false
that will trigger this function
public function setEnv($key, $val)
{
$path = base_path('.env');
if (file_exists($path)) {
file_put_contents($path, str_replace(
$key . '=' . env($key), $key . '=' . $val, file_get_contents($path)
));
}
}
public function envUpdate($flag,$value)
{
//dd($flag,$value);
$allow_flags = ["MAIL_REPORT", "SMS_REPORT"];
if (in_array($flag, $allow_flags))
{
setEnv((string)$flag, (string)$value);
return env(env((string)$flag));
}
}
I kept getting true because in my .env does not seem to be updated
MAIL_REPORT=true
I suppose to have MAIL_REPORT=false
Note : I already ran : sudo chmod 777 .env
How would one go about and debug this further?

If you need to change the environment variables I would suggest to just change your .env file and re-cache your config (if in production). Your current implementation might be pretty sensitive for security issues.
If you do want to change your env variables programmatically at run time you can always use the config() helper method.
config(['mailing. reporting' => false]);
This is also documented in the docs.
Edit
So I think you're implementation of the env variables might be a little incorrect. The environment variables itself SHOULD NOT change at run time in your applications. The only place where the env() function should be called is in the config files (found in the config directory). So what you want is to create a new key in your config/mailing.php config file.
'reporting' => env('MAIL_REPORT', false),
Now whenever you need to set this variable to true you can either change the .env file or use the first given example (config(['mailing. reporting' => false]);).
Read more about it in the docs.

Related

What could possibly cause getenv to fail when the variable is present in .env file?

I have an .env file containing SOME_IP=127.0.0.1:8080. In a Laravel controller for a certain request I call $foo = getenv('SOME_IP');. About 90% of the time it works fine, I get the string and proceed. But the other 10% of times, getenv returns false, even though the variable is clearly in the .env file. What could be causing this?
Alternatively, Laravel's env returns null.
Observed with vlucas/phpdotenv v2.6.4.
Maybe it's because of caching the config.
It is better to load your env variable in a config file and then retrieve it from the config.
For example you can create a file with the name 'ips' in config directory like this:
<?php
return ['someIp' => env('SOME_IP')];
and then use
$foo = config('ips.someIp')

What is best way to create variable in environment file?

In laravel I need to create variable in env file. According to documentation and some relevant threads (got after googling) I need to do add variables in .env file
I have tried following
SANDBOX_PAYPAL_CLIENT_ID=7I3D9
SANDBOX_PAYPAL_CLIENT_SECRET=S2E4C5R6E7T
I am confused that after adding here variable I just need to call then into controller or I need to setup again in somewhere ./config/ directory? What is best practice, can someone guide me about that. I would like to appreciate. Thank you
You should put env variables in .env file, but make sure to only use env() calls in configuration files (the ones under /config) to retrieve their values.
Keep in mind that if you cache the configuration (php artisan config:cache) any env() will return null as Laravel will no longer load .env files.
That's also stated in to the documentation
You can get .env variables using the env() helper function.
Most packages get these values in their conf file to group the configurations.
You can then use the config() helper function to get the value.
However you implement this is up to you.
It depends on how you want to use them. Maybe create a file with name ConfigVariables.php declare all variables of env there.
1) You can have all of them at one place. Centralized control of all env variables at one place.
2) Take care of null checks etc, if config doesn't exit, pass some default value
3) This will help you to have one standard being used for all
4) If you use env directly in the code, you will have to check and take care of the null values (in case if there is no variable in the config)
Just to add a point here, Strings with spaces could be an issue if you do not use ""
You can test it:
Email_Sender_Name=Danyal Sandeelo
echo it as: echo env("Email_Sender_Name");
Email_Sender_Name="Danyal Sandeelo"
echo it as: echo env("Email_Sender_Name");
You can read this one: Laravel 5.2 not reading env file

How would you skip Laravel Scout if enviroment is not production?

I have an app that I am writing with Laravel. I am still fairly new with the framework and don't understand most of it. I am using Algolia as the search engine with Laravel's Scout. In the models you add use Searchable, a trait, and the records are automatically passed to Algolia, which is cool. I am trying to put a simple statement if (App::environment('local'))" exit scout, just so we are not sending our development data to Algolia. Scout will also throw an exception if I run out of the hacker level of 10,000 records a Algolia.
In your local .env add
SCOUT_DRIVER=null
In production add
SCOUT_DRIVER=algolia
In config/scout.php add
'driver' => env('SCOUT_DRIVER', 'null')
Automatically it will be ignored in local but work in production.
This is just a suggestion. Try to adapt it to your specific context.
On your local environment you can call YourModel::disableSearchSyncing(), which will prevent this model from pushing data to Algolia.
The reverse to this method is YourModel::enableSeachSyncing(), but the search is enabled by default, so usually there is no need to use it.
Per the Laravel 5.3 documentation:
Set the environment the in the .env file:
APP_ENV=local
Determine the current environment:
$environment = App::environment();
Check on $environment and return true:
if (App::environment('local')) {
// The environment is local
}
if (App::environment('local', 'staging')) {
// The environment is either local OR staging...
}
None of above solution works I suggest you to check in your toSearchableArray() method inside your User Model. If you try to set the SCOUT_DRIVER=null in local environment then you will face an error because your application tends to push to Algolia in any environment.
Try to do this instead:
public function toSearchableArray()
{
if (! app()->isLocal()) {
return [
'username' => $this->username,
'age' => (string) $this->age,
// and so on ...
];
}
}

Laravel 4.2 URI based configuration

I'm working on a project which has multiple URL's, and each URL need a custom configuration. It does not have to be in it's own configuration file, but would be a nice to have (for a clear overview of project structure).
At the moment I have the following in my custom configuration file, which works - but is IMO not the best place to put this.
$domain = $_SERVER['HTTP_HOST'];
switch($domain)
{
case 'domain':
$var = 'foo';
break;
case 'otherdomain':
$var = 'bar';
break;
}
I've tried adding the same code to filters, in App::before function (but instead of $var =, I do:)
Config::set('var','foo')
Unfortunately, this does not give me the desired effect, when I do it like this - I cannot access Config::get('var') in my configuration file to make the switch between the different variables I need per URL.
I'm pretty sure there should be a better way to handle this than my "I'll add it to config file". Can anybody point me into the right direction?
I think you should use environments for this. Just create directories under app/config like:
config
-- domain
-- otherdomain
And place a file in them. Let's say app.php. In there you return an array of config values:
return array(
'foo' => 'bar'
);
And finally, in bootstrap/start.php, change the detectEnvironment call to this:
$env = $app->detectEnvironment(function()
{
return $_SERVER['HTTP_HOST'];
});

Yii console with different configs

In the web application we use same code and modules with different configs like:
in index.php file app will decide, wchin config to turn:
switch($_SERVER['HTTP_HOST']){
default:
$yii=$webRoot.'/framework/yiilite.php';
$config = $webRoot.'/protected/config/main.php';
break;
case 'someurl.com':
...
break;
...
}
But, how can I do it with console application?
The reason in that I use different databases ant etc.
is it possible to do something like this:
$ ./protected/yiic --application=myappname [all defined commands as default]
in the code a
--application
will set with which console config to work
more explanation
my answer to #Joe Miller
But the problem is, how choose theme?
I did in the files foloowings:
in protectes/yiic
$__appId = null;
for( $__i=1,$__max=count($argv); $__i<$__max; ++$__i ) {
if ( strpos($argv[$__i],'--appid',0) === 0 ) {
$__appId = substr($argv[$__i], 8);
unset($argv[$__i]);
}
}
require_once(dirname(__FILE__).'/yiic.php');
and in protected/yiic.php
$__appIdsList = array(
'my_site_1',
'my_site_2',
'my_site_3',
'my_site_4',
);
$yiic=dirname(__FILE__).'/../framework/yiic.php';
$config=dirname(__FILE__).'/config/console_'.$__appId.'.php';
require_once($yiic);
and it works and it catchs that config file what I need
./protected/yiic --appid=my_site_1
bu when I`m trying to do migrate
./protected/yiic --appid=my_site_1 migrate
the app cant recognize comman and gives me migrates help list
And final conslusion (I solved it)
I`d like to add transperent console command without affecting it to other execution of builtin console commands and custom console commands.
Another requirement is, solve this issue on a low-level approach, without inheritance or overloading other classes or methods.
So, my solution is:
in protected/yiic
#!/usr/bin/env php
<?php
$__appId = null;
for( $__i=1,$__max=count($argv); $__i<$__max; ++$__i ) {
if ( strpos($argv[$__i],'--appid',0) === 0 ) {
$__appId = substr($argv[$__i], 8);
unset($argv[$__i]);
unset($_SERVER['argv'][$__i]);
$argv = $_SERVER['argv'] = array_values($argv);
}
}
require_once(dirname(__FILE__).'/yiic.php');
and in /protected/yiic.php
<?php
// change the following paths if necessary
$__appIdsList = array(
'app_1',
'app_2',
);
$yiic=dirname(__FILE__).'/../framework/yiic.php';
$config=dirname(__FILE__).'/config/console_'.$__appId.'.php';
if ( !is_file($config) ) {
die("Error: There is no or wrong parametr appid. Please set parametr or correct. Example -appid={application_name}\n\tThe list of available appid:\n\t\t - ".implode("\n\t\t - ", $__appIdsList));
}
require_once($yiic);
and now it is possible to set param "appid" in any place of command line, like
./protected/yiic migrate --appid=app_1
and it acts only in that app what we need
PS: in any case, thanks #Joe Miller
Copy yiic.php for example to cron.php and modify the config file in the cron.php
then use as if it were yiic, for example:
cd ~/protected;php ~/protected/cron.php app command --param=value >> ~/runtime/crontab.log
If I've understood what you're trying to do correctly, I think you might need something like this. I've referred to this article http://www.yiiframework.com/doc/guide/1.1/en/topics.console#creating-commands. I've not tried this, so I'm just interpreting the article.
Create a base command class, from which you will extend all the other commands. The base class run() method selects the config file to load.
In protected>commands you need a file migrate.php. This must contain the class MigrateCommand, and must extend CConsoleCommand. You can then override the run() method of this class to allow parameters to be passed to the method. e.g.
In protected>commands>baseCommand.php
class MyBaseCommand extends CConsoleCommand{
public function run($args){
//Code here to select the config file to load
//$args are any arguments you have passed in the command line
}
}
In protected>commands>migrate.php
class Migrate extends MyBaseCommand{
public function run($args){
parent::run($args);
//Do your own stuff here
}
}
you should then be able to call the command as;
./protected/yiic migrate --appid=my_site_1
Note that the name of the command appears first, I'm not sure if this is important, but it's what the guide says! I hope I've understood your question this time!
I think, I founded more confortable solution!
It`s more easy, and solved all my requirements.
in the file
protected/yiic.php
I write:
...
$yiic=dirname(__FILE__).'/../lib/framework/yiic.php';
if ( strpos(__FILE__,{first/place}) !== false ) {
$config=dirname(__FILE__).'/config/first_config.php';
} elseif ( strpos(__FILE__,{second/place}) !== false ) {
$config=dirname(__FILE__).'/config/second_plase.php';
} else {
// by default
$config=dirname(__FILE__).'/config/console.php';
}
require_once($yiic);
...
where {first/place},{second/place} - a part of the project`s path. For example:
Your first project is placed in:
/var/www/aproject/first_one
and the second one on the
/var/www/aproject/second_one
than you checks will be:
// for first porject
strpos(__FILE__,'aproject/first_one') !== false
and etc.

Categories