Zend_Session: determine if Session was initially started or just updated - php

I've got a problem with Zend_Session. I need to know, if the Session for this user was initially started the first time or if it was just updated in the current request.
I need to know that for statistics. If the session was initialized (meaning the user visits my app for the first time) I want to store the referer of the request in some db-table. This of course I only want to do for the first request within this session.
The manual talks about the methods Zend_Session::isStarted() and Zend_Session::sessionExists(). But it seems that both methods only work for within the current request (meaning it returns true if I use Zend_Session::start() somewhere in my app).
My approach was the following:
I tried to override Zend_Session::start() to insert the statistic-data into my db-table.
// Somewhere in my bootstrap:
My_Session::start();
// This is my class (eased up)
class My_Session extends Zend_Session
{
public static function start($options)
{
parent::start($options);
if(/* Here I need the condition to test, if it was the initial session-starting... */)
{
$table = new Zend_Db_Table(array('name' => 'referer'));
$row = $table->createRow();
$row->url = $_SERVER['HTTP_REFERRER'];
$row->ip = $_SERVER['REMOTE_ADDR'];
// ... some columns ...
$row->save();
}
}
}
Anybody has any idea?

I need to know, if the Session for this user was initially started the first time or if it was just updated in the current request.
Not a problem:
Zend_Session::start();
$my_logger = new Zend_Session_Namespace('my_logger');
if(isset($my_logger->has_already_visited_app) && $my_logger->has_already_visited_app) {
// this is not the first request
} else {
// this is the first request, do something here
// make sure to add the following
$my_logger->has_already_visited_app = true;
}

Related

Cannot get queued cookie from request

So I have PHP controller that sends cookie in queue, and I need to get this cookie next time when I refresh the page (and call this controller).
When controller is called, it checks if the cookie exists in request, an if not, it sets it in queue with expiration time 15 minutes.
But when this controller is called again, nothing is got in request. I've looked in dev-tools->Network->Cookies and haven't found this cookie neither in Request nor in Response section. At the same time, getQueuedQookies() shows that this cookie has been added to the queue. The code looks as follows:
$cookie = $this->request->cookie('id');
if($cookie=='id') {
die('ID detected.');
} else {
$this->cookieJar->queue('id', 'id', 15);
}
Then other actions are taken, and the controller returns some string in the end.
What am I doing wrong and how can my problem be solved? Would highly appreciate any possible help!
Update
change test to your function name and CookieJar will be auto injected.
public function test(CookieJar $cookieJar, Request $request){
$cookie= $request->cookie('id');
if($cookie=='id') {
print('ID detected.');
} else {
$cookieJar->queue(cookie('id', 'id', 15));
}
}

Does PHP's Laravel 4 hit the Database on every call to the Auth class?

I am building my first Laravel 4 Application (PHP).
I find myself needing to call somthing like this often in most of my Models and Controllers...
$this->user = Auth::user();
So my question is, is calling this several times in the application, hitting the Database several times, or is it smart enough to cache it somewhere for the remainder of the request/page build?
Or do I need to do it differently myself? I glanced over the Auth class but didnt have time to inspect every file (16 files for Auth)
Here is the code for the method Auth::user().
// vendor/laravel/framework/src/Illuminate/Auth/Guard.php
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Auth\UserInterface|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method becaue that would tremendously slow the app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) and ! is_null($recaller))
{
$user = $this->provider->retrieveByID($recaller);
}
return $this->user = $user;
}
To me, it looks like it will get the user from the database only once per request. So, you can call it as many times as you want. It will only hit the DB once.
Auth::user() only hits the DB once, so it's not a problem invokes it many times. Btw, you can cache useful information of the user that you want to access frequently.

Symfony Session Last Request Time

