PHP Session Variables -> Accessing another unique identifier - php

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;
}
}

Related

Store value of last runtime without session

I met storage problem with php.
What I want is when each time I visit the function Main of Class A, I can get the value of variable $temp of last time.
P.s. I know I can use session, but it wastes many memory, and not safe.
so I want to find another solution.
Below is the code.
class A {
//initilize the value, how to make it just initialize once?
private static $temp = 0;
public function Main() {
echo "Last time I was=". $this->temp;
$this->temp += 1;
}
}
Thank you for your guys' help! Waiting for your idea
static variable value is stored in a request lifetime.sessions are safe enough to even store authentication data in it so if you want to store this data between multiple requests i recommend sessions or database.
Will it be useful if you store it in a separate file, you overwrite the value in it and read from it when needed?

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.

Zend_Session: determine if Session was initially started or just updated

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;
}

Reduce database calls for php web shop

I'm looking for a way to prevent repeated calls to the database if the item in question has already been loaded previously. The reason is that we have a lot of different areas that show popular items, latest releases, top rated etc. and sometimes it happens that one item appears in multiple lists on the same page.
I wonder if it's possible to save the object instance in a static array associated with the class and then check if the data is actually in there yet, but then how do I point the new instance to the existing one?
Here's a draft of my idea:
$baseball = new Item($idOfTheBaseballItem);
$baseballAgain = new Item($idOfTheBaseballItem);
class Item
{
static $arrItems = array();
function __construct($id) {
if(in_array($id, self::arrItems)){
// Point this instance to the object in self::arrItems[$id]
// But how?
}
else {
// Call the database
self::arrItems[id] = $this;
}
}
}
If you have any other ideas or you just think I'm totally nuts, let me know.
You should know that static variables only exist in the page they were created, meaning 2 users that load the same page and get served the same script still exist as 2 different memory spaces.
You should consider caching results, take a look at code igniter database caching
What you are trying to achieve is similar to a singleton factory
$baseball = getItem($idOfTheBaseballItem);
$baseballAgain =getItem($idOfTheBaseballItem);
function getItem($id){
static $items=array();
if(!isset($items[$id])$items[$id]=new Item($id);
return $items[$id];
}
class Item{
// this stays the same
}
P.S. Also take a look at memcache. A very simple way to remove database load is to create a /cache/ directory and save database results there for a few minutes or until you deem the data old (this can be done in a number of ways, but most approaches are time based)
You can't directly replace "this" in constructor. Instead, prepare a static function like "getById($id)" that returns object from list.
And as stated above: this will work only per page load.

Zend PHP Class Variable retention for mysql queries

I have a flash application which uses a single php file to retrieve records from a database (using the Zend framework). When the application first begins, I make a call to the php to set a class variable, so that all future requests to the database will use this variable to select records based on its value. So here is how the class begins:
class MyClass
{
private $animal = "";
public function setAnimal($anim) {
$this->animal = $anim;
echo($this->animal); //this correctly prints the variable I passed in
}
Later, based on user input, I make a call to a different method in this class, but it's as if the class variable $animal has been forgotten, because it no longer has a value on any subsequent accessing of the class:
public function getAnimals()
{
echo('getAnimals: ');
echo($this->animal); //this prints nothing - as if it doesn't know what "animal" is
$result = mysql_query("SELECT * FROM animals WHERE animal='$this->animal'"); //and therefore this query doesn't work
$t = array();
while($row = mysql_fetch_assoc($result))
{
array_push($t, $row);
}
return $t;
}
So my question is, how can I get a PHP class variable to persist so that I can set it once, and I can access it anytime during the life of an application?
I could be mis-interpreting your question, but it sounds like you first make a call to a PHP script from your Flash, and later you are making a second call to the PHP script from the Flash and expecting a certain variable to be set?
If this is the case, then it is also the problem. PHP is stateless. Every time you access a PHP script (ie, request the URL), the PHP environment is re-created from scratch. As soon as the request is done and the PHP script is finished executing, the environment is destroyed (ie. the web server thread shuts down, and the PHP environment is lost). Anything you set or do in your first request won't exist on your second request.
If you want information to persist, you can use sessions or cookies. Since you're using Flash, sessions is probably the best way to go. The first time you call your script, generate a session token and pass it back to the flash with your response. On all subsequent calls, your Flash should provide the session token, and you can store/fetch any state variables you need from $_SESSION.

Categories