Skip to content

Instantly share code, notes, and snippets.

@martinandersen3d
Forked from lavandosovich/poo.md
Created March 21, 2020 11:51
Show Gist options
  • Save martinandersen3d/6407d74b07c2c88a1fd07f6f8c060463 to your computer and use it in GitHub Desktop.
Save martinandersen3d/6407d74b07c2c88a1fd07f6f8c060463 to your computer and use it in GitHub Desktop.
PHP7 Object Orientetion

OOP in PHP

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).

Useful keywords:

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

New class

class ClassName{};

New Instance of a class

$instance = new ClassName();

var_dump($instance);
object(ClassName)#170 (0) {
}

Access of instance variables beyond the scope

Public

  • 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)

Protected

  • works only within:
    • class
    • child

Private

  • accessible only within the class
  • sublings have no access for it

accessability of instance methods:

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(...){...}; 

Constructor

  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 
}

Constant

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

Abstract class

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.

Interfaces

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 after extends only
  • there could be more than one interface
class Consultancy extends TimedService implements Bookable, Chargeable
{
   // ...
}

Traits aka Mixins

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;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment