PHP What is OOP
What Is Object-Oriented Programming? In simple terms: Object-oriented programming (OOP) organizes code around objects — units that combine data (what something is ) with behavior (what it can do ). A
What Is Object-Oriented Programming?
In simple terms: Object-oriented programming (OOP) organizes code around objects — units that combine data (what something is) with behavior (what it can do). A bank account object knows its balance and knows how to accept deposits and withdrawals; a shopping cart object knows its items and how to calculate its total.
Technically: In OOP, you define classes — blueprints that describe the properties (data) and methods (functions) of a kind of thing — and create objects (instances) from them. PHP has supported OOP since PHP 5 and has steadily added modern features: typed properties, constructor promotion, enums, readonly properties, and property hooks (PHP 8.4).
Procedural vs Object-Oriented
So far, most examples in this tutorial used procedural code: data in variables and arrays, processed by separate functions. That works well for small scripts. As applications grow, OOP helps keep code organized:
| Procedural | Object-Oriented |
|---|---|
| Data (arrays) and functions are separate | Data and the functions that operate on it are combined |
| Any code can change any data | Objects control access to their own data |
| Related functions are grouped by naming conventions | Related behavior lives in one class |
| Reuse by copying or calling functions | Reuse through composition, inheritance, and interfaces |
| Good for small scripts | Good for larger, long-lived applications |
A Comparison: Bank Account
Procedural Version
<?php
$account = ['owner' => 'Asha', 'balance' => 1000.0];
function deposit(array $account, float $amount): array
{
$account['balance'] += $amount;
return $account;
}
$account = deposit($account, 500);
$account['balance'] = -999999; // nothing prevents this
echo $account['balance'] . "\n";
Output
-999999
The rules for a valid account (no negative deposits, no overdrafts) live in functions, but any code can bypass them and change the array directly. As a project grows, such changes happen in many places, and nobody can guarantee that the data is valid.
Object-Oriented Version
<?php
class BankAccount
{
private float $balance = 0.0;
public function __construct(private string $owner) {}
public function deposit(float $amount): void
{
if ($amount <= 0) {
throw new InvalidArgumentException('Deposit must be positive.');
}
$this->balance += $amount;
}
public function withdraw(float $amount): void
{
if ($amount > $this->balance) {
throw new RuntimeException('Insufficient balance.');
}
$this->balance -= $amount;
}
public function balance(): float
{
return $this->balance;
}
}
$account = new BankAccount('Asha');
$account->deposit(1000);
$account->withdraw(300);
echo "Balance: " . $account->balance() . "\n";
try {
$account->withdraw(5000);
} catch (RuntimeException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
try {
$account->balance = -999999;
} catch (Error $e) {
echo get_class($e) . ": " . $e->getMessage() . "\n";
}
Output
Balance: 700
Error: Insufficient balance.
Error: Cannot access private property BankAccount::$balance
What Changed
- The balance is private: only the class's own methods can change it. Direct access from outside is rejected with an
Error. - All rules live in one place —
deposit()andwithdraw()— and are applied every time. - Code using the class does not need to know how the balance is stored; it only uses the public methods.
This idea — protecting data behind methods that enforce the rules — is called encapsulation, and it is the most important benefit of OOP.
The Core Concepts
| Concept | Meaning | Covered In |
|---|---|---|
| Class | A blueprint that defines properties and methods | PHP Classes/Objects |
| Object | An instance of a class with its own data | PHP Classes/Objects |
| Property | A variable that belongs to an object | PHP Properties |
| Method | A function that belongs to a class | PHP Methods |
| Constructor | A method that initializes a new object | PHP Constructor |
The Four Principles of OOP
| Principle | Idea | Example |
|---|---|---|
| Encapsulation | Hide internal data; expose a controlled public interface | A private balance changed only via deposit() and withdraw() |
| Abstraction | Show what an object does, hide how | $mailer->send($email) without knowing SMTP details |
| Inheritance | A class reuses and extends another class | SavingsAccount extends BankAccount |
| Polymorphism | Different classes can be used through the same interface | Every PaymentGateway has charge(), whether it is Razorpay or Stripe |
Polymorphism in a Nutshell
<?php
interface Shape
{
public function name(): string;
public function area(): float;
}
class Circle implements Shape
{
public function __construct(private float $radius) {}
public function name(): string
{
return 'Circle';
}
public function area(): float
{
return M_PI * $this->radius ** 2;
}
}
class Rectangle implements Shape
{
public function __construct(private float $width, private float $height) {}
public function name(): string
{
return 'Rectangle';
}
public function area(): float
{
return $this->width * $this->height;
}
}
$shapes = [new Circle(2), new Rectangle(3, 4)];
foreach ($shapes as $shape) {
echo $shape->name() . ': ' . number_format($shape->area(), 2) . "\n";
}
Output
Circle: 12.57
Rectangle: 12.00
Why This Is Powerful
- The loop does not care which kind of shape it has; it only relies on the
Shapeinterface. - Adding a new shape (a triangle, for example) requires a new class, but no change to the loop.
- In real applications, the same idea lets you swap a payment provider, a storage system, or a mail service without changing the code that uses it.
Interfaces and polymorphism are covered in PHP Interfaces and Polymorphism.
Benefits of OOP
| Benefit | How OOP Provides It |
|---|---|
| Maintainability | Related data and behavior are kept together, so changes are made in one place |
| Data integrity | Encapsulation prevents invalid states |
| Reusability | Classes can be reused across projects and composed into larger systems |
| Testability | Objects with clear interfaces can be tested in isolation, and dependencies can be replaced with test doubles |
| Collaboration | Teams can work on separate classes with well-defined interfaces |
| Ecosystem | Frameworks (Laravel, Symfony) and Composer packages are object-oriented |
When Procedural Code Is Fine
OOP is not required for everything. Short scripts, simple command-line tools, and small one-page features are often clearer as a few functions. Use OOP when data has rules that must always be enforced, when the code base grows, or when different implementations of the same behavior are needed.
OOP in Real PHP Applications
In a typical Laravel or Symfony application, almost everything is an object:
| Object | Responsibility |
|---|---|
Request / Response | Represent the HTTP request and response |
| Controllers | Handle requests and choose responses |
Models / Entities (Order, User) | Represent business data and rules |
Services (PaymentService, InvoiceGenerator) | Perform business operations |
| Repositories | Load and save objects in the database |
Value objects (Money, EmailAddress) | Represent small, validated values |
Learning OOP concepts is therefore essential for working with modern PHP frameworks and libraries.
Common Misconceptions
"OOP Means Putting Functions Into Classes"
Grouping unrelated static functions in a class (Utils::doEverything()) is still procedural code. OOP is about objects that own their data and enforce their rules.
"Everything Should Use Inheritance"
Deep inheritance hierarchies make code rigid. Modern design prefers composition (objects using other objects) and interfaces; inheritance is used where a true "is-a" relationship exists.
"OOP Is Slower"
The performance difference is negligible for web applications. The maintainability gains far outweigh it.
Best Practices
- Model important concepts of your application as classes with clear responsibilities.
- Keep data private and expose behavior through public methods.
- Depend on interfaces rather than concrete classes where implementations may vary.
- Prefer composition over deep inheritance.
- Use procedural code where it is simpler; use OOP where structure and rules matter.
Official reference: https://www.php.net/manual/en/language.oop5.php