objects namespaces and application architecture
Classes and Objects
A class is a blueprint for a kind of value in your application. An object is one actual instance of that class at runtime.
Classes become useful when data and behaviour belong together. Instead of passing loose arrays through many functions, a class can give a concept a name, protect its rules, and make calling code easier to read.
Create a simple class
This class represents one product.
<?php
declare(strict_types=1);
class Product
{
public string $sku;
public string $name;
public int $pricePennies;
}
$product = new Product();
$product->sku = 'KB-101';
$product->name = 'Keyboard';
$product->pricePennies = 2499;
echo $product->name . ' costs ' . $product->pricePennies . ' pennies' . PHP_EOL;
// Prints:
// Keyboard costs 2499 pennies
Product is the class. $product is an object. The object has its own property values.
Objects group related data
An associative array can also hold product data, but the shape is only implied.
<?php
declare(strict_types=1);
$product = [
'sku' => 'KB-101',
'name' => 'Keyboard',
'pricePennies' => 2499,
];
echo $product['name'] . PHP_EOL;
// Prints:
// Keyboard
Arrays are still useful, especially at boundaries such as JSON, CSV, and database rows. Classes become more useful when the same concept appears repeatedly and has rules or behaviour.
Put behaviour next to the data
A method is a function that belongs to a class.
<?php
declare(strict_types=1);
class BasketLine
{
public int $unitPricePennies;
public int $quantity;
public function lineTotalPennies(): int
{
return $this->unitPricePennies * $this->quantity;
}
}
$line = new BasketLine();
$line->unitPricePennies = 1299;
$line->quantity = 3;
echo $line->lineTotalPennies() . PHP_EOL;
// Prints:
// 3897
$this means "this object". Inside the method, $this->unitPricePennies reads the property from the object the method was called on.
Every object has its own state
Two objects created from the same class can hold different values.
<?php
declare(strict_types=1);
class Counter
{
public int $value = 0;
public function increment(): void
{
$this->value++;
}
}
$first = new Counter();
$second = new Counter();
$first->increment();
$first->increment();
$second->increment();
echo $first->value . PHP_EOL;
echo $second->value . PHP_EOL;
// Prints:
// 2
// 1
Both objects use the same class definition, but each object has its own property values.
Classes should model real responsibilities
Do not create classes just to wrap one unrelated function. A useful class usually represents a concept in the system: Product, Order, Invoice, Money, UserRegistration, PasswordResetToken, CsvImporter, or EmailMessage.
<?php
declare(strict_types=1);
class EmailMessage
{
public string $recipient;
public string $subject;
public string $body;
public function preview(): string
{
return $this->subject . ' -> ' . $this->recipient;
}
}
$message = new EmailMessage();
$message->recipient = 'nia@example.com';
$message->subject = 'Welcome';
$message->body = 'Hello Nia';
echo $message->preview() . PHP_EOL;
// Prints:
// Welcome -> nia@example.com
The class name should help another developer understand what the object is responsible for.
Watch the limits of public properties
Public properties are easy to learn, but they allow invalid objects.
<?php
declare(strict_types=1);
class OrderLine
{
public int $unitPricePennies;
public int $quantity;
}
$line = new OrderLine();
$line->unitPricePennies = 1299;
$line->quantity = 0;
echo 'Invalid quantity is possible here' . PHP_EOL;
// Prints:
// Invalid quantity is possible here
Later lessons will fix this with constructors, visibility, and methods that protect the object's rules.
What to remember
Use a class when a concept has a name, data, and behaviour that belong together. An object is one runtime instance of that class. Start simple, name classes after real responsibilities, and watch for invalid state when properties are public.
Practice
Task: Model a basket line
Create a small class for a basket line.
Requirements
- Use
declare(strict_types=1);. - Create a
BasketLineclass. - Give it public properties for
sku,unitPricePennies, andquantity. - Add a
lineTotalPennies()method. - Create two different
BasketLineobjects. - Print each line total.
- Print the combined total.
- Include the expected output as comments in the same PHP code block.
The goal is to show that two objects can come from the same class while holding different state.
Show solution
<?php
declare(strict_types=1);
class BasketLine
{
public string $sku;
public int $unitPricePennies;
public int $quantity;
public function lineTotalPennies(): int
{
return $this->unitPricePennies * $this->quantity;
}
}
$keyboard = new BasketLine();
$keyboard->sku = 'KB-101';
$keyboard->unitPricePennies = 2499;
$keyboard->quantity = 1;
$mouse = new BasketLine();
$mouse->sku = 'MS-202';
$mouse->unitPricePennies = 1299;
$mouse->quantity = 2;
$combinedTotal = $keyboard->lineTotalPennies() + $mouse->lineTotalPennies();
echo $keyboard->sku . ': ' . $keyboard->lineTotalPennies() . PHP_EOL;
echo $mouse->sku . ': ' . $mouse->lineTotalPennies() . PHP_EOL;
echo 'Total: ' . $combinedTotal . PHP_EOL;
// Prints:
// KB-101: 2499
// MS-202: 2598
// Total: 5097
Both objects use the same BasketLine class, but each object has its own SKU, price, and quantity. The method keeps the line-total calculation next to the data it uses.