PHP The $this Keyword
Inside a PHP class, $this is a special variable that refers to the current object — the specific instance a method is being called on. It is how a method reaches back into “its own” object to read properties, call other methods, or pass itself around. Understanding $this is essential to object-oriented PHP, because almost every non-static method you write depends on it, whether you type it explicitly or not.
Overview: What Is $this?
When you define a class, you are writing a blueprint. No actual data exists until you create an object from that blueprint with new. Each object created from the same class has its own independent set of property values, even though all objects share the exact same method code. So how does a method know which object’s properties to use when it runs? That is exactly what $this solves.
Every time you call a non-static method on an object, PHP’s engine (the Zend Engine) implicitly passes a reference to the calling object into the method as a hidden first argument. Inside the method body, that reference is exposed to you as the variable $this. You never declare it, never assign it, and never pass it explicitly in the method call — PHP wires it up automatically based on which object you called the method on.
Because $this always points to “the object the method was called on,” the same method body can behave differently depending on which instance invoked it. If you have two Car objects, calling describe() on each one uses the identical method code, but $this->make resolves to a different string for each object because $this is bound to a different object each time.
$this only exists inside object context — that is, inside a non-static method that was called on an actual instance. It does not exist inside static methods, inside plain functions, or before any object has been created. Attempting to use it in those situations produces a fatal error, which is one of the most common mistakes beginners make (covered below).
Syntax
The general form for using $this is:
<?php
class ClassName
{
public function methodName()
{
$this->propertyName; // read or write a property
$this->otherMethod(); // call another instance method
return $this; // return the current object itself
}
}
| Part | Meaning |
|---|---|
$this |
A reference to the object the current method was called on. Not a copy — the actual object. |
-> |
The object operator, used to access a property or method belonging to the object $this refers to. |
$this->property |
Reads or writes an instance property on the current object. |
$this->method() |
Calls another non-static method on the current object. |
return $this; |
Returns the current object, enabling method chaining. |
Note that $this is always accessed with the object operator ->, never with :: (that is reserved for static access via self::, static::, or a class name).
Examples
Example 1: Setting and reading properties in a constructor
<?php
class Car {
public string $make;
public string $model;
public int $year;
public function __construct(string $make, string $model, int $year) {
$this->make = $make;
$this->model = $model;
$this->year = $year;
}
public function describe(): string {
return "{$this->year} {$this->make} {$this->model}";
}
}
$car = new Car("Toyota", "Corolla", 2023);
echo $car->describe();
Output:
2023 Toyota Corolla
The constructor receives three local parameters ($make, $model, $year) and uses $this to copy each one onto the object’s own properties. Without $this->, the assignments would just overwrite the local parameter variables and vanish once the constructor finished — the object’s properties would remain uninitialized. Inside describe(), $this->year, $this->make, and $this->model read back the values that were stored on this particular Car instance.
Example 2: Method chaining with a fluent interface
<?php
class QueryBuilder {
private array $wheres = [];
private string $table = '';
public function table(string $name): static {
$this->table = $name;
return $this;
}
public function where(string $condition): static {
$this->wheres[] = $condition;
return $this;
}
public function toSql(): string {
$sql = "SELECT * FROM {$this->table}";
if (!empty($this->wheres)) {
$sql .= " WHERE " . implode(" AND ", $this->wheres);
}
return $sql;
}
}
$query = (new QueryBuilder())
->table("users")
->where("age > 18")
->where("active = 1")
->toSql();
echo $query;
Output:
SELECT * FROM users WHERE age > 18 AND active = 1
This is the classic use of return $this;: each method mutates the object and then hands the exact same object back to the caller, so another method can immediately be called on the result. That is what lets you chain ->table()->where()->where()->toSql() into one expression. The return type static tells PHP (and your editor) that the method returns “whatever class this actually is,” which matters correctly in subclasses too.
Example 3: $this inside closures
<?php
class Cart {
private array $items = [];
public function __construct(array $items) {
$this->items = $items;
}
public function total(): float {
return array_reduce(
$this->items,
fn(float $carry, array $item): float => $carry + ($item['price'] * $item['qty']),
0.0
);
}
public function summary(): string {
$lines = array_map(
function (array $item): string {
return "{$item['qty']}x {$item['name']} (this cart has " . count($this->items) . " line items)";
},
$this->items
);
return implode("\n", $lines);
}
}
$cart = new Cart([
['name' => 'Keyboard', 'price' => 45.00, 'qty' => 1],
['name' => 'Mouse', 'price' => 20.00, 'qty' => 2],
]);
echo $cart->total() . "\n";
echo $cart->summary();
Output:
85
1x Keyboard (this cart has 2 line items)
2x Mouse (this cart has 2 line items)
Both the arrow function (fn) and the regular anonymous function here are defined inside a method, and both are able to use $this even though they are technically separate closures. Since PHP 5.4, closures created inside a method automatically bind to the enclosing object, so $this inside them refers to the same Cart instance as the outer method — you do not need use ($this) or any manual binding.
How $this Works Under the Hood
PHP objects are stored as “handles” on the Zend Engine’s heap, not as plain values copied around like arrays or strings. When you write $car = new Car(...), the variable $car holds a reference-like handle pointing to a single object in memory. When you call $car->describe(), the engine does roughly the following:
- It looks up the
describemethod on theCarclass (or an ancestor class, following the inheritance chain). - It creates a new call frame for that method invocation and silently binds the handle for
$carinto that frame as the variable$this. - Execution proceeds through the method body. Any
$this->propertyaccess reads or writes directly on the same object$carrefers to — there is no copying. - When the method returns, the call frame (including its local
$thisbinding) is discarded, but the underlying object continues to exist as long as something still references it.
Because $this is a reference to the real object rather than a copy, mutating $this->property inside a method changes the same object every other variable pointing at it sees — there is only ever one object in memory for a given instance, no matter how many variables or method calls currently reference it.
This binding is set up per call, based on how the method was invoked, not on how it was written. That is why calling describe() on two different Car objects gives two different results from the same compiled method code: the engine rebinds $this to whichever object appears to the left of -> at the call site.
Common Mistakes
Mistake 1: Using $this inside a static method
Static methods belong to the class itself, not to any particular instance, so there is no object for $this to refer to. Trying to use it there is a fatal error at runtime:
<?php
class Counter {
private static int $count = 0;
public static function increment(): void {
$this->count++; // Fatal error: Using $this when not in object context
}
}
The fix is to use self:: (or static:: for late static binding) to reach static properties, since static members belong to the class, not to $this:
<?php
class Counter {
private static int $count = 0;
public static function increment(): void {
self::$count++;
}
public static function getCount(): int {
return self::$count;
}
}
Counter::increment();
Counter::increment();
echo Counter::getCount();
Output:
2
Mistake 2: Forgetting the -> and using a bare local variable
A very common typo is writing a plain variable name where you meant a property access. PHP will not warn you that you “meant” a property — it just treats the bare name as an ordinary local variable, which is a completely different piece of storage:
<?php
class User {
private string $name;
public function __construct(string $name) {
$name = $name; // Bug: reassigns the local parameter to itself; $this->name is never set
}
public function getName(): string {
return $name; // Bug: $name is an undefined local variable here, not $this->name
}
}
The corrected version explicitly qualifies every access to the object’s property with $this->, so it is unmistakably different from the constructor’s local $name parameter:
<?php
class User {
private string $name;
public function __construct(string $name) {
$this->name = $name;
}
public function getName(): string {
return $this->name;
}
}
$user = new User("Priya");
echo $user->getName();
Output:
Priya
Best Practices
- Always qualify property and method access on the current object with
$this->— never rely on a bare variable name that happens to match a property name. - Use
self::orstatic::for static members; reserve$thisstrictly for instance (non-static) context. - Return
$thisfrom setter-style methods only when you deliberately want a fluent, chainable API — mixing chainable and non-chainable methods inconsistently confuses callers. - Type-hint the return of chainable methods as
staticrather than the concrete class name, so subclasses inherit correct chaining behavior. - Remember closures defined inside a method auto-bind
$this; you do not need to pass the object in manually viause. - Never try to access
$thisin a static method, in a plain function, or before an object has been fully constructed.
Practice Exercises
- Write a
Rectangleclass withwidthandheightproperties set in the constructor using$this, plus anarea()method that returns$this->width * $this->height. Create an instance with width 4 and height 5, and echo the area. - Write a
StringBuilderclass with anappend(string $text): staticmethod that appends to an internal property and returns$this, plus abuild(): stringmethod. Chain three calls toappend()and then callbuild()to produce one combined string. - Predict, without running it, what error PHP raises if you remove the constructor entirely from Example 1’s
Carclass but keepdescribe()unchanged, then explain why$this->makewould fail at runtime.
Summary
$thisis a built-in variable available inside non-static methods that refers to the specific object the method was called on.- PHP binds
$thisautomatically at call time — you never assign it yourself. $this->propertyreads/writes instance data;$this->method()calls another instance method;return $this;enables method chaining.$thisrefers to the real object in memory, not a copy, so changes made through it are visible everywhere else that object is referenced.$thisdoes not exist in static methods — useself::orstatic::there instead.- Closures defined inside a method automatically capture the enclosing
$this, no manual binding required.
