class Goodbye {
const LEAVING_MESSAGE = "Thank you for visiting US!\n";
public function byebye() {
echo self::LEAVING_MESSAGE;
}
}
$goodbye = new Goodbye();
// Access const variable with getter method
$goodbye->byebye();
// Access const variable with class name
echo Goodbye::LEAVING_MESSAGE;
// Access const variable directly with object
echo $goodbye::LEAVING_MESSAGE;
About class constants:
Constants cannot be changed once it is declared
Class constants are case-sensitive
A class constant is declared inside a class with the const keyword
It is recommended to name the constants in all uppercase letters
new
keyword followed by the class name(new Foo)->nonStaticMethod();
Another method is to use self
which comes after new
keyword(new self)->nonStaticMethod();
Complete example:class Foo {
public function nonStaticMethod()
{
return 'non-static';
}
public static function staticMethod()
{
// return (new Foo)->nonStaticMethod();
return (new self)->nonStaticMethod();
}
}
echo Foo::staticMethod();
The second method new self
is better, because if we want to rename the class later, we will not need to change the class name more than one placeclass Foo {
private $color;
public function bar() {
echo 'before';
$this->color = "blue";
echo 'after';
}
}
// Foo::bar();
// Deprecated
$obj = new Foo;
$obj::bar();
Deprecated: Non-static method Foo::bar() should not be called statically
php.net: In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future
class Foo
{
public static $staticVariable = 'foo';
public static function getVariableStatic() {
return self::$staticVariable;
}
public function getVariableNONStatic() {
return self::$staticVariable;
}
}
We can not access $staticVariable
using an object directly:$foo = new Foo();
print $foo->staticVariable;
This will produce the following error message:Notice: Accessing static property Foo::$staticVariable as non static...
But there are several ways to access static variable using an object:
1. Using static getter method:$foo = new Foo();
print $foo->getVariableStatic();
2. Using non-static getter method:$foo = new Foo();
print $foo->getVariableNONStatic();
php.net: A property declared as static cannot be accessed with an instantiated class object (though a static method can).
class BLock { }
class Lock {
private $isLocked;
public function __construct() {
}
public function lock() {
$this->isLocked = true;
}
public function unLock() {
$this->isLocked = false;
}
public function isLocked() {
return $this->isLocked;
}
}
class Chest {
private $lock;
public function __construct(Lock $lock) {
$this->lock = $lock;
}
public function close() {
$this->lock->lock();
echo 'Closed' . PHP_EOL;
}
public function open() {
if ($this->lock->isLocked()) {
$this->lock->unLock();
}
echo 'Opened' . PHP_EOL;
}
public function isClosed() {
return $this->lock->isLocked();
}
}
$chest = new Chest(new Lock);
// $chest = new Chest(new Block);
$chest->open();
$chest->close();
In this example Chest
class constructor waits to receive Lock
class object.
If we pass any other class object, we will get an error like the following:
Fatal error: Uncaught TypeError: Argument 1 passed to Chest::__construct() must be an instance of Lock, instance of BLock given
int
parameter.
If any other type is passed, fatal error will be generatedclass Book {
public $price;
public function price(int $price) {
$this->price = $price;
}
}
$book = new Book;
$book->price('k34');
echo $book->price;
Fatal error: Uncaught TypeError: Argument 1 passed to Book::price() must be of the type int, string given
__destruct
method will be executed at the end (before the script stops execution)class Bill {
public $dinner = 20;
public $dessert = 5;
public $drink = 3;
public $bill = 0;
public function __construct() {
$this->bill = 10;
}
public function dinner($count) {
$this->bill += $count * $this->dinner;
return $this;
}
public function dessert($count) {
$this->bill += $count * $this->dessert;
return $this;
}
public function drink($count) {
$this->bill += $count * $this->drink;
return $this;
}
public function __destruct() {
echo $this->bill;
}
}
$bill = new Bill;
$bill->dinner(3)->dessert(2)->drink(1);
class Bill {
public $dinner = 20;
public $dessert = 5;
public $drink = 3;
public $bill = 0;
public function dinner($count) {
$this->bill += $count * $this->dinner;
return $this;
}
public function dessert($count) {
$this->bill += $count * $this->dessert;
return $this;
}
public function drink($count) {
$this->bill += $count * $this->drink;
return $this;
}
}
$bill = new Bill;
We can call several methods one by one and print the $bill
:$bill->dinner(3);
$bill->dessert(2);
$bill->drink(1);
echo $bill->bill;
Or we can combine the above 4 expressions using method chaining. The result will be the same:echo $bill->dinner(3)->dessert(2)->drink(1)->bill;
class Foo {
public function __toString()
{
return "Some text about the OBJECT";
}
}
$foo = new Foo();
echo $foo;
__toString
method gets invoked when we echo or print the objectinterface Talkative {
public function talk();
}
class Cat implements Talkative {
public function talk() {
return 'Woof' . PHP_EOL;
}
}
class Dog implements Talkative {
public function talk() {
return 'Meow' . PHP_EOL;
}
}
class Tortoise implements Talkative {
public function talk() {
return 'Yak yak yak yak ...' . PHP_EOL;
}
}
$cat = new Cat;
$dog = new Dog;
$tortoise = new Tortoise;
echo $cat->talk();
echo $dog->talk();
echo $tortoise->talk();