Herança e Polimorfismo
- #PHP
- #MySQL
- #POO
Na quarta parte do meu projeto de sistema de gestão de academias de artes marciais, vou expandir os conceitos de herança e polimorfismo na linguagem PHP.
<?php
include_once "connection.php";
class User
{
private $connection;
private string $name;
private string $description;
private string $pathImage;
private string $phone;
private string $email;
private string $level;
private string $status;
private string $password;
private int $days;
private string $addressline1;
private string $addressline2;
private string $neighborhood;
private string $city;
private string $state;
private string $country;
private string $postal_code;
private string $updatedDate;
private string $createdDate;
public function __construct($name, $description, $phone, $email, $level, $status, $days, $addressline1, $addressline2, $neighborhood, $city, $state, $country, $postal_code, $updatedDate, $pathImage = "", $hashedPassword = "", $createdDate = "")
{
$dbConnection = new Connection();
$this->connection = $dbConnection->connect();
$this->name = $name;
$this->description = $description;
$this->pathImage = $pathImage;
$this->phone = $phone;
$this->email = $email;
$this->level = $level;
$this->status = $status;
$this->password = $hashedPassword;
$this->days = $days;
$this->addressline1 = $addressline1;
$this->addressline2 = $addressline2;
$this->neighborhood = $neighborhood;
$this->city = $city;
$this->state = $state;
$this->country = $country;
$this->postal_code = $postal_code;
$this->updatedDate = $updatedDate;
$this->createdDate = $createdDate;
}
public function create_user()
{
try {
$insert = $this->connection->prepare("INSERT INTO users (name, description, pathImage, phone, email, level, status, password, days, addressline1, addressline2, neighborhood, city, state, country, postal_code, updatedDate, createdDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
echo "</br> INSERT INTO users (name, description, pathImage, phone, email, level, status, password, days, addressline1, addressline2, neighborhood, city, state, country, postal_code, updatedDate, createdDate) VALUES ('$this->name', '$this->description', '$this->pathImage', '$this->phone', '$this->email', '$this->level', '$this->status', '$this->password', '$this->days', '$this->addressline1', '$this->addressline2', '$this->neighborhood', '$this->city', '$this->state', '$this->country', '$this->postal_code', '$this->updatedDate', '$this->createdDate')";
$insert->bind_param("ssssssssdsssssssss", $this->name, $this->description, $this->pathImage, $this->phone, $this->email, $this->level, $this->status, $this->password, $this->days, $this->addressline1, $this->addressline2, $this->neighborhood, $this->city, $this->state, $this->country, $this->postal_code, $this->updatedDate, $this->createdDate);
$result = $insert->execute();
$insert->close();
if (!$result) {
throw new Exception("Error to create a user.");
}
return true;
} catch (Exception $e) {
error_log("Error creating user: " . $e->getMessage());
return false;
}
}
public function update_user_by_id(int $user_id): bool
{
try {
$update = $this->connection->prepare("UPDATE users SET name = ?, description = ?, phone = ?, email = ?, level = ?, status = ?, days = ?, addressline1 = ?, addressline2 = ?, neighborhood = ?, city = ?, state = ?, country = ?, postal_code = ?, updatedDate = ? WHERE user_id = ?");
$update->bind_param("ssssdsssssssssi", $this->name, $this->description, $this->phone, $this->email, $this->level, $this->status, $this->days, $this->addressline1, $this->addressline2, $this->neighborhood, $this->city, $this->country, $this->postal_code, $this->updatedDate, $user_id);
$result = $update->execute();
$update->close();
if (!$result) {
throw new Exception("Error to update a user.");
}
return true;
} catch (Exception $e) {
error_log("Error updating user: " . $e->getMessage());
return false;
}
}
public static function update_user_password_by_id($user_id, $password, $updatedDate): bool
{
$dbConnection = new Connection();
$connection = $dbConnection->connect();
$update = $connection->prepare("UPDATE users SET password = ?, updatedDate = ? WHERE user_id = ?");
$update->bind_param("ssi", $password, $updatedDate, $user_id);
$result = $update->execute();
$update->close();
return $result;
}
public static function update_user_password_by_email($email, $password, $updatedDate): bool
{
$dbConnection = new Connection();
$connection = $dbConnection->connect();
$update = $connection->prepare("UPDATE users SET password = ?, updatedDate = ? WHERE email = ?");
$update->bind_param("ssi", $password, $updatedDate, $email);
$result = $update->execute();
$update->close();
return $result;
}
public function delete_user_by_id(int $user_id): bool
{
$delete = $this->connection->prepare("DELETE FROM users WHERE user_id = ?");
$delete->bind_param("i", $user_id);
$result = $delete->execute();
$delete->close();
return $result;
}
public static function find_user($query)
{
try {
$dbConnection = new Connection();
$connection = $dbConnection->connect();
if (is_numeric($query)) {
$stmt = $connection->prepare("SELECT * FROM users WHERE user_id = ?");
$stmt->bind_param("i", $query);
} else {
$stmt = $connection->prepare("SELECT * FROM users WHERE email = ? OR name = ?");
$stmt->bind_param("ss", $query, $query);
}
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
if ($result->num_rows > 0) {
$user_data = $result->fetch_assoc();
return $user_data;
} else {
return null;
}
} catch (Exception $e) {
error_log("Error finding user: " . $e->getMessage());
return null;
}
}
public static function login_user($email, $password)
{
try {
$dbConnection = new Connection();
$connection = $dbConnection->connect();
$query = "SELECT * FROM users WHERE email = ?";
$stmt = $connection->prepare($query);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 1) {
$user = $result->fetch_assoc();
if (password_verify($password, $user["password"])) {
return $user;
} else {
return false;
}
} else {
return false;
}
$stmt->close();
$connection->close();
} catch (Exception $e) {
error_log("Error during login: " . $e->getMessage());
return false;
}
}
}
Herança é um dos pilares fundamentais da programação orientada a objetos (POO). Ela permite que você crie uma nova classe (conhecida como subclasse ou classe filha) com base em uma classe existente (superclasse ou classe pai). A subclasse herda os atributos e métodos da superclasse, o que promove a reutilização de código e a criação de uma hierarquia de classes. No exemplo que apresentarei, a classe SubUser herda da classe User, o que significa que SubUser possui todos os atributos e métodos de User, além da capacidade de adicionar ou substituir seus próprios.
<?php
include_once "connection.php";
include_once "user.php";
class SubUser extends User
{
private $connection;
private string $type;
public function __construct($name, $description, $phone, $email, $type, $status, $days, $addressline1, $addressline2, $neighborhood, $city, $state, $country, $postal_code, $updatedDate, $pathImage = "", $hashedPassword = "", $createdDate = "")
{
$dbConnection = new Connection();
$this->connection = $dbConnection->connect();
parent::__construct($name, $description, $phone, $email, $type, $status, $days, $addressline1, $addressline2, $neighborhood, $city, $state, $country, $postal_code, $updatedDate, $pathImage, $hashedPassword, $createdDate);
$this->type = $type;
}
public function create_user()
{
try {
$insert = $this->connection->prepare("INSERT INTO users (name, description, pathImage, phone, email, type, status, password, days, addressline1, addressline2, neighborhood, city, state, country, postal_code, updatedDate, createdDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$insert->bind_param("ssssssssdsssssssss", $this->name, $this->description, $this->pathImage, $this->phone, $this->email, $this->type, $this->status, $this->password, $this->days, $this->addressline1, $this->addressline2, $this->neighborhood, $this->city, $this->state, $this->country, $this->postal_code, $this->updatedDate, $this->createdDate);
$result = $insert->execute();
$insert->close();
if (!$result) {
throw new Exception("Error to create a user.");
}
return true;
} catch (Exception $e) {
error_log("Error creating user: " . $e->getMessage());
return false;
}
}
public function update_user_by_id(int $user_id): bool
{
try {
$update = $this->connection->prepare("UPDATE users SET name = ?, description = ?, phone = ?, email = ?, type = ?, status = ?, days = ?, addressline1 = ?, addressline2 = ?, neighborhood = ?, city = ?, state = ?, country = ?, postal_code = ?, updatedDate = ? WHERE user_id = ?");
$update->bind_param("ssssdsssssssssi", $this->name, $this->description, $this->phone, $this->email, $this->type, $this->status, $this->days, $this->addressline1, $this->addressline2, $this->neighborhood, $this->city, $this->country, $this->postal_code, $this->updatedDate, $user_id);
$result = $update->execute();
$update->close();
if (!$result) {
throw new Exception("Error to update a user.");
}
return true;
} catch (Exception $e) {
error_log("Error updating user: " . $e->getMessage());
return false;
}
}
public static function update_user_password_by_id($user_id, $password, $updatedDate): bool
{
$result = parent::update_user_password_by_id($user_id, $password, $updatedDate);
return $result;
return $result;
}
public static function update_user_password_by_email($email, $password, $updatedDate): bool
{
$result = parent::update_user_password_by_email($email, $password, $updatedDate);
return $result;
return $result;
}
public function delete_user_by_id($user_id): bool
{
$result = parent::delete_user_by_id($user_id);
return $result;
}
public static function find_user($query)
{
$result = parent::find_user($query);
return $result;
}
public static function login_user($email, $password)
{
$result = parent::login_user($email, $password);
return $result;
}
}
Polimorfismo é outro conceito crucial da POO que permite que objetos de classes diferentes sejam tratados de maneira uniforme. Isso significa que você pode usar um método com o mesmo nome, mas com diferentes implementações, em várias classes. Em PHP, isso é frequentemente alcançado usando interfaces ou métodos abstratos nas superclasses. O polimorfismo permite que você escreva código mais genérico e flexível, tornando-o valioso em situações em que diferentes classes precisam se comportar de maneira semelhante.
- Classe Base (User): A classe User atua como uma classe base com atributos e métodos comuns para todos os tipos de usuários. Ela possui um construtor que inicializa todos os atributos e métodos para criar, atualizar e buscar usuários no banco de dados. A classe também lida com a autenticação de login.
- Classe Filha (SubUser): A classe SubUser herda da classe User e adiciona um novo atributo chamado type. Ela também redefine os métodos create_user, update_user_by_id, update_user_password_by_id, update_user_password_by_email, delete_user_by_id, find_user, e login_user. O uso do parent:: chama os métodos correspondentes da classe base quando necessário, permitindo a extensão sem duplicação de código.
- Reescrita de Métodos: Os métodos na classe SubUser são reescritos para acomodar o novo atributo type. Por exemplo, o método create_user inclui o tipo de usuário ao inserir no banco de dados. Aqui, o conceito de polimorfismo está sendo aplicado, pois a mesma assinatura de método (create_user) está sendo usada de forma diferente na classe filha.
contate me clicando aqui