Why can't I access my static variables from another php page - php

I'm trying to create a simple class that holds all my session information so I can easily obtain it later on. I don't like having to keep using $_SESSION['foo'] to access it through all my PHP pages because I want to be better organized and have all of the session data stored in one area so I can just pull up the page if I need a quick reference to see all the variables I've stored. Also on a side note, if there is a better way I'm suppose to store SESSION data so that its organized and easily read by other programmers that would be very helpful information as well.
So far I created the following class..
class staticVars {
public static $ownerID;
public static $ownerFullName;
public static $ownerEmail;
public static function createFromArray($array) {
$ownerID = $array['ownerID'];
$ownerFullName = $array['ownerFullName'];
$ownerEmail = $array['ownerEmail'];
}
}
in my PHP page I have this...
include("./includes/core/coreGlobals.php");
staticVars::createFromArray($_SESSION);
echo ("owner id " . staticVars::$ownerID);
However, when I echo out the response, the $ownerID just comes back blank.

You're setting variables local to the function and not the class variables. Use self or maybe static:
public static function createFromArray($array) {
self::$ownerID = $array['ownerID'];
self::$ownerFullName = $array['ownerFullName'];
self::$ownerEmail = $array['ownerEmail'];
}
See: Late Static Bindings for when you would use static.

Related

Variable scope for different sessions in PHP

I've just started PHP developement and I would like to know a bit more about variables scope.
I know about the scope inside the script. I just want to know, how variables are treated between different users. Let's say I have a class :
class SomeClass {
public static $myVar = 0;
public static function doSomethingToMyVar(){
// $myVar gets manipulated
}
}
NOTE: I know it's an awful design, so it's just for showing an example of my question.
Now my question is: if user A uses the page so that doSomethingToMyVar is called, does user B get modified value of $myVar? I mean, do different users share static variables or PHP gives seperate sets of variables for each user?

Store and use global variables in the same class, but different public functions using php

I have a project made in netbeans with php and I am using Zend framework, so it's model-view-controller.
Into a class (newclassController), I have 4 public functions. I want to store a global variable from the second function and use it into the 4-th function.
I have tried to send the variable in the URL as a parameter and SESSION variables but I get some errors so if you have some other ideeas please enlight me.
All I tried returns gives this error message:
Notice: Undefined variable
NOTE: It works if I store the variable in the init function, but I want to store it from another function.
unless I miss my guess when you initiate a value in:
public function init(){
$this->value = 'value';
}
the value is available to all of the 'actions' in the controller.
This is by design.
The init() method is used in ZF1 to supplement the constructor. It's where you add arguments that might normally be put in the constructor.
In order to persist a value from one action to another, some form of storage must be used.
For example:
//a verbose example
public function indexAction(){
//initiate a variable
$i = 100;
//start a new session and assign a name to it
$session = new Zend_Session_Namespace('number');
//assign the value to the namespace
$session->value = $i
}
later in that same controller or even another controller
public function newAction(){
//access the session
$session = new Zend_Session_Namespace('number');
//assign the value to the view
$this->view->value = $session->value;
}
now in the new.phtml view
<?php echo $this-value ?>
An important thing to remember when using PHP and specifically Zend Framework 1, every request runs the entire application.
This was a concept that tripped me up in the beginning. Every time you request a new page your Zend Framework application runs from scratch, so any data that needs to survive from one request to the next must be saved (persisted).
public function__constructor(){
$this->value = 'something';
}
$this->value
will give 'something' in the class
decalre the variable in the constructor of the class and use it

Accessing a sibling (?) variable in PHP

I have a base class, which includes all other files. I can access this class (it is public) throughout my entire application (by way of base::$var or base::function()).
One of the functions of this base class is to load additional frameworks. One of the frameworks looks like the following (simplified) - based off a singleton that I saw here on SO.
<?php
class someOtherFramework{
public static $site = array();
public static function Instance() {
static $inst = null;
if ($inst == null) {
$inst = new someOtherFramework();
}
return $inst;
}
private function __construct() {
}
}
base::createInstance('blah', 'someOtherFramework');
?>
The call to base::createInstance is the following:
public static function createInstance($variable, $class){
if (class_exists($class)){
$variable = $class::Instance();
}
}
The goal is that I can access $blah in the same way that I do $base. Is it possible? Does this make sense? If not, what's the best way to provide access to a class another developer might want to use?
the only way of accessing your 'blah' variable, is if it was a global. which isn't really OOP design.
Maybe you should look into creating a Registry class which is passed around by reference that contains all of those variables? For myself, I find it neater to do that (and much less of a nightmare thank you Eclipse IDE!) - and personally, I don't like Singleton classes
... though, the code you posted, doesn't exactly make sense. Can you post more details?
You could use $GLOBALS, the array that holds all global variables. It's accessible from within a function. Maybe better, there's also the global keyword and variable variables.
Using $GLOBALS, you'd do something like this:
$GLOBALS[$variable] = $class::Instance();
With the global keyword, your function would look like this:
global $$variable;
if (class_exists($class)){
$$variable = $class::Instance();
}

Maintaining state between runs | Session Use

There are different way to run PHP code. For example user initiate reloads and user initiated ajax requests.
What it the best way to maintain state between these runs?
PHP does consider it separate runs. Two things:
Don't use globals... they're bad :) Consider making your "session" class a collection of static functions with the session_id as a static member var.
Simply create a new session class in your 2nd snippet:
$obj_ses = new session();
$obj_ses->activate('email', $this->_protected['email']);
The session id will be the same across all page views for that particular user, so creating a new session() in the second snippet will still refer to the same session you started in the first snippet.
Here's what a static implementation might look like:
// class names should be camel-cased
class SessionManager
{
protected static $session_id = null;
public static function start()
{
self::$session_id = session_start();
}
// ... and so on
}
// to use
SessionManager::start();
SessionManager::activate('email', $email);
That should really be all you need. There are certainly many ways to do this, but this ought to get you started :)

