Cannot update Laravel Session variable? - php

I have an ongoing problem in Laravel. I am building "load more" system for comments with Laravel and Ajax, and using Session variable for counting and skipping already loaded rows. But for some reason my session variable wont persist, for unknown reason (trying whole the day to resolve this).. Ok here is some code:
public function load_more() {
$comments = Comments::whereid(Input::get('article_id'))->orderBy('id','DESC')->skip(Session::get('loaded')->take(12)->get();
Session::set('loaded', Session::get('loaded') + 12 ) ;
return \Response::json($comments);
}
So as you can see i am trying to increment variable each call. But the variable stays the same all the time.. When I make another variable for example Session::set('another', Session::get('loaded') + 12 ) ;
it actually get summed and i have sum in this variable.. but why it cannot update itself?

Fixed the problem in frontend with Jquery global counter which I am sending as an GET argument on every request, instead of using Session variables. Still don't know what's the problem with session, maybe some bug in my Laravel installation.

If your have laravel 5.2 the probleme is you put your route into group web
Route::group(['middleware' => ['web']], function () {
PUT YOUR ROUTE HERE
}

Related

Laravel: how to cache route for 5 minutes?

I want to cache one route in Laravel project and clear it for every 5 minutes.
I searched a bunch of articles but only found artisan route:cache command and I have no idea if it possible to configure caching time.
So, this is my routes routes/web.php:
$router->group(['middleware' => ['api','cors']], function () use ($router) {
$router->get('game', ['uses' => 'GameController#checkGameStatus']);
$router->get('promo', ['uses' => 'PromoController#sendPromoCode']);
$router->get('get_leaders', ['uses' => 'GameController#getLeaders']); // <-- cache this for 5m
});
And every time when user loads rating page the getLeaders() function initiates DB request to get and calculate all user results. Therefore I want to reduce DB load and make it calculating all results once in 5 minutes. The rest of the time get_leaders route should send back just cached json output.
How to set such configuration? Is it possible to do just with Laravel (artisan) or should I change .htaccess file (I am using apache)?
To add to #TimLewis 's answer, if you're using laravel 5.8 or newer then the Cache::remember function can simplify the controller code quite a bit
public function getLeaders(){
$leaders = Cache::remember('leaders', 300, function () {
return Leader::where(...)->get();
});
return response()->json(['leaders' => $leaders]);
}
The Cache::remember function takes care of the entire caching workflow, it first checks the cache for the leaders object and returns that if it exists. If not, it runs the code inside the closure and stores the result in the cache under the key specified in the first param, for the number of seconds specified in the second param. So in this case it would cache the result under the key "leaders" for 300 seconds (5 minutes).
This is a pretty simple to solve problem actually. In your function getLeaders(), you'll need to modify the code:
public function getLeaders(){
$leadersCache = Cache::get("leaders", null);
if($leadersCache){
return response()->json(["leaders", $leadersCache], 200);
}
$leaders = Leader::where(...)->get();
Cache::put("leaders", $leaders, 5);
return response(["leaders", $leaders], 200);
}
So, what this does, is first, check if "leaders" exists in the cache. If it does, it will simply return that. If it doesn't (which will be the case when this route is first called), then it will do the calculations, and using Cache::put(), store it in the cache, then return. For the next 5 minutes, anytime this route is hit, it will return the cached result, until the process is started over again.
Note the above is pseudo-code, as your Controller wasn't shown, but the approach can be easily adapted to existing code. Also, you may need to include use Cache; at the top of your Controller, or reference Cache via \Cache::{method}
Everything about the cache can be found in the documentation: https://laravel.com/docs/5.7/cache
Laravel > 7 u can use cash::rmember(), and u will save a lot with writing less
Example :
$getleaders = Cache::remember('getleaders', 'minutes', function () {
u query;
});

PHP - Run script/function/class continuously and update variables (Laravel)

I need something specific and i have no idea how to approach it.
I need to run a script/class/function continuously with start/stop button in my browser and update my views accordingly.
The script calls an API every minute and updates the variable in the class.
I made a basic Controller with a displayPage() method that returns the view with $data.
Inside the controller , i called the class that is supposed to run continuously . It has global variables. I was thinking of adding a while(true) loop function which does not return anything but instead updates the variable.
Controller :
$c = new Folder\TestClass();
$c->start();
$x = $c->variable1value;
return view('testpage',$x);
I'm not sure if the above will work or if there is a better way to do it . Any advise would be much appreciated.
Now , if the above works :
How do i update my view ?
I was thinking of making an update() function in the controller and call it using javascript every minute . I don;t want to reload the whole page however , just the view i.e : $x value , reinitialize graphs etc...

kohana ajax controller sessions are not working with auto render

Using ajax function working with sessions. In controller with ajax action i'm setting the session values using $this->session->set('coupons',$data). After setting this session i'm not able to get in another controller file already added session.Can you pls advice me.
public function action_applypcode()
{
$this->auto_render = false;
$this->session->set('coupon_details', $restcode);
}
public function action_receipt()
{
$coupon_details = $this->session->get('coupon_details');
print_r($coupon_details);
//Here getting empty session values
}
What is $restcode?
You shouldn't have any problem on setting session values through ajax or normal request, they work equally, the only diff is that you don't want the layout form ajax calls.
Are you using another lib or module that could initialize a session too? Search in your external modules for $_SESSION, sometimes that can be the problem. If that's the problem, try using Session::instance() at the first line of your template controller.
Btw, I don't remember kohana having an attr for the session in the controllers, also you can try using Session::instance()->set and ->get , maybe that could help too.
Regards!

CodeIgniter $this->session->set_userdata() on 2 simultaneous AJAX

I have simulatneous AJAX requests on codeIgniter with all of them session update like so:
function ajax1($value)
{
$this->session->set_userdata('foo', $value);
}
function ajax2($value)
{
$this->session->set_userdata('bar', $value);
}
But sometimes because of MySQL concurrency, one variable or the other is not updated, I suppose because one method gets overwrites the new value of the other method with the old value if grabbed from the db.
I cannot update the 2 sessions at the same time as they do completely different things and I don't know which ones will be called, as the page is dynamic and might have one or several of these method calls.
Anybody ran into this in the past and has a way of going around that problem?
I think this problem was fixed in the latest version of codeIgniter, but if you are still using an old one, try to replace system/libraries/Session.php with a new one, or you can just override the Session Library like follow:
application/libraries/MY_Session.php
class MY_Session extends CI_Session
{
function sess_update()
{
if (!$this->CI->input->is_ajax_request())
return parent::sess_update();
}
}

Laravel session data not sticking across page loads

I tried running the following code:
Session::put('progress', '5%');
dd(Session::get('progress'));
This will show '5%' in the dump.
If I rerun the same page but comment out Session::put('progress', '5%'); so that only the dd() line is called, I get a null value instead of the 5% values stored in the previous page load.
Here is my sessions config, so I know it should be storing the data:
'driver' => 'native',
'lifetime' => 120,
'expire_on_close' => false,
Why is Laravel not storing the session data across page loads?
The problem is because you are killing the script before Laravel finishes its application lifecycle, so the values put in session (but not yet stored) got killed too.
When a Laravel application lifecycle starts, any value put in Session are not yet stored until the application lifecycle ends. That is when any value put in Session will be finally/really stored.
If you check the source you will find the same aforementioned behavior:
public function put($key, $value)
{
$all = $this->all();
array_set($all, $key, $value);
$this->replace($all);
}
If you want to test it, do the following:
Store a value in session without killing the script.
Route::get('test', function() {
Session::put('progress', '5%');
// dd(Session::get('progress'));
});
Retrieve the value already stored:
Route::get('test', function() {
// Session::put('progress', '5%');
dd(Session::get('progress'));
});
Rubens Mariuzzo's answer is very good. I just want to add that if you need the data to be stored immediately you could use the save method:
Session::put('progress', '5%');
Session::save();
For me, even after data has been stored to session properly:
dd(Session::all());
returns nothing, but:
print_r(Session::all());
returns all session data!
In my case I flashed the variable in one request and then put it into session in another request (with the same name).
Unfortunatelly, terminating method went through all the previously flashed properties and cleaned my newly created session property (it was flushed in previous request so laravel thought it was no longer required and couldn't tell it was newly created). I figured it out debugging Kernel->terminateMiddleware method. You can put a breakpoint in terminating method. At some stage it reaches Store->ageFlashData. This is the method responsible for deleting my property.
I moved the session middleware
\Illuminate\Session\Middleware\StartSession::class
to the property $middleware in
app/Http/Kernel.php
In this case, you need to remove it from the web group ($middlewareGroups)
It helped me, I hope it helps you too

Categories