Writing a model for a user (php) - php

I have a users model that has a lot of properties such as first_name, last_name, email, address, address2...etc
I am writing a php class to manage these properties, but it seems like I am writing a lot of the same code. (Getters and setters). Should I use magic methods to manage this? It seems like an OK idea, but I don't want incorrect properties being set. Any ideas?
<?php
class User
{
private $username;
private $email
private $first_name;
private $last_name;
private $address;
private $address2;
function __construct()
{
}
function getUsername()
{
return $this->username
}
function setUsername($username)
{
$this->username = $username;
}
...
}
?>

Unless you are doing validation on the input, there's no point using getters/setters here in my opinion.
Make the properties public, and override the getters/setters for invalid properties using magic methods:
class User
{
public $username;
public $email;
public $first_name;
public $last_name;
public $address;
public $address2;
public function __get($var) {
throw new Exception("Invalid property $var");
}
public function __set($var, $value) {
$this->__get($var);
}
}
$user = new User;
$user->username = 'foo'; // works
$user->foo = 'bar'; // errors

First of all, can't you use public properties?
If no and your properties does not require any logic when getting/setting, i would use __get and __set.
If you really don't want "incorrect" properties being set (why?), a option could be to use a whitelist of properties that's okay to set:
function __set($key, $value) {
$whitelist = array("firstname", "lastname", ..);
if(!in_array($key, $whitelist))
throw new Exception("Invalid property");
}

Related

How can I access to public properties/method of an object represented by $this->myObject in my class?