Is it possible to make an action (more specifically 'ajax/heartbeat') not update last request time for the session ?
It is used for fetching notifications etc, so it shouldn't update timeout on sessions or they will never expire.
If the user is doing stuff on the page (onmousemove) I set update=true else update=false
Well, you will have to hook into the User lib of Symfony.
lastRequest is updated during the initialization of the User lib (ie: inside sfBasicSecurityUser).
Inside your app/[appname]/lib/myUser.class.php, extends this initialize function to not set the request time. Something ugly like that:
public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
{
$lastRequest = $this->getLastRequestTime();
parent::initialize($dispatcher, $storage, $options);
if (condition)
{
$this->lastRequest = $lastRequest;
}
}
The only things you need to find is, how to catch the module/action from the myUser lib and then place it in condition.

CakePHP, file uploading, and inconsistent Auth

I have an application built in CakePHP that is doing file uploads. For each file upload, I know the user's id, so I grab it from $this->Auth->user()
Now, what I have found is that when I am on the page, I will upload files while logged in but sometimes when I print_r the $this->Auth->user() it returns nothing back, and then the next time I try a file upload it will come back, all without e logging in or out. It seems extremely inconsistent, in that sometimes it is in there but other times it doesn't see it.
What am I missing? Thanks!
Why don't set a var in your app_controller to $this->Auth->userModel so it's accessible by the rest of the application.
In my app_controller I call the below in before_filter to set $current_user.
/**
* Sets a value for current user $current_user.
* #return boolean
*/
function __setCurrentUser() {
$user = null;
if ($user = $this->Auth->user()) {
$this->set('current_user', $user[$this->Auth->userModel]);
return true;
} else {
return false;
}
}
Elsewhere in my app, I can access $current_user's id via $current_user['id'].
You can also always grab userinfo from the Session that is created by AuthComponent. If $this->Auth->user('id') is empty.. I'm wondering if there is actually a valid session! Are you sure you haven't been logged out in the meantime and the page isn't requiring a login for some reason?

PHP Session Variables -> Accessing another unique identifier

I have a problem right now where, when a user logs in, their user object is stored in a session variable as to be quicker than making a database call each time. The problem I am having is if something updates on their end (like the number of points they have), I have no way to modify that session variable, I can only update their row in the table.
Is there any way for php to access that session variable given it's unique identifier instead of reading from their cookie? Or would it be better to check some flag in the database, and if the flag is set, update all the information?
You need to read it from a centralized storage (contrary to sessions). If you could, you should avoid the database calls. Use cache and update the cache on insert:
user 1 checks cache for user 2's score
it's non-existing, so the call is forwarded to db
the score is still empty/0 so an entry in the cache is written like this: key: "goals-2" (unique identifier which is easy to figure out), value: "0"
user 2 scores a goal
the score for user-2 is calculated by checking the cache (which is empty) and then checking the db (which is empty/0): 0 is current score
the new score is 0 + 1 = 1
the new score is inserted to database (for persistence), the cache with the key "goals-2" is saved with the key "goals-2" and the value "1"
then we're done, let's try the loop again:
user 1 checks cache for user 2's score, finds "1"
user 1 checks cache again for user 2's score, finds "1"
We're saving really many database calls here.
Some possible engines for caching are:
APC
memcache
If you're on shared hosting, or unable to get PHP compiled with a good engine for caching, writing to files could do the job.
What I suggest is to create custom object which will hold data for example 5 minutes and than it will be reloaded. Just create object which will load your data from session, if loaded object is older than five minutes just reload data.
Load object
Check variable in object if (time()) its older than 5 min (or any custom time) reload data
If data reloaded update variable in object to new time and save it to session
I think this can resolve your problem
class MySession
{
public $Duration = 0;
public $Loaded = 0;
public static function Load()
{
$obj = null;
if(isset($_SESSION["my_session"]))
{
$obj = deserialize($_SESSION["my_session"]);
if((time()-$obj->Loaded)>$Duaration)
$obj = self::LoadObject();
}
else { $obj = self::LoadObject(); }
$obj->Save();
return $obj;
}
public function Save()
{
$_SESSION["my_session"] = serialize($this);
}
public static function LoadObject()
{
$obj = new MySession();
$obj->Loaded = time();
//logic for updating data
return $obj;
}
}

Categories