I'm using laravel 5.8 and created a command that runs in the background to keep data updated.
web.php
Route::get('/admin/do_stuff', function () {
Artisan::call('do:stuff');
return 'Started!';
});
DoStuff.php
while(config('key.value')){
doStuff();
sleep(120);
}
Also got my route (mysite.com/admin/do_stuff) that will start this process, but now I want to add a new route (mysite.com/admin/stop_doing_stuff) to be able to stop it. I've seen in the documentation config variables could be set during runtime https://laravel.com/docs/5.8/configuration#accessing-configuration-values but this doesn't seem to be changing the value at all. Is this possible?
Reading the value from the .env file seems to work but that means I need to edit that file manually and that's not an option, also I could store the value in the database but would like to not doing it. Tried clearing the config cache but getting the same result
Related
I am working with some coaching using Redis in Nodejs.
here is my code implimentation.
redis.get(key)
if(!key) {
redis.set(key, {"SomeValue": "SomeValue", "SomeAnohterValue":"SomeAnohterValue"}
}
return redis.get(key)
Till here everything works well.
But let's assume a situation where I need to get the value from a function call and set it to Redis and then I keep getting the same value from Redis whenever I want, in this case, I don't need to call the function again and again for getting the value.
But for an instance, the values have been changed or some more values have been added to my actual API call, now I need to call that function again to update the values again inside the Redis corresponding to that same key.
But I don't know how can I do this.
Any help would be appreciated.
Thank you in advanced.
First thing is that your initial code has a bug. You should use the set if not exist functionality that redis provides natively instead of doing check and set calls
What you are describing is called cache invalidation and is one of the hardest parts in software development
You need to do a 'notify' in some way when the value changes so that the fetchers know that it is time to grab the most up to date value.
One simple way would be to have a dirty boolean variable that is set to true when the value is updated and when fetching you check that variable. If dirty then get from redis and set to false else return the vue from prior
Im using Laravel 7 so I didnt think this was going to be an issue.
Just a note on my installation, it was an upgrade from 5.3.
My issue is with a custom Blade directive I created.
It is aded additional quotes around the input
I added a dd() to see why my Helper didnt work.
My ServiceProvider
Blade::directive('setting', function ($expression) {
dd($expression);
return SettingHelper::value($expression);
});
View file
#setting('theme_public')
Output of dd()
"'theme_public'"
Expected output
'theme_public'
I dont know why the extra quotes are being added.
You are right, I get the same behavior with a fresh laravel 7 installation.
I created some little tests, to see what's going on. I think the behavior is best explained like this. Imagine you are calling a view with one variable:
return view('welcome', ['var' => "Hallo"]);
You have a custom blade directive like this:
Blade::directive('dirtest', function ($expression) {
dd($expression);
});
If you use that in your template the output is this:
#dirtest($var)
// output of dd in the browser:
"$var"
So it seems like the blade directives are just meant to replace some shorthand directive with more verbose php code. The actual code get's executed later in the blade templating engine. That makes sense, since blade templates are also cached for faster execution. In the cached version that custom directive is already embedded and your custom function doesn't get fired anymore. I hope that explanation makes sense to you.
What that means for you
It really depends on your use case. If you have a custom directive, that only gets passed constant strings, you could probably get away with just writing:
#setting(theme_public)
But if there's just a slight chance, that you might pass in a variable from time to time, like
#setting($theme)
You really have to return code, that utilizes that variable and can be evaluated later.
Is it possible to set a method that changes a value in my database automatically when I run a php artisan command? What I'm trying to accomplish is change the value of the first row in my "domains" table to suit the url from my .env file automatically whenever I push codes to my live/staging environment. Are there any ways to do this automatically without me manually going into my DB and changing it.
You could setup a Listener for the native event CommandFinished and check if the command is the config:cache.
Event::listen('Illuminate\Console\Events\CommandFinished', function ($event) {
if ($event->command == 'config:cache') {
// Change domains table data using Eloquent or Query Builder
}
});
To learn more about Events, see: https://laravel.com/docs/5.7/events#generating-events-and-listeners
I am using "file storage" for my session. When I run this:
Session::set('awesomekey', 'myVal123');
And refresh the page, I can see new files being created in /storage/session each time. I assumed it would update the same file each time. This basically means sessions don't work at all. In other words, if it keeps recreating a session file, this never works:
Session::get('awesomekey');
Or at least, it returns a blank. What am I missing that could possibly be causing a new session key to be created each time a page is loaded?
UPDATE
On further investigation, it seems the cookie is regenerated on each page load. What could be causing that?
I am not even looking at logging in yet, so this information is useless to me --> http://willworkforbanjos.com/2014/02/laravel-sessions-not-working-in-4-1/
My problem is happening when I simply put the above set and get code in the master.blade.php file. It should set it, store the info, and on the next reload get the right information from session. But it can't because on reload it changed the cookie to some other code.
Anyone know why this is happening?
UPDATE 2
Adding: 'lifetime' => 120 to session.php did not work. (#Sheikh Heera)
Placing the code in the controller only, does not work. (#Phill Sparks)
I tried chrome and firefox, same result (#The Shift Exchange)
Just to be clear on what I'm trying to do. I add the following code in HomeController.php:
public function index()
{
Session::put('awesomekey', 'myVal123');
return View::make('home.index');
}
Then I put this in my master.blade.php:
print Session::get('awesomekey');
I do not include any "dies" or random echos in my controller side of the code, except for this. When I open the file the first time, I can see myVal123 being printed out.
I then take out this part in the controller:
Session::put('awesomekey', 'myVal123');
And reload the page. It now prints nothing. I can see in my browser that the cookie has changed. Generating a new cookie will lose the reference to the session, so I'm stuck trying to understand why it's doing that each time, even though it saves the session on the first load.
Any more ideas?
UPDATE 3
I also tried:
Running "php artisan dump-autoload" ... still doesn't work
I went here: http://www.whatismybrowser.com/are-cookies-enabled ... and yes, cookies are enabled.
I'm really running out of ideas here...
UPDATE 4
I went to SessionManager.php and just underneath this:
$lifetime = $this->app['config']['session.lifetime'];
I printed out the value of life time:
print $lifetime; die();
And this code was never hit on page reload?! However, adding this in my controller:
$d = Config::get('session.lifetime');
print $d;
Does in fact print out my value for lifetime.... :(
The problem was this line:
'cookie' => 'xxxx.com',
in session.php. Apparently it loses the cookie if you have a "." in the cookie name. I can't believe Laravel doesn't like that. Or maybe it's browser's in general.
I believe you are using:
'lifetime' => 0 // number of minutes
in your app/config/session.php file. Make it something like this:
'lifetime' => 120 // number of minutes or whatever you want
It'll work. I tried same settings as you described and just used 0 and I get same result, each time a new file is being created but once I change it to 120 or so, it works. So, it make sense that, if it's set to 'lifetime' => 0 in the session config then every time it just creates a new file for a new session because the session doesn't live. So, go to your app/config/session.php file and you'll find something like this, change the value:
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
Update:
You may use following code to get the lifetime value set in the app/config/session.php file:
Config::get('session.lifetime');
Have a look at the cookie's expire time in Chrome developer tools, or Firebug. If it is set to 0 then the cookie will expire immediately.
Also, double-check if your clock is setup correctly - strange things could happen if there's a disparity between your host's and the browser's clock. Make both systems consult NTP to ensure this is not an issue.
I had a similar problem with the sessions, if you're using the model User and your users table doesn't have the primaryKey as Id, you must overwrite that variable at the model.
class User extends Eloquent {
protected $primaryKey = 'admin_id';
}
In /app/config/session.php check the "HTTPS Only Cookie" setting.
Make sure it's "secure => false" if you are not using SSL!
I've experienced issues related to this. The session file wasn't created every time but sometimes I just can't get the session variable displayed. After hours of experiments I found that the problem was related to Debugbar.
If you're using Debugbar and having session issues, disable it and try again to confirm.
Use Session::put('value') instead of set.
http://laravel.com/docs/session#session-usage
As above: Is it possible to regenerate Code Igniter sessions manually? I'm looking for something similar to session_regenerate_id in PHP sessions, so that I could call it manually when a user went through privilege escalation.
Thanks,
Lemiant
CI automatically regenerates the session id every x seconds, which you can set in your config.
You could create a new function in Session.php the same as sess_update() but with the following removed from the top & the function renamed to regenerate_id().
// We only update the session every five minutes by default
if (($this->userdata['last_activity']+$this->sess_time_to_update) >= $this->now)
{
return;
}
This will regenerate the session id, update users_activity and keep the users data. Just call it by $this->session->regenerate_id();
I know this is an old post, but I came across it, so others might too.
You could also do the following so you don't have to hack the core files at all (making codeigniter more easily upgradable with future releases):
//Setting this to 0 forces the sess_update method to regenerate on the next call
$this->session->sess_time_to_update=0;
//Call the sess_update method to actually regenerate the session ID
$this->session->sess_update();
Credit to the original answer for leading me down this path though, thank you.