Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).
self - self from the root
parent - parent of the class
static - true self
for exact class, static
is more agile than self
, super useful for inheritance issues
class ClassName{};
$instance = new ClassName();
var_dump($instance);
object(ClassName)#170 (0) {
}
- you can see/call/invoke it everywhre
class ShopProduct { public $title = "default product"; public $producerMainName = "main name"; public $producerFirstName = "first name"; public $price = 0; }
also:
- instantiate from the ShopProduct class will now be prepopulated with default data all variables in this example are availible both as Setters and Getters (wombo-combo)
- works only within:
- class
- child
- accessible only within the class
- sublings have no access for it
it is a sign of good manners to set public for in-ce m-ds. (without that been made, they(functions), OFCOURESE would be set to public by default)
public function method_name(...){...};
public function __construct(params){}
works aka hook on :
new ClassName(params)
Constructor of the ancestor:
public function _constructor()
{
parent::_constructor()
//some stuff goes next
//declaration for example
}
class SomeClass
{
const TRUE_CONST = primitive_type_value;
}
print SomeClass::TRUE_CONST; // call the const
- const is unchangeble
- attempts to change the const will lead to error parse
Its kind of Templamte class Pattern
They serve mostly for declaration then for implementation.
You can make instance of AC
AC can have abstract methods:
abstract class ShopProductWriter
{
protected $products = [];
public function addProduct(ShopProduct $shopProduct)
{
$this->products[]=$shopProduct;
}
abstract public function write();
}
They (am) serves as Template method for child classes. Once they are defined, all child classes must implement functionality for them otherwise - error occures
All child class can redefine it(am) again as abstract. This will prevent from errors.
interface Chargeable
{
public function getPrice(): float;
}
- Name consist of Someable, able is a key part Examples: Chargeable, Bookable
- True Templates or supposed to be so
- Useful for type validation - could help to achive some similarities of some classes that have not so much in common
class ShopProduct implements Chargeable
{
// ...
protected $price;
// ...
public function getPrice(): float
{
return $this->price;
}
// ...
}
implemets
follows afterextends
only- there could be more than one interface
class Consultancy extends TimedService implements Bookable, Chargeable
{
// ...
}
They come to the rescue at the moment than you realize that PHP can't implement multi inheritence
UNlike interfaces they don't affect on typing
trait PriceUtilities
{
private $taxrate = 17;
public function calculateTax(float $price): float
{
return (($this->taxrate / 100) * $price);
}
// other utilities
}
class ShopProduct
{
use PriceUtilities;
}
abstract class Service
{
// service oriented stuff
}
class UtilityService extends Service
{
use PriceUtilities;
}
You can use multiply traits per class
trait IdentityTrait
{
public function generateId(): string
{
return uniqid();
}
}
class ShopProduct
{
use PriceUtilities, IdentityTrait;
}
$p = new ShopProduct();
print $p->calculateTax(100) . "\n";
print $p->generateId() . "\n";
At some point you can encounter the problem of collision of traits methods which occures when you include multiply traits to the class
trait TaxTools
{
function calculateTax(float $price): float
{
return 222;
}
}
trait PriceUtilities
{
private $taxrate = 17;
public function calculateTax(float $price): float
{
return (($this->taxrate / 100) * $price);
}
// other utilities
}
class UtilityService extends Service
{
use PriceUtilities, TaxTools;
}
// listing 04.28
$u = new UtilityService();
print $u->calculateTax(100) . "\n";
//PHP Fatal error: Trait method calculateTax has not been applied, because there
//are collisions with other trait methods on...
It can be useful to embrace insdeaof
in this kind of situations:
class UtilityService extends Service
{
use PriceUtilities, TaxTools {
TaxTools::calculateTax insteadof PriceUtilities;
PriceUtilities::calculateTax as basicTax;
// aliasing overriden method so it's now availiable on object
// aliasing requires 'insteadof' first !
}
}
$u = new UtilityService();
print $u->calculateTax(100) . "\n";
You can also use abstract methods in traits But remember: traits with am burden classes which use whem with the implementations It is also possible to change Access Rights of traits methods for classes
trait PriceUtilities
{
public function calculateTax(float $price): float
{
// better design.. we know getTaxRate() is implemented
return (($this->getTaxRate() / 100) * $price);
}
abstract function getTaxRate(): float;
// other utilities
}
class UtilityService extends Service
{
use PriceUtilities {
PriceUtilities::calculateTax as private; // access rights changing
}
public function getTaxRate(): float
{
return 17;
}
}