Warning
This page is located in archive.

Řešení PHP OOP

Úkol 1

bootstrap.php

<?php
 
define ("CLASSDIR", "classes/");
 
function __autoload($classname) {
	$filename = strtolower($classname.".php");
	include(CLASSDIR.$filename);
}
 
?>

Pak každý hlavní skript musí vložit bootstrap.php

index.php

<?php
require ("bootstrap.php");
 
// pouziji nejakou tridu bez jeji predchozi explicitni definice
$kniha = new Kniha("autor", "nazev", "nejake isbn");
 
// ...
?>

Úkol 2

Nejprve zavedeme společné rozhraní Zbozi

classes/zbozi.php

<?php
 
interface Zbozi {
 
    public function getId(); 
 
    public function setId($id);
 
    public function getCena();
 
    public function setCena($cena);
 
    public function getDPH();
 
    public function setDPH($dph);
}
?>

Pak jednotlivé třídy, které se mají stát zbožím, musí toto rozhraní také implementovat.

classes/vzducholod.php

<?php
class Vzducholod implements Zbozi {
 	protected $id;
    protected $cena;
    protected $dph;
 
    protected $objem;
    protected $nosnost;
    protected $dostup;
 
 
    public function __construct($objem, $nosnost, $dostup) {
    	$this->objem = $objem;
    	$this->nosnost= $nosnost;
    	$this->dostup = $dostup;
    }
 
    public function getId() {
        return $this->id;
    }
 
    public function setId($id) {
        $this->id = $id;
    }
 
    public function getCena() {
        return $this->cena;
    }
 
    public function setCena($cena) {
        $this->cena = $cena;
    }
 
    public function getDPH(){
		return $this->dph;    	
    }
 
    public function setDPH($dph) {
    	$this->dph = $dph;
    }
 
    public function getObjem() {
    	return $this->objem;
    }
 
    public function getNosnost() {
		return $this->nosnost;
    }
 
    public function getDostup() {
    	return $this->dostup;
    }
 
}
 
?>

classes/kniha.php

<?php
class Kniha implements Zbozi {
 	protected $id;
    protected $cena;
    protected $dph;
 
    protected $autor;
    protected $nazev;
    protected $isbn;
 
 
    public function __construct($autor, $nazev, $isbn) {
    	$this->autor = $autor;
    	$this->nazev = $nazev;
    	$this->isbn = $isbn;
    }
 
    public function getId() {
        return $this->id;
    }
 
    public function setId($id) {
        $this->id = $id;
    }
 
    public function getCena() {
        return $this->cena;
    }
 
    public function setCena($cena) {
        $this->cena = $cena;
    }
 
    public function getDPH(){
		return $this->dph;    	
    }
 
    public function setDPH($dph) {
    	$this->dph = $dph;
    }
 
    public function getAutor() {
    	return $this->autor;
    }
 
    public function getNazev() {
		return $this->nazev;
    }
 
    public function getIsbn() {
    	return $this->isbn;
    }
 
}
?>

Úkol 3

Pozor, pokud chceme využívat session kdekoli v projektu, je nutné dát session_start(); do bootstrap.php

Řešení:

classes/sessionkosik.php

<?php
 
class Sessionkosik extends Kosik {
    const SESSION_NAME = "kosik_session";
 
    public function __construct() {
 
    }
 
    public function save() {
        $_SESSION[Sessionkosik::SESSION_NAME] = $this->obsah;
    }
 
    public function load() {
       if (isset($_SESSION[Sessionkosik::SESSION_NAME])) {
            foreach ($_SESSION[Sessionkosik::SESSION_NAME] as $klic=>$hodnota) {
                $this->obsah[$klic] = $hodnota;
            } 
       }
 
    }
}
 
?>

Úkol 4

Protože není dovoleno přestínit metody se snižujícími se právy, tj. není možné udělat Singlekosik extends SessionKosik a u SingleKosik mi privátní konstruktor, udělmáme to jinak:

classes/singlekosik.php

<?php
 
class Singlekosik  {
	protected static $instance = null;
 
	private function __construct() {
		// nelze volat konstruktor
		// ostatne tato trida nic sama nedela
	}
 
 
	public static function getInstance() {
		if (self::$instance == null) {
			self::$instance = new Sessionkosik();
		}
 
		return self::$instance;
	}
}
 
?>

Použití pak vypadá takto:

<?php
 require ('bootstrap.php');
 $kosik = Singlekosik::getInstance();
 $kosik->load();
 
