I was trying to send an email from a job. It was actually calls an external API and I store the URL in config/services.php file like this-
<?php
return [
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
'sm_api' => env('SM_API', 'api-url'),
];
I also use this sm_api value from frontend like this config('services.sm_api'). There it works like a charm. but when I try to use the same value from a laravel job class, which actually dispatched from Redis queue server, the same function call returns null. I tried to log the whole config()->all() and it returns the predefined values, except sm_api.
array (
'mailgun' => array (
'domain' => NULL,
'secret' => NULL,
),
'ses' => array (
'key' => NULL,
'secret' => NULL,
'region' => 'us-east-1',
),
'sparkpost' => array (
'secret' => NULL,
),
'stripe' => array (
'model' => 'App\\User',
'key' => NULL,
'secret' => NULL,
),
)
It also shows mailgun's domain and secret value to null though I set it in the .env file. I also log the env('SM_API') value, and it works from the same job. So, the problem is I can bear with env('SM_API') from the job, but I can use mail, as the mailgun driver and key is null. But all this works fine from the frontend. I also tried it in php artisan tinker, and it works perfectly.
I searched on google for this and found this. This issue suggest to use php artisan config:cache to resolve this. I tried this as well. But nothing happens.
The issue you shared contains everything that can be said basically :) Not sure why you opened a new issue.
@themsaid I can't solve the problem. Any suggestion that I can do?
As it works perfectly on web end and in php artisan tinker, but not in cron. So, I thought there must be something that you can do.
When you say cron do you mean using the laravel scheduler? If so then it should work since the scheduler just call a console command in same environment as tinker
@themsaid yes, I am using laravel schedular. And I know, tinker and cron are same environment. That's the problem here. It is so weird that I can't even ask anyone to solve.
I just checked it again. In the tinker, it returns this value for config('services')-
[
"sm_api" => "my-api-url",
"mailgun" => [
"domain" => "mailgun-domain",
"secret" => "mailgun-secret",
],
"ses" => [
"key" => null,
"secret" => null,
"region" => "us-east-1",
],
"sparkpost" => [
"secret" => null,
],
"stripe" => [
"model" => "App\User",
"key" => null,
"secret" => null,
],
]
but in the cron it returns this-
[
"mailgun" => [
"domain" => null,
"secret" => null,
],
"ses" => [
"key" => null,
"secret" => null,
"region" => "us-east-1",
],
"sparkpost" => [
"secret" => null,
],
"stripe" => [
"model" => "App\User",
"key" => null,
"secret" => null,
],
]
I also checked the bootstrap/cache/config.php file where these configs are cached. It looks fine. Only in the console it is not working. I am very depressed with it. I spent my last 18 hours with it find the problem. Couldn't find anything. :(
Did you try changing environment to production after caching configurations?
@lkmadushan yes, I tried. but nothing happens. And in tinker, env('value') is always return null.
For example-
>>> config('app.env')
=> "production"
>>> env('APP_ENV')
=> null
It's really weird.
@themsaid I think, in the cron the configuration is not loaded from the bootstrap/cache/config.php file. Could you please check?
@milon
It _is_ weird. I'm working on linux mint (Ubuntu 14.04.2 LTS) on a homestead machine (Ubuntu 16.04 LTS) with PHP 7.0.8, laravel/framework v5.3.22 and I can't reproduce your problem.
Furthermore: I am sending mails – triggered from the schedule method / cron – that successfully fetch a lot of config values.
Brief tests have shown that config values are read on my system:
protected function schedule(Schedule $schedule)
{
Log::info(config('app.env'));
Log::info(config('services'));
}
Output for APP_ENV=production:
$ tail -f storage/logs/laravel.log
[2016-11-09 22:33:01] production.INFO: production
[2016-11-09 22:33:01] production.INFO: array (
'mailgun' =>
array (
'domain' => NULL,
'secret' => NULL,
),
We also have custom configuration values in services and they show up in the log properly. The output matches the output in artisan tinker:
$ php artisan tinker
Psy Shell v0.7.2 (PHP 7.0.8-2+deb.sury.org~xenial+1 — cli) by Justin Hileman
>>> config('app.env')
=> "production"
>>> env('APP_ENV')
=> "production"
>>> config('services')
=> [
"mailgun" => [
"domain" => null,
"secret" => null,
],
php artisan tinker shows our custom services very well. No differences to the output from schedule.
Maybe something is messed up on your system?
Your example
>>> config('app.env')
=> "production"
>>> env('APP_ENV')
=> null
lets me think that env('APP_ENV') is always null on your system, because config('app.env') is resolved with fallback 'production'. You can see that in config/app.php:
'env' => env('APP_ENV', 'production'),
Maybe something on your system prevents setting environment variables?
Also, have a look at your crontab and compare it to the one, homestead set up for me:
/etc/cron.d/{appname}app <- root:root -rw-r--r--
* * * * * vagrant /usr/bin/php /home/vagrant/{appname}/public/../artisan schedule:run >> /dev/null 2>&1
[edit] the file-owner shouldn't be root I guess. It's an ntfs mounted ssd with vagrant / homestead "nfs" option for shared folders, so this aspect might not be of relevance.
The .env file is not loaded (accurate for 5.2 and 5.3) if you have cached your configuration files. This is the intended behavior. You should only call env() from your config files to help build the cached configuration, and then call config() in your code.
@sisve, I am doing that exactly. I am using this bit of code config('services.sm_api') and it's return null. Any idea why?
Yes, 1) you have an old cached configuration file, or 2) you already have a SM_API environment variable so the one in .env isn't used.
It's most probably number 1.
There are a few other common cases; like your queue being handled/executed on another machine that you havn't updated or you're censoring things in your answers to the degree that we no longer understand the problem.
@sisve, I also suspect that I have an old cached config file. But where it is located. Or how can I remove that?
You can remove it with php artisan config:clear or manually delete the file bootstrap/cache/config.php
@sisve, I removed it. then create it again with php artisan config:cache. But no luck.
@milon same as me
In my case php artisan config:clear works.
For me, php artisan config:cache worked. (config:clear didn't).
We get a lot of config related issues for some reason. Something is fishy with caching.
just stop supervisorctl and start it again.
It's happen due to cache of supervisorctl
Another reason can be that your shell environment defines another env variable.
Typically, I have export ALGOLIA_APP_ID=blah in my .dotfiles so when I run Laravel in console mode, this takes precedence over the .env file. In HTTP or Tinker context my config is not loaded so everything works as expected.
Hope it helps someone one day.
Most helpful comment
In my case
php artisan config:clearworks.