To elaborate on Lance' answer; if the point of the class is to be nothing more than an container for the data, in stead of doing something with the data you're pretty safe. But a good principal of OOP is to stick to encapsulation. Encapsulation means, amongst other things, that you hide the inner details of your object from the outside and only let the outside access the fields through it's interface methods.
Let's say you don't want the fields in the User object to be altered from the outside, but only accessed, then you'ld be better of with something like the following:
class User
{
private $_userId;
// and a bunch of other fields
public function __construct( $data )
{
// do something with the data
}
public function getUserId()
{
return $this->_userId;
}
// and a bunch of other getters to access the data
}
In all honesty, you could use magic methods like __set and __get to simulate what you want and catch any unwanted altering in the __set method.
Furthermore, I wouldn't use the session as a global variable. You should pass the session object as an argument to it's constructor (like I illustrated in the example). This enforces loose coupling. Because now your User objects are tied to the global session object, but with passing it to the constructor any data could be passed in. This makes the class more flexible.
Edit:
Here's an example of how you could pass an object (for instance your session object) to the constructor. One thing to keep in mind is that, the way your session object is designed, it still, somewhat, enforces tight coupling, because it mandates getting properties through the get() method.
class User
{
public function __construct( $data )
{
$this->_id = $data->get( 'id' );
$this->_firstname = $data->get( 'firstname' );
// etc
}
}
// usage
$session = new YourSessionObject();
$user = new User( $session );
You have a few options at hand to propagate loose coupling, and making you User object a little more flexible.
Mandate that the data for you User object is provided as:
distinct arguments
class User
{
protected $_id;
protected $_firstname;
// etc;
public function __construct( $id, $firstname, /* etc */ )
{
$this->_id = $id;
$this->_firstname = $firstname;
// etc
}
}
// usage
$session = new YourSessionObject();
$user = new User( $session->get( 'id' ), $session->get( 'firstname' ), /* etc */ );
array
class User
{
protected $_fields = array(
'id' => null,
'firstname' => null,
// etc
);
// dictate (type hint) that the argument should be an array
public function __construct( array $data )
{
foreach( $data as $field => $value )
{
if( array_key_exists( $field, $this->_fields )
{
$this->_fields[ $field ] = $value;
}
}
}
}
// usage
$session = new YourSessionObject();
$array = /* fill this array with your session data */;
$user = new User( $array );
implementing some interface
// objects that implement this interface need to implement the toArray() method
interface Arrayable
{
public function toArray();
}
class User
{
protected $_fields = array(
'id' => null,
'firstname' => null,
// etc
);
// dictate (type hint) that the argument should implement Arrayable interface
public function __construct( Arrayable $data )
{
// get the data by calling the toArray() method of the $data object
$data = $data->toArray();
foreach( $data as $field => $value )
{
if( array_key_exists( $field, $this->_fields )
{
$this->_fields[ $field ] = $value;
}
}
}
}
class YourSessionObject implements Arrayable
{
public function toArray()
{
/* this method should return an array of it's data */
}
}
// usage
$session = new YourSessionObject();
$user = new User( $session );
etc
There are a few other options, but this should give you some ideas. Hope this helps.