// nejake dalsi operace s kosikem
 $kosik->save();
?>

Úkol 5

Nejprve rozhraní

classes/kosikeventproducer.php

<?php
interface Kosikeventproducer {
 
	public function addEventListener(Kosikeventlistener $l);
 
	public function removeEventListener(Kosikeventlistener $l);
 
}
?>

classes/kosikeventproducer.php

<?php
interface Kosikeventlistener {
 
	public function processEvent(Kosikevent $e);
 
}
?>

Ted trida udalosti ( zde je vhodna i hierarchie trid)

classes/kosikevent.php

<?php
 
class Kosikevent {
	protected $zbozi;
	protected $pocet;
 
 
	public function __construct(Zbozi $z, $pocet) {
		$this->zbozi = $z;
		$this->pocet = $pocet;
	}
 
	public function getZbozi() {
		return $this->zbozi;
	}
 
	public function getPocet() {
		return $this->pocet;
	}
}
 
?>

</php>

Třídy implementující eventlistenery, tj. Logocac a Ucetni

classes/logovac.php

<?php
class Logovac implements Kosikeventlistener {
 
	public function processEvent(KosikEvent $e) {
 
		echo "<h1>Logovac zaregistroval udalost</h1>";
		if ($e->getPocet()>=0) {
			echo "pridano ";	
			$pocet = $e->getPocet();		
		} else {
			echo "odebrano ";
			$pocet = -$e->getPocet();
		}
		echo $pocet." ks zbozi s id: ".$e->getZbozi()->getId();
	}
}
 
?>

classes/ucetni.php

<?php
class Ucetni implements Kosikeventlistener {
 
	public function processEvent(KosikEvent $e) {
 
		echo "<h1>Ucetni zaregistroval udalost</h1>";
		if ($e->getPocet()>=0) {
			echo "pridano ";
			$pocet = $e->getPocet();
		} else {
			echo "odebrano ";
			$pocet = -$e->getPocet();
		}
		echo $pocet." ks zbozi s id: ".$e->getZbozi()->getId();
	}
}
 
?>

Musíme upravit Sessionkosik tak, aby vyhazoval události. Pozor, pro jednoduchost je prezentováno vyhazování události jen na dvou metodách, mělo by se to ale rozšířit na všechny.

classes/sledovatelnysessionkosik.php

<?php
class Sledovatelnysessionkosik extends Sessionkosik implements Kosikeventproducer  {
 
	protected $listeners; 
 
	public function __construct() {
		parent::__construct();
		$this->listeners = array();
	}
 
	public function addEventListener(Kosikeventlistener $l) {
		if (!in_array($l, $this->listeners)) {
			$this->listeners[] = $l;
		}
	}
 
	public function removeEventListener(Kosikeventlistener $l) {
		foreach ($this->listeners as $klic=>$listener) {
			if ($listener === $l) {
				unset($this->listeners[$klic]);
			}
		}
	}
 
 
	protected function rozesliUdalost (Kosikevent $udalost) {
		foreach ($this->listeners as $listener) {
			$listener->processEvent($udalost);
		}
	}
 
 
	// predefinujeme existujici metody
	public function pridat(Zbozi $z, $pocet = 1) {
		parent::pridat($z,$pocet);
		$this->rozesliUdalost(new Kosikevent($z,$pocet));
	}
 
	public function odebrat(Zbozi $z, $pocet = 1) {
		parent::odebrat($z, $pocet);
		$this->rozesliUdalost(new Kosikevent($z, -$pocet));
	}
}
 
?>

No a to je vše :-) Teď to jenom použijeme v praxi:

 require ('bootstrap.php');
 
 $vzducholod = new Vzducholod(100, 1000, 100000);
 $vzducholod->setCena(123);
 $vzducholod->setDPH(0.2);
 $vzducholod->setId("vz01");
 
 $kosik = new Sledovatelnysessionkosik();
 
 $logovac = new Logovac();
 $ucetni = new Ucetni();
 
 $kosik->addEventListener($logovac);
 $kosik->addEventListener($ucetni);
 
 $kosik->load();
 
 $kosik->pridat($vzducholod, 2);
 $kosik->odebrat($vzducholod,1);
 
 $kosik->save();

Řešení v jednom souboru [ZIP]

courses/b6b39zwa/tutorials/solutions/07/start_2010.txt · Last modified: 2018/10/01 15:02 (external edit)