I'm trying to access getters of a custom object. I wanted to send the object to the constructor params (I'm currently sending to the build method (but
My class representing an object that I'd like to display its values :
class User{
private $id;
private $name;
private $email;
public function __construct(int $id, string $name, string $email) {
$this->id = $id;
$this->name = $name;
$this->email = $email;
}
public function getName(): string {
return $this->name;
}
... // the other getters
}
In my Page :
$myUser = new User(1, "toto", "toto#url.com");
$blockUser = new UserBlock($sqlConnection);
$blockUser->setUser($myUser);
$blockUser->build();
interface IBlock :
interface IBlock {
function __construct($sqlConnection);
function build();
}
UserBlock class:
class UserBlock implements IBlock {
private $myUser;
public function __construct($sqlConnection) {
...
}
public setUser($myUser) {
$this->myUser = $myUser;
}
function build() {
echo "Name = ".$this->myUser->getName(); // ERROR: Doesn't know the type of $this->myUser so can't access to getName method.
$tempVarUser = $this->myUser;
echo "Name = ".$tempVarUser->getName(); // ERROR: Doesn't know the type of $tempVarUser so can't access to getName method.
}
}
With my code structure, how can I access to the properties and methods of the object User represented by the variable $this->myUser in the UserBlock class ?
I have to remove the implements of the Interface and send the User object to the build method as parameter (which is not allowing by my interface here).
Hope this is clear. Thanks for your help.

PHP class return nothing

I'm just beginner with PHP OOP. I have a class and output is empty:
$test = new form('name1', 'passw2');
$test->getName();
and class:
<?php
class form
{
protected $username;
protected $password;
protected $errors = array();
function _construct($username, $password){
$this->username=$username;
$this->password=$password;
}
public function getsomething() {
echo '<br>working'. $this->getn() . '<-missed';
}
public function getName(){
return $this->getsomething();
}
public function getn() {
return $this->username;
}
}
?>
And output is only text without username:
POST working
working<-missed
Where is name1?
I've modifed your code a bit and added some examples to play around with.
This should get you started.
class form
{
protected $username;
protected $password;
protected $errors = array();
// construct is a magic function, two underscores are needed here
function __construct($username, $password){
$this->username = $username;
$this->password = $password;
}
// functions starting with get are called Getters
// they are accessor functions for the class property of the same name
public function getPassword(){
return $this->password;
}
public function getUserName() {
return $this->username;
}
public function render() {
echo '<br>working:';
echo '<br>Name: ' . $this->username; // using properties directly
echo '<br>Password:' . $this->password; // not the getters
}
}
$test = new form('name1', 'passw2');
// output via property access
echo $test->username;
echo $test->password;
// output via getter methods
echo $test->getUserName();
echo $test->getPassword();
// output via the render function of the class
$test->render();
Hi You have used _construct it should be __contrust(2 underscores)

Handling Object Dependency

Consider the following class
class User
{
protected $password;
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
}
I want to apply bcrypt on password using Zend\Crypt\Password\Bcrypt in user object, since this creates a dependency i want to know how to correctly deal with this, i can think about several approaches to make this work, let me elaborate
Approach 1 : Here we instantiate the class inside the method and apply required changes.
class User
{
protected $password;
public function setPassword($password)
{
$bcrypt = new Bcrypt();
$this->password = $bcrypt->create($password);
return $this;
}
public function getPassword()
{
return $this->password;
}
public function verifyPassword($password)
{
$bcrypt = new Bcrypt();
return $bcrypt->verify($password, $this->getPassword());
}
}
Towards my understanding this is not recommended approach since i see two problems here
Bcrypt() is instantiated twice
This makes User object tightly coupled with Bcrypt
I can solve problem-1 by instantiating Bcrypt() once in class constructor and use it whenever required, however this does not solve problem-2
Approach 2 : Move Bcrypt object out of user class and inject it while setting the password
class User
{
protected $password;
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
}
// Init Bcrypt
$bcrypt = new Bcrypt;
// Instantiate user object and create a password
$user = new User;
$user->setPassword($bcrypt->create($password));
// Verify user password
if ($bcrypt->verify($password, $user->getPassword())) {
// Password is verified
}
What is the best way to about it ?
Thanks.
And maybe you can just create a Password class and move this logic there?
You can either do something like this:
class Password
{
private $password;
public __construct($password)
{
$this->password = $password;
}
public crypt(Zend_Crypt_Password_PasswordInterface $crypt)
{
$this->password = $crypt->create($password);
}
}
or use a Decorator.
Both solution gives you a possibility for extending your code.
Instead of Zend_Crypt_Password_PasswordInterface you can also use your own Wrapper. It would be IMHO even better solution.
And then you can set the password for particular user and it does not care whether it was crypted, hashed or whatever:
class User
{
private $password;
public function changePassword(Password $password)
{
$this->password = $password;
}
}
I guess first approach is better because its hide using of bcrypt within User class.
I dont think that other programmer have to keep in mind that he have to use, for example, $bcrypt->verify when working with User class.

How to retrieve array variables in a class

I'm new to OOP and very confused about it. A class that collected user info from database based on the ID passed though:
class user {
public $profile_data;
public function __construct($profile_user_id) {
$this->profile_data = user_data($profile_user_id, 'id', 'username', 'password', 'email', 'admin');
}
}
$profile_data[] = new user(1);
How do I get all the variables in the array? How do I echo out the username for example?
Simply try this.
class user {
public $profile_data;
public function __construct($profile_user_id) {
$this->profile_data = user_data($profile_user_id, 'id', 'username', 'password', 'email', 'admin');
}
}
$userObj = new user(1);
$profileData = $userObj->profile_data;
echo $profileData['username'];
Assuming your user_data function is returning an associative array of data, you should be able to access the fields using as such:
$profile = new user(1);
echo $profile->profile_data['username'];
As in Lighthart's example, it would be good practice to create private variables, with functions to access them.
Another option would be to implement the ArrayAccess interface (http://php.net/manual/en/class.arrayaccess.php) Using this interface, you would be able to use your object similarly to how you use an array. That is, you could use:
echo $user['username'];
As a starting point, you could try something like:
class user implements ArrayAccess {
private $data;
public function __construct($profile_user_id) {
$this->data= user_data($profile_user_id, 'id', 'username', 'password', 'email', 'admin');
}
public function offsetSet($offset, $value) {
// Do nothing, assuming non mutable data - or throw an exception if you want
}
public function offsetExists($offset) {
return isset($this->data[$offset]);
}
public function offsetUnset($offset) {
// Do nothing, assuming non mutable data - or throw an exception if you want
}
public function offsetGet($offset) {
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
}
The example you have given probably won't work for what you are trying to accomplish. It is not clear what function userdata does. Revised:
class User {
private $id;
private $username;
private $password;
private $email;
private $admin;
public function __construct($id, $username, $password, $email, $admin) {
$profileData = user_data($profile_user_id
,'id'
,'username'
,'password'
,'email'
,'admin');
$this->id = $profileData ['id'];
$this->username = $profileData ['username'];
$this->password = $profileData ['password'];
$this->email = $profileData ['email'];
$this->admin = $profileData ['admin'];
}
public function getId(){ return $this->id; }
public function getUsername(){ return $this->username; }
public function getEmail(){ return $this->email; }
public function getAdmin(){ return $this->admin; }
public function setAdmin($admin){ $this->admin = $admin; }
}
The variables are set private. Only the user object should have access to the data directly. However, other objects might want to retrieve the data, which is why there are 4 public get functions. getPassword was omitted because you probably don't want that one publicly available. Also, it is concievable you might set a new admin, so a public setter function was added as well. you would instance the new user (that is, take the class and make a real example of it) thusly:
$user1 = new User(1);
And during usage you would echo these variables by:
echo $user1->getUsername();
Please accept my apologies for not directly answering your question, but that example is headed for trouble.

PHP operating on a variable upon setting it in PHP

This might look as a stupid question. But, I have a class with some public string variables defined in it.
Upon assigning a value to a property:
$a = new user();
$a->FirstName = "sth";
I want to store the value as UTF8.
I know I can do this via:
$a->Firstname = utf8_encode("sth");
However, I want the object to do this automatically.
How can I do this?
Otherwise no, the object cannot do it automatically.
Not automatically, but automagically!
<?php
class User {
/**
* Change the public to private/protected!
*/
private $Firstname;
/**
* This is automatically called upon calling a value that can't be written "from the outside".
*/
public function __set( $key, $value ) {
$this->$key = utf8_encode( $value );
}
public function __get( $key ) {
return isset( $this->$key ) ? $this->$key : false;
}
}
$user = new User;
$user->Firstname = 'Berry';
echo $user->Firstname;
The better solution would be to refactor in using mutators and accessors, or better yet, learn OO.
You want to use setters and getters. See: http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29
Like:
class User
{
protected $Firstname;
public function setFirstname($Firstname) {
$this->Firstname = utf8_encode($Firstname);
}
public function getFirstname() {
return $this->Firstname;
}
}
Example using magic methods:
class User
{
protected $data = array(
'Firstname' => '',
// ...
);
public function __set($key, $value) {
if (isset($this->data[$key])) {
$this->data[$key] = utf8_encode($value);
}
}
public function __get($key) {
return isset($this->data[$key]) ? $this->data[$key] : null;
}
}
Edit: I'm using $data so that there is at least a minimum of control of what properties can be set.
If you'd designed your class to have accessors and mutators, rather than public access to raw variables, then this would be easy.
Original code:
class user {
private $FirstName = '';
public function getFirstName() {
return $this->FirstName;
}
}
Solution code:
class user {
private $FirstName = '';
public function getFirstName() {
return utf8_encode($this->FirstName);
}
}
I suggest moving towards this approach.
Otherwise no, the object cannot do it automatically.
Edit
__set and __get might be the most appropriate way to implement this. I'm not too familiar with them, and it doesn't really matter: the point I'm making here is to use accessors and mutators... however you end up implementing them.

Categories