Web Technology IIUnit 619 min read
PHP OOP: Classes, Objects, Inheritance & Database Links
Unit 6 of Web Technology II covers PHP’s object-oriented programming (OOP) features—classes, objects, inheritance, polymorphism, and abstract classes—with real-world applications in user authentication, database-driven apps, and modular code. Learn how to model data (e.g., Student, User) and connect to MySQL, plus solv
Core Concepts of PHP OOP
1. Classes and Objects: The Blueprint and Instance
Definition:
- A class is a blueprint for creating objects (e.g.,
Car,User). It defines properties (attributes) and methods (functions). - An object is an instance of a class with actual values.
How it works:
class Student {
// Properties (attributes)
public $name;
public $age;
// Methods (functions)
public function greet() {
return "Hello, I'm " . $this->name;
}
}
// Create an object
$ram = new Student();
$ram->name = "Ram";
$ram->age = 20;
echo $ram->greet(); // Output: Hello, I'm Ram
Visual: Class vs. Object
classDiagram
class Student {
+String name
+int age
+String greet()
}
class Ram {
-name: "Ram"
-age: 20
}
Student <|-- Ram : "is an instance of"Real-world analogy:
- Class = Recipe for a pizza (ingredients + steps).
- Object = A specific pizza you order (e.g., "Margherita with extra cheese").
2. Constructors and Destructors
Definition:
- Constructor (
__construct()): Runs when an object is created. Initializes properties. - Destructor (
__destruct()): Runs when an object is destroyed (e.g., page ends).
Example: Login Form User
class User {
public $username;
public $password;
// Constructor
public function __construct($username, $password) {
$this->username = $username;
$this->password = $password;
}
// Destructor
public function __destruct() {
echo "User $this->username logged out.";
}
}
$user = new User("admin", "12345");
Output:
User admin logged out.
Exam Tip:
- Always use constructors to set default values (e.g.,
$this->isLoggedIn = false;).
3. Inheritance: Reusing and Extending Code
Definition:
- Inheritance lets a child class (subclass) inherit properties/methods from a parent class (superclass).
- Uses
extendsandparent::method()to override or reuse methods.
Example: Admin vs. Regular User
class User {
public $username;
protected $role = "user"; // Protected: accessible in child classes
public function login() {
return "$this->username logged in as $this->role.";
}
}
class Admin extends User {
protected $role = "admin";
public function deleteUser($user) {
return "Admin $this->username deleted $user.";
}
}
$admin = new Admin();
$admin->username = "superadmin";
echo $admin->login(); // Output: superadmin logged in as admin.
echo $admin->deleteUser("Ram"); // Output: Admin superadmin deleted Ram.
Visual: Inheritance Hierarchy
classDiagram
class User {
+String username
+String role
+login()
}
class Admin {
+deleteUser(user)
}
User <|-- Admin : "extends"Real-world use in Nepal:
- eSewa: Uses inheritance to separate
Customer(regular users) andAdmin(eSewa staff) classes. TheAdminclass extendsCustomerbut adds methods likeapprovePayment(). - Khalti: Models
User,Merchant, andSupportAgentwith inheritance to share common login logic but add unique features.
4. Polymorphism: Same Method, Different Behavior
Definition:
- Method overriding: Child class redefines a parent method.
- Method overloading: PHP doesn’t support it natively (use variable arguments
...$argsinstead).
Example: Payment Processing
class Payment {
public function process($amount) {
return "Processing \$$amount via default method.";
}
}
class CreditCardPayment extends Payment {
public function process($amount) {
return "Processing \$$amount via Credit Card (2% fee).";
}
}
$payment = new CreditCardPayment();
echo $payment->process(100); // Output: Processing $100 via Credit Card (2% fee).
Visual: Polymorphism in Action
sequenceDiagram
participant Client
participant Payment
participant CreditCardPayment
Client->>Payment: process(100)
Payment->>CreditCardPayment: (overridden)
CreditCardPayment-->>Client: "Processing $100 via Credit Card"Real-world tie-in:
- Pathao Driver App: Uses polymorphism for different payment methods (
CashPayment,KhaltiPayment,CreditCardPayment). TheprocessPayment()method behaves differently for each class.
5. Abstract Classes and Interfaces
Definition:
- Abstract class: Cannot be instantiated. Forces child classes to implement abstract methods.
- Interface: Pure contract (methods without implementation). A class can implement multiple interfaces.
Example: Database Connection
abstract class Database {
abstract public function connect();
}
class MySQL extends Database {
public function connect() {
return "Connected to MySQL using PDO.";
}
}
$mysql = new MySQL();
echo $mysql->connect();
Interface Example: Payment Gateway
interface PaymentGateway {
public function pay($amount);
}
class PayPal implements PaymentGateway {
public function pay($amount) {
return "Paid \$$amount via PayPal.";
}
}
$paypal = new PayPal();
echo $paypal->pay(50); // Output: Paid $50 via PayPal.
Visual: Abstract Class vs. Interface
classDiagram
abstract class Database {
<<abstract>>
+connect()
}
class MySQL {
+connect()
}
Database <|-- MySQL : "implements abstract"
interface PaymentGateway {
+pay(amount)
}
class PayPal {
+pay(amount)
}
PaymentGateway <|.. PayPal : "implements"Real-world use:
- Nepal Stock Exchange (NEPSE): Uses interfaces to standardize trading methods across
Broker,Investor, andAdminclasses. All must implementexecuteTrade()but can do so differently.
6. Access Modifiers: Public, Private, Protected
| Modifier | Accessible In | Example Use Case |
|---|---|---|
public |
Anywhere | $username (visible to all) |
private |
Only within the class | $apiKey (hidden from subclasses) |
protected |
Class + subclasses | $role (shared with child classes) |
Example: Secure User Data
class User {
public $username;
private $password;
protected $lastLogin;
public function setPassword($pass) {
$this->password = md5($pass); // Never store plaintext!
}
}
Exam Tip:
- Use
privatefor sensitive data (e.g., passwords, API keys). - Use
protectedfor data meant for inheritance (e.g.,$roleinAdminclass).
7. Static Properties and Methods
Definition:
- Static: Belongs to the class, not objects. Called using
ClassName::method(). - Use case: Counters, utility functions.
Example: User Counter
class User {
public static $totalUsers = 0;
public function __construct() {
self::$totalUsers++;
}
}
$user1 = new User();
$user2 = new User();
echo User::$totalUsers; // Output: 2
Real-world use in Nepal:
- NTC Website: Uses static methods to count total internet subscribers without creating objects for each user.
8. Magic Methods: __get, __set, __toString
Definition:
- Special methods for dynamic behavior (e.g., lazy loading, type conversion).
Example: Lazy-Loaded User Profile
class User {
private $data = [];
public function __get($key) {
return $this->data[$key] ?? null;
}
public function __set($key, $value) {
$this->data[$key] = $value;
}
public function __toString() {
return "User: " . $this->name;
}
}
$user = new User();
$user->name = "Hari"; // Uses __set
echo $user->name; // Uses __get
echo $user; // Uses __toString
Output:
Hari
User: Hari
9. PHP OOP with Databases (PDO Example)
Step-by-Step: Login System with MySQL
<?php
// 1. Define User class
class User {
private $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function login($username, $password) {
$stmt = $this->db->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, md5($password)]);
return $stmt->fetch();
}
}
// 2. Database connection
$db = new PDO("mysql:host=localhost;dbname=webtech", "root", "");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 3. Create User object and test login
$user = new User($db);
$loginResult = $user->login("admin", "12345");
if ($loginResult) {
header("Location: home.php");
} else {
echo "Login failed!";
}
?>
Visual: Database Connection Flow
sequenceDiagram
participant Client
participant UserClass
participant PDO
participant MySQL
Client->>UserClass: login("admin", "12345")
UserClass->>PDO: prepare("SELECT...")
PDO->>MySQL: execute()
MySQL-->>PDO: fetch()
PDO-->>UserClass: User object
UserClass-->>Client: Redirect to home.phpReal-world tie-in:
- Khalti’s Login System: Uses PDO to securely fetch user data from MySQL and validate credentials before redirecting to the dashboard.
10. Error Handling in OOP
Best Practices:
- Use
try-catchfor database operations. - Throw custom exceptions for business logic errors.
Example: Invalid User Exception
class InvalidUserException extends Exception {}
class User {
public function login($username, $password) {
if (empty($username)) {
throw new InvalidUserException("Username cannot be empty!");
}
// ... rest of the login logic
}
}
try {
$user = new User();
$user->login("", "12345");
} catch (InvalidUserException $e) {
echo "Error: " . $e->getMessage();
}
Output:
Error: Username cannot be empty!
In the Real World
eSewa’s User Authentication
- Idea Used: OOP classes (
User,Admin,Customer) with inheritance. - How: The
Adminclass extendsUserand adds methods likeapprovePayment(). Thelogin()method (overridden inAdmin) checks permissions before granting access to the dashboard. - Database Link: PDO connects to eSewa’s MySQL database to verify user credentials.
- Idea Used: OOP classes (
Pathao Driver App’s Payment System
- Idea Used: Polymorphism via interfaces (
PaymentGateway) and abstract classes (Payment). - How: The app implements
KhaltiPayment,CashPayment, andCreditCardPaymentclasses, all inheriting fromPayment. TheprocessPayment()method behaves differently for each class (e.g., Khalti deducts a 2% fee, while cash payments are instant). - Real Example: When a user selects "Pay with Khalti," the app calls
$khaltiPayment->process(500), which internally uses Khalti’s API.
- Idea Used: Polymorphism via interfaces (
NEPSE Trading Platform
- Idea Used: Abstract classes and interfaces for standardized trading.
- How: The
Traderabstract class definesexecuteTrade()andcheckBalance(). Concrete classes likeBrokerandInvestorimplement these methods differently. TheTradeinterface ensures all trading classes supportbuy()andsell(). - Database Link: PDO connects to NEPSE’s PostgreSQL database to fetch stock prices and update portfolios.
Worked Example: Daraz Order Queue System
Problem: Daraz wants to model an order queue where:
- Orders have
orderId,customer,status(e.g., "pending," "shipped"). - Admins can cancel orders, and customers can track status.
Solution:
<?php
class Order {
public $orderId;
public $customer;
protected $status;
public function __construct($orderId, $customer) {
$this->orderId = $orderId;
$this->customer = $customer;
$this->status = "pending";
}
public function updateStatus($newStatus) {
$this->status = $newStatus;
}
}
class AdminOrder extends Order {
public function cancelOrder() {
$this->status = "cancelled";
return "Order #$this->orderId cancelled by admin.";
}
}
class CustomerOrder extends Order {
public function trackStatus() {
return "Order #$this->orderId: $this->status";
}
}
// Simulate Daraz's order flow
$order = new CustomerOrder(1001, "Ram");
echo $order->trackStatus() . "\n"; // Order #1001: pending
$adminOrder = new AdminOrder(1001, "Ram");
echo $adminOrder->cancelOrder() . "\n"; // Order #1001 cancelled by admin.
echo $order->trackStatus(); // Order #1001: cancelled (inherited)
?>
Output:
Order #1001: pending
Order #1001 cancelled by admin.
Order #1001: cancelled
Visual: Daraz Order Flow
stateDiagram-v2
[*] --> Pending: Order created
Pending --> Shipped: Admin updates status
Pending --> Cancelled: Admin cancels
Shipped --> Delivered: Courier updates
Cancelled --> [*]
Delivered --> [*]Comparison Table: OOP vs. Procedural PHP
| Feature | OOP | Procedural PHP |
|---|---|---|
| Code Organization | Classes/objects | Functions + global variables |
| Reusability | High (inheritance) | Low (copy-paste code) |
| Maintainability | Easy (modular) | Hard (spaghetti code) |
| Security | Better (encapsulation) | Risky (global variables exposed) |
| Example | class User { ... } |
function login($user, $pass) { ... } |
Common Pitfalls and How to Avoid Them
Overusing
publicproperties- Problem: Exposes data to unintended modifications.
- Fix: Use
privateproperties withgetter/settermethods.class User { private $email; public function setEmail($email) { $this->email = filter_var($email, FILTER_VALIDATE_EMAIL); } }
Tight Coupling
- Problem: Classes depend on each other directly (hard to reuse).
- Fix: Use dependency injection (pass dependencies as parameters).
class Order { private $paymentGateway; public function __construct(PaymentGateway $gateway) { $this->paymentGateway = $gateway; } }
Ignoring
__destruct- Problem: Resources (e.g., database connections) may leak.
- Fix: Close connections in
__destruct.class Database { public function __destruct() { $this->connection = null; } }
Exam Tip: How to Score Full Marks
For coding questions:
- Always include:
- Class definition with
public/privatemodifiers. - Constructor to initialize properties.
- Methods with proper logic (e.g.,
login()checks credentials). - Error handling (
try-catchorifchecks).
- Class definition with
- Example Starter:
<?php class User { private $username; private $password; public function __construct($username, $password) { $this->username = $username; $this->password = md5($password); // Hash password } public function login($inputPassword) { return $this->password === md5($inputPassword); } } $user = new User("admin", "12345"); if ($user->login("12345")) { echo "Login successful!"; } else { echo "Invalid credentials."; } ?>
- Always include:
For theory questions:
- Define terms clearly (e.g., "Inheritance allows a child class to inherit properties and methods from a parent class.").
- Use diagrams (class diagrams, sequence diagrams) to explain relationships.
- Relate to real-world examples (e.g., "Like how eSewa uses inheritance for
AdminandCustomerclasses...").
Database questions:
- Show the PDO connection code.
- Use prepared statements to prevent SQL injection.
- Example:
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$username]);
JSON/XML parsing:
- Use
json_decode()orsimplexml_load_file(). - Example:
$json = '{"Name": "Gunadi", "Email": "[email protected]"}'; $data = json_decode($json); echo $data->Name; // Output: Gunadi
- Use
Array manipulation:
- For
array_splice(), show both insertion and removal:$fruits = ["apple", "banana", "orange"]; array_splice($fruits, 1, 0, "kiwi"); // Insert "kiwi" at index 1 array_splice($fruits, 1, 1); // Remove 1 element at index 1
- For
Past Exam Questions Solved
Q1: Login Form Redirection
<?php
class Login {
private $username;
private $password;
public function __construct($username, $password) {
$this->username = $username;
$this->password = md5($password);
}
public function validate($inputPassword) {
return $this->password === md5($inputPassword);
}
}
// Simulate form submission
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$user = new Login("admin", "12345"); // Hardcoded for demo; use DB in real apps
if ($user->validate($_POST["password"])) {
header("Location: home.php");
exit();
} else {
echo "Invalid credentials!";
}
}
?>
<!-- HTML Form -->
<form method="post">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
<input type="reset" value="Cancel">
</form>
Q2: Student Object in JavaScript (PHP Equivalent)
<?php
class Student {
public $name = "Ram";
public $age = 20;
public $dob = "2003-02-03";
public function display() {
echo "Name: " . $this->name . "<br>";
echo "Age: " . $this->age . "<br>";
echo "DOB: " . $this->dob;
}
}
$student = new Student();
$student->display();
?>
Q3: PHP.ini Settings
| Setting | Purpose |
|---|---|
display_errors |
Controls whether PHP errors are shown to users (On/Off). |
variables_order |
Defines the order of $_GET, $_POST, etc. (e.g., "GPCS" for all). |
request_order |
Legacy setting (use variables_order instead). |
Example php.ini snippet:
display_errors = Off
variables_order = "GPCS"
Q4: JSON File Parsing
<?php
$json = file_get_contents("BIT.JSON");
$data = json_decode($json);
echo "Name: " . $data->Name . "<br>";
echo "Email: " . $data->Email . "<br>";
echo "Age: " . $data->Age;
?>
Q5: Database Connection and Form Insert
<?php
class Database {
private $conn;
public function __construct() {
$this->conn = new PDO("mysql:host=localhost;dbname=test", "root", "");
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public function insertUser($name, $password) {
$stmt = $this->conn->prepare("INSERT INTO users (name, password) VALUES (?, ?)");
$stmt->execute([$name, md5($password)]);
return $stmt->rowCount();
}
}
// Handle form submission
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$db = new Database();
$rowsAffected = $db->insertUser($_POST["name"], $_POST["password"]);
echo $rowsAffected ? "User added!" : "Error!";
}
?>
<!-- HTML Form -->
<form method="post">
Name: <input type="text" name="name"><br>
Password: <input type="password" name="password"><br>
<input type="radio" name="role" value="user"> User<br>
<input type="radio" name="role" value="admin"> Admin<br>
<input type="submit" value="Submit">
</form>
Summary Checklist for Exams
Before submitting your answer, verify:
- Classes: Defined with proper access modifiers (
public,private). - Objects: Instantiated with
newand properties set. - Methods: Include logic (e.g.,
login()checks credentials). - Database: PDO connection + prepared statements.
- Error Handling:
try-catchor input validation. - Real-world Tie-in: Mention at least one Nepalese app (eSewa, Khalti, etc.).
- Diagrams: Draw class/inheritance diagrams for theory questions.
Based on the TU BIT syllabus for Web Technology II (BIT301), unit 6.
Discussion
Loading…