Skip to content

Instantly share code, notes, and snippets.

@martindilling
Last active May 25, 2021 08:37
Show Gist options
  • Save martindilling/205488b7125147a7ad573eecd64c345b to your computer and use it in GitHub Desktop.
Save martindilling/205488b7125147a7ad573eecd64c345b to your computer and use it in GitHub Desktop.
Example of keeping a class immutable, meaning that from the outside you are not able to modify the object after it has been instantiated.
<?php
class User
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $email;
/**
* @var null|string
*/
private $passwordHash = null;
/**
* User constructor.
*
* @param int $id
* @param string $name
* @param string $email
* @param string $passwordHash If you already have an user, you want to create a user with the existing hash
*/
public function __construct(int $id, string $name, string $email, string $passwordHash = null)
{
$this->id = $id;
$this->name = $name;
$this->email = $email;
$this->passwordHash = $passwordHash;
}
/**
* @return int
*/
public function id() : int
{
return $this->id;
}
/**
* @return string
*/
public function name() : string
{
return $this->name;
}
/**
* @return string
*/
public function email() : string
{
return $this->email;
}
/**
* Check if a given password matches the users password.
*
* @param string $password
*
* @return bool
*/
public function checkPassword(string $password) : bool
{
return password_verify($password, $this->passwordHash);
}
/**
* Get a clone of this instance but with the given name.
*
* @param string $name
*
* @return User
*/
public function withName(string $name) : User
{
$clone = clone $this;
$clone->name = $name;
return $clone;
}
/**
* Get a clone of this instance but with the given email.
*
* @param string $email
*
* @return User
*/
public function withEmail(string $email) : User
{
$clone = clone $this;
$clone->email = $email;
return $clone;
}
/**
* Get a clone of this instance but with the given password.
*
* @param string $password
*
* @return User
*/
public function withPassword(string $password) : User
{
$clone = clone $this;
$clone->passwordHash = $this->hashPassword($password);
return $clone;
}
/**
* A small helper method that handles the password hashing.
*
* @param string $password
*
* @return string
*/
private function hashPassword(string $password) : string
{
return password_hash($password, PASSWORD_BCRYPT);
}
}
///////////////////////////////////////////////////////////////////////////////
// Example
///////////////////////////////////////////////////////////////////////////////
// You can only create a new User if you provide all
// the needed constructor arguments.
$user = new User(
1,
'John',
'john@example.com'
);
// Create a new user with the password set to the given value
$user = $user->withPassword('secret');
// Create a new user with the email changed
$user = $user->withEmail('john.doe@example.com');
// Some output
var_dump($user->checkPassword('wrong')); // false
var_dump($user->checkPassword('secret')); // true
var_dump($user->id()); // 1
var_dump($user->name()); // 'John'
var_dump($user->email()); // 'john.doe@example.com'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment