phanalist

E6 Properties without modifier.

Problem

Forgetting to add a modifier makes it seem like it has no harm.

Example
<?php

// Dinner.php
class Dinner {

  bool $isTableClean = false;

  private function eat(){}
  
  private function drink(){}
  
  private function dessert(){}

  private function cleanTable(){}

  private function sittAtTable(){}
  
  public function cleanTable(){}

  public function spillWater(){
    $this->isTableClean = false;
  }

  public function start(){
    $this->sittAtTable();
    $this->eat();
    $this->drink();
    $this->dessert();
    $this->eat();
  }

  public function end(){
    if($this->isTableClean === false){
       $this->cleanTable();
    }
  }
}

The end() method can automatically detect if there is something to clean after dinner. If one of the persons at the table spills water, the method spillWater() will be used as intended. The object will remember that the table is still dirty and clean it if needed.

<?php
 
// index.php

$person = new Person();
$dinner = new Dinner();

$dinner->start();

$dinner->spillWater();

$dinner->end();

This will work without any issues, but how will you prevent someone from introducing a bug? They can avoid cleaning the table if they do not want to.

 <?php
 
// index.php

$person = new Person();
$dinner = new Dinner();

$dinner->start();

$dinner->spillWater();

$dinner->isTableClean  = true;

/// The table will be dirty forever
$dinner->end();

Solution

The solution is to close the property to the outside world.

<?php

// Dinner.php
class Dinner {

  private bool $isTableClean = false;

  private function eat(){}
  
  private function drink(){}
  
  private function dessert(){}

  private function cleanTable(){}

  private function sittAtTable(){}
  
  public function cleanTable(){}

  public function spillWater(){

    $this->isTableClean = false;
  }

  public function start(){
  
    $this->sittAtTable();
    $this->eat();
    $this->drink();
    $this->dessert();
    $this->eat();
  }

  public function end(){
    if($this->isTableClean === false){
       $this->cleanTable();
    }
  }
}