Feedback on a session storage class design

I have a session class that basicly just sets and retrieves session variables,
the reason I made it was so I could easily change it to use sessions or something
like memcache to set the items and have them accessible on multiple pages without hitting the database
I then have this user class which uses the session object to get session variables in it.
I am wanting to add to this user class though, to make it more encapsulated I would like to be able to set the variables that I am retrieving in this class
so right now I can display the userid with $user->userid; I would like to first have a method or something that sets its value from the session object I guess
Does this sound lke a good idea or possibly a lot of overhead?
And if what I am trying to do is a good idea maybe you could suggest/show example of how I should do it? I am thinking that if I add that method in that possibly I should move the code in the __construct method into it's own method
Basicly, I have the variables listed in the top part of the class that are used in the construct method, if I have multiple methods in the class though would I need to set them all at the top like that?
<?PHP
//user.class.php file
class User
{
public $userid;
public $name;
public $pic_url;
public $gender;
public $user_role;
public $location_lat;
public $location_long;
public $newuser;
function __construct()
{
global $session;
if($session->get('auto_id') != ''){
//set user vars on every page load
$this->userid = $session->get('auto_id'); //user id number
$this->name = $session->get('disp_name');
$this->pic_url = $session->get('pic_url');
$this->gender = $session->get('gender');
$this->user_role = $session->get('user_role');
$this->location_lat = $session->get('lat');
$this->location_long = $session->get('long');
$this->newuser = $session->get('newregister');
}else{
return false;
}
}
}
//with the class above I can easily show some user variables I have saved into a session like this below
$user = new user();
$user->userid;
?>
In general your idea is a good one
3 things I would do differently:
1) In your implementation doesn't seem to consider having several users. ie Several instances of the same class.
2) I would use factories instead of using IF in the constructor.
So for a user you have saved in the session you would call:
$savedUser = User::fromSession($userId);
for a new user
$user = new User()
3) Use the serialize and unserialze functions to save that data to the session
Then your class could could be implemented as
public static function fromSession($userId) {
return unserialize($session->get('users_'.$userId));
}
public function save() {
return $session->set('users_'.$this->id , serialize($this));
}
I guess this is vaguely an answer to the "is this a good idea" question. In my understanding, locating variables in the session versus refreshing them from the database is a question of the trade off between complex queries and deserializing data. The session data isn't a free magic cache that escapes database calls, it is just a convenient wrapper around a database call that you don't have to deal with. Any variable that you place in the session must be serializable. The whole collection of serialized data is then managed; the server fetches the data using the session key, deserializes it all, and hands it to the php script. Then when it closes the session for that request-response cycle it serializes it all and puts it back in the db.
So the mess in dealing with all that can, in some cases, be worse than the mess of just opening a connection and asking the db for the same stuff (or a subset of stuff) directly.
I would say that putting one or two key values in the session is a good stopping place, and relying on it too heavily for statefulness is a less-optimal plan.
I would set a new session with a name like "ValuesInSession" to true or false depending on whether or not you have session values for the fields in your user class. Then, in the sessions\users class you can check whether this session is true or false and set your values accordingly (IE from the existing sessions or to empty strings\0)
EDIT: You could, alternatively to putting that code in the user or sessions class, write a new class which could work with your users class to set the values properly (perhaps it could extend the sessions class?)
I'm not sure I understand the question, however, if you are using php 5, you can use the __set magic method to help with this.
Modifying your current class:
class User
{
private $id;
private $data = array();
public function __construct()
{
global $session;
$this->id = $session->get('auto_id');
$this->data = array(
'disp_name'=>$session->get('disp_name'),
'pic_url'=>$session->get('pic_url'),
'gender'=>$session->get('gender'),
'user_role'=>$session->get('user_role'),
'lat'=>$session->get('lat'),
'long'=>$session->get('long'),
'newregister'=>$session->get('newregister')
);
}
// return the user id
public function id()
{
return $this->id;
}
// the __get magic method is called when trying to retrieve a value of a
// property that has not been defined.
public function __get($name)
{
if(array_key_exists($name, $this->data))
{
return $this->data[$name];
}
return null;
}
// the __set magic method is called when trying to store a value in a property
// that has not been defined.
public function __set($name, $value)
{
global $session;
// check if the key exists in the 'data' array.
// if so, set the value in the array as well as the session
if(array_key_exists($name, $this->data))
{
$this->data[$name] = $value;
$session->set($name, $value);
}
}
}
This way you can still get and set values the same as you were, but will also store the set the value in your session class.
To test this:
$user = new User;
if($user->id())
{
echo $user->disp_name;
$user->disp_name = 'new name';
echo $session->get('disp_name');
}
I would not suggest you that because:
It is not a good practice to select an architecture "in case of future need" ('the reason I made it was so I could easily change'). Check http://www.startuplessonslearned.com (Eric Ries) or http://highscalability.com articles
Your code is hard/impossible to test (See Misko Hevery's blog (A google evangelist) http://misko.hevery.com for further information).
You are using "global" (never a good idea if you want to keep track of the dependencies).
It is better to seperate "the business logic" (a User class) and the wiring/building (a factory class for example). (See http://en.wikipedia.org/wiki/Single_responsibility_principle and "separation of concerns")
For really good code examples (and to understand which OO laws should not be broken), I can advice you Misko's blog (Also do not miss his technical talks at google that you can find on youtube). I am sure you will love them.
Hope this helps.

Categories