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 lettersnew 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 futureclass 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 givenint 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();