What are Properties?
According to PHP documentation, member variables in a class are known as properties.
They may also be referred to as fields, but for the sake of this discussion, the term properties shall be used.
As of PHP 7.4, they are defined with at least one modifier (such as visibility, static keyword, or, as of PHP 8.1.0, read-only), optionally (except for read-only properties), followed by a type declaration, then a normal variable declaration.
This declaration may contain an initialization, but it must consist of a constant value.
Note: Using the var keyword instead of a modifier to declare class properties is deprecated.
Note: A property declared without a visibility modifier is public by default.
Non-static properties may be accessed within class methods by using -> (Object Operator): $this->property (where property is the property’s name).
The :: (Double Colon) is utilized to access static properties: self::$property. For additional details on the distinction between static and non-static attributes, see Static Keyword.
The artificial variable when a class method is invoked from within an object context, $this is accessible within the method. $this is the value of the object that is calling.
Example of Property Declaration
<?php
class SimpleClass
{
public $var1 = 'hello ' . 'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
// invalid property declarations:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// valid property declarations:
public $var6 = myConstant;
public $var7 = [true, false];
public $var8 = <<<'EOD'
hello world
EOD;
// Without visibility modifier:
static $var9;
readonly int $var10;
}
?>Note: There are several functions to handle classes and objects. See the reference for Class/Object Functions.
Type Declarations
With the exception of callable, property definitions can include Type declarations as of PHP 7.4.0.
Example of Typed Properties in PHP Class Variables
<?php
class User
{
public int $id;
public ?string $name;
public function __construct(int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}
}
$user = new User(2468, "Prince");
var_dump($user->id);
var_dump($user->name);
?>The above example will output:
int(2468) string(6) "Prince"If typed properties are not initialized before access, an Error is thrown.
Example of Accessing Properties in PHP Class Variables
<?php
class Shape {
public int $numberOfSides;
public string $name;
public function setNumberOfSides(int $numberOfSides): void {
$this->numberOfSides = $numberOfSides;
}
public function setName(string $name): void {
$this->name = $name;
}
public function getNumberOfSides(): int {
return $this->numberOfSides;
}
public function getName(): string {
return $this->name;
}
}
$triangle = new Shape();
$triangle->setName("square");
$triangle->setNumberofSides(4);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());
$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>The above example will output:
string(6) "square" int(4) string(6) "circle"
Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initializationReadonly Properties in PHP Class Variables
Since PHP 8.1.0, a property can be declared with the readonly modifier, which prohibits the property from being modified after initialization.
Example of Readonly Properties in PHP Class Variables
<?php
class Test {
public readonly string $prop;
public function __construct(string $prop) {
// This is a Legal initialization
$this->prop = $prop;
}
}
$test = new Test("sample text");
// This is a Legal read
var_dump($test->prop); // output would be string(11) "sampletext"
// Illegal reassignment. It does not matter that the assigned value is the same.
$test->prop = "sampletext";
// Error: Cannot modify readonly property Test::$prop
?>Note: The readonly modifier is only applicable to typed properties. Using the mixed type, a read-only property without type constraints can be generated.
Note: Not supported are readonly static properties.
A readonly property can only be initialized once, and only inside the declaration’s scope.
Any additional assignment or modification of the property will result in an exception of type Error.
Example of Illegal Initialization of Readonly Properties in PHP Class Initialize Variables
<?php
class Test1 {
public readonly string $prop;
}
$test1 = new Test1;
// Illegal initialization outside of private scope.
$test1->prop = "sample text";
// Error: Cannot initialize readonly property Test1::$prop from global scope
?>The above example will output:
Fatal error: Uncaught Error: Cannot initialize readonly property Test1::$prop from global scopeNote: A readonly property with a default value is essentially the same as a constant and therefore not particularly useful.
<?php
class Test {
// Fatal error: Readonly property Test::$prop cannot have default value
public readonly int $prop = 42;
}
?>The above example will output:
Fatal error: Readonly property Test::$prop cannot have default valueNote: Once initialized, readonly properties cannot be unset using the unset() method.
However, prior to initialization, it is possible to unset a readonly property from the scope where it was declared.
Modifications are not always simple assignments; the following will also generate an Error exception:
<?php class Test { public function __construct( public readonly int $i = 0, public readonly array $ary = [], ) {} } $test = new Test; $test->i += 1; $test->i++; ++$test->i; $test->ary[] = 1; $test->ary[0][] = 1; $ref =& $test->i; $test->i =& $ref; byRef($test->i); foreach ($test as &$prop); ?>
However, readonly features do not prohibit the possibility of inner modification.
Objects (or resources) whose properties are set to readonly can nonetheless be updated internally:
<?php class Test { public function __construct(public readonly object $obj) {} } $test = new Test(new stdClass); // Legal interior mutation. $test->obj->bar = 1; // Illegal reassignment. $test->obj = new stdClass; ?>
Related Articles
- PHP PDO Fetch (With Detailed Explanation)
- PHP trait With Detailed Explanation
- PHP includes With Detailed Explanation
- PHP Escape Quotes With Detailed Explanation
- PHP Remove Element From Array With Examples
Summary
In summary, we have learned about the PHP Class Variable through examples.
I hope you can now apply this information to your PHP project apps.
Lastly, if you want to learn more about PHP Class Variable, please leave a comment below. We’ll be happy to hear it!
Common use cases for PHP Class Variable (Declaration
- Web application development. Full-stack PHP apps using vanilla PHP or Laravel/Symfony frameworks.
- WordPress plugin/theme development. Custom functionality for the world’s most popular CMS.
- API development. REST or GraphQL endpoints serving mobile apps and SPAs.
- CLI tools. Command-line scripts for cron jobs, data migration, or automation.
- Legacy code maintenance. PHP powers a large share of the web; understanding it is a durable skill.
Working code example
<?php
declare(strict_types=1);
class UserService {
public function getGreeting(string $name): string {
if ($name === "") {
throw new InvalidArgumentException("Name is required");
}
return "Welcome, " . htmlspecialchars($name);
}
}
$service = new UserService();
echo $service->getGreeting("Alice");
?>
Best practices
- Enable strict types. declare(strict_types=1) at the top of every file catches type coercion bugs.
- Use Composer. Modern PHP uses Composer for dependency management, autoloading, and PSR-4 class naming.
- Follow PSR standards. PSR-12 for coding style, PSR-4 for autoloading, PSR-3 for logging.
- Write unit tests with PHPUnit. Aim for 70%+ code coverage on business-critical modules.
- Use static analysis. PHPStan or Psalm catch many bugs before code runs.
Common pitfalls
- Global state. Overusing global variables makes testing hard. Prefer dependency injection.
- SQL concatenation. Always use prepared statements. Never concatenate user input into SQL strings.
- Missing type declarations. Old PHP allowed loose types. Modern PHP encourages strict typing everywhere.
- Ignoring errors. Set error_reporting(E_ALL) in development. Handle errors explicitly in production.
