Properties & Methods
Properties are the variables that belong to a class, and methods are the functions that belong to it. Together they are what a class actually is: properties hold an object's state, and methods define how that state can be read, changed, or acted on. This page digs into how to declare properties properly — with types and defaults — and into a scoping mistake that trips up almost everyone the first time they meet it.
Declaring typed properties
Since PHP 7.4, properties can (and should) carry a type declaration, the same way function parameters can. A typed property rejects assignments of the wrong kind of value, which catches mistakes far earlier than an untyped property would.
Product with typed properties
<?php
class Product
{
public string $name;
public float $price;
private float $taxRate;
}
$product = new Product();
$product->name = 'Wireless Mouse';
$product->price = 25.00;
// $product->price = 'expensive'; // Fatal error: Cannot assign string to
// property Product::$price of type floatpublic string $name reads as "a public property named $name, which must hold a string." Trying to assign an incompatible value to a typed property is a hard error, not a silent coercion — PHP would rather stop you than let a Product end up with a price that is actually the string 'expensive'.
Giving properties default values
A property can be given a default value right in its declaration. Any object created from the class starts with that value already in place, so you do not have to set it manually every time — only where it needs to differ from the default.
Defaults mean fewer things to set by hand
<?php
class Product
{
public string $name = 'Untitled product';
public float $price = 0.0;
private float $taxRate = 0.08; // most products use the standard rate
}
$product = new Product();
echo $product->name . ': $' . $product->price . "\n";
$product->name = 'Wireless Mouse';
$product->price = 25.00;
echo $product->name . ': $' . $product->price . "\n";Untitled product: $0 Wireless Mouse: $25
Note that default values must be simple, fixed expressions known at compile time — a literal, a constant, or a simple calculation on literals. You cannot default a property to the result of calling a function; that kind of setup belongs in the constructor instead, which the next page covers.
Methods act on $this
A method is just a function defined inside a class, and inside it, $this is how you reach the current object's own properties. Here, applyDiscount() mutates the object's price property directly.
A method that changes the object's own state
<?php
class Product
{
public string $name = 'Untitled product';
public float $price = 0.0;
public function applyDiscount(float $percentOff): void
{
$this->price = round($this->price * (1 - $percentOff / 100), 2);
}
}
$product = new Product();
$product->name = 'Wireless Mouse';
$product->price = 25.00;
$product->applyDiscount(20);
echo $product->name . ': $' . $product->price . "\n";Wireless Mouse: $20
The property-vs-local-variable pitfall
Inside a method, a bare $price and $this->price are two
completely different variables that happen to share a name. $price
is a local variable that lives only for the duration of the method
call; $this->price is the object's property. Forgetting $this->
does not raise an error — PHP happily creates a brand new local
variable instead, silently, and the property is never touched.
Forgetting $this-> silently breaks the update
<?php
class Product
{
public float $price = 25.00;
public function applyDiscountBroken(float $percentOff): void
{
// BUG: assigns to a local variable, not the property
$price = round($price * (1 - $percentOff / 100), 2);
}
public function applyDiscountFixed(float $percentOff): void
{
$this->price = round($this->price * (1 - $percentOff / 100), 2);
}
}
$product = new Product();
$product->applyDiscountBroken(20);
echo 'After broken discount: $' . $product->price . "\n";
$product->applyDiscountFixed(20);
echo 'After fixed discount: $' . $product->price . "\n";After broken discount: $25 After fixed discount: $20
applyDiscountBroken() reads an undefined local $price (treated as null, triggering a warning in modern PHP), does some arithmetic on it, and stores the result in a local variable that vanishes the moment the method returns. The object's actual price property never changes.
Typed properties (
public float $price) reject assignments of the wrong type with a fatal error.Default values in a property declaration must be fixed, compile-time expressions.
Inside a method,
$this->priceis the object's property;$pricealone is a separate local variable or parameter.A method with the same-named parameter as a property must explicitly assign
$this->prop = $param;— nothing does this automatically.