Plain old PHP object POPO

Mr. Popo

POPO is as an object of a simple class. When you make it as a stdClass object it’s not a strict contract of what you would have in that object. stdClass object can be easily abused by other developers.

POPO is a PHP variant of POJO that was coined by Martin Fowler

Points to consider while making POPO

  • All member variables are private. Accessor methods should be used vs direct member access.
  • Public accessor methods (getters/setters)
  • Public toArray(), toJson() like methods for easy access, easy storage/persistence
  • Constructor accepting an array of values that need to be set.
  • It should not have any business logic
  • Avoid any kind of validation in this object
  • Don’t worry about implementing an interface for POPO. [Optional]
  • If you need method chaining, return $this from your setters. [Optional]
  • Probably a __toString() method [Optional]

When to use it

Consider the use of POPO in these cases:

  • To transfer data across the boundary. Like transferring data from Model to Controllers or from controllers to View or from one application to other application. In this case, it would behave like Data Transfer Object (DTO). More details – DTO vs Value Object vs POCO
  • If we have JSON data, we could bind that JSON data and map it to a POPO. So we exactly know what’s there in JSON field. This will also ensure that our JSON data has a consistent structure always. It will also prevent abuse of JSON structure.
  • If there are too many parameters for a function, we could use “Introduce Parameter Object” refactoring to replace all those parameters with a POPO containing those members.
  • For mapping a database composite type

Example

class CPerson {

private $m_strNameFirst;
private $m_strNameLast;
private $m_fltHeight;
private $m_fltWeight;

public function __construct( $arrmixValues ) {
    $this->setNameFirst( $arrmixValues['name_first'] ?? NULL );
    $this->setNameLast( $arrmixValues['name_last'] ?? NULL );
    $this->setHeight( $arrmixValues['height'] ?? NULL );
    $this->setWeight( $arrmixValues['weight'] ?? NULL );
}

public function toArray() : array {
    return [
        'name_first' => $this->getNameFirst(),
        'name_last'  => $this->getNameLast(),
        'height'     => $this->getHeight(),
        'weight'     => $this->getWeight(),
    ];
}

public function getNameFirst() {
    return $this->m_strNameFirst;
}

public function setNameFirst( $strNameFirst ) {
    $this->m_strNameFirst = $strNameFirst;
}

public function getNameLast() {
    return $this->m_strNameLast;
}

public function setNameLast( $strNameLast ) {
    $this->m_strNameLast = $strNameLast;
}

public function getHeight() {
    return $this->m_fltHeight;
}

public function setHeight( $fltHeight ) {
    $this->m_fltHeight = $fltHeight;
}

public function getWeight() {
    return $this->m_fltWeight;
}

public function setWeight( $fltWeight ) {
    $this->m_fltWeight = $fltWeight;
}

}