I tried to learn Facade pattern, but got stuck with a problem. PHP doesnt output $totalprice from PrintPrice method. Also, here is additional information: var_dump after initializing and object gives me:
private 'SkiRent' =>
object(SkiRent)[2]
private 'SkiResortTicketSystem' =>
object(SkiResortTicketSystem)[3]
private 'HotelBookingSystem' =>
object(HotelBookingSystem)[4]
private 'totalprice' => null
but var_dump after calling HaveGoodRest gives me blank page.
I wonder if you could help me, here is the code:
<?php
class SkiRent
{
public function RentBoots($feetSize, $skierLevel)
{
return 20*$skierLevel*100/$feetSize;
}
public function RentSki($weight, $skierLevel)
{
return 40*$skierLevel*100/$weight;
}
public function RentPole($height)
{
return 5*$height/100;
}
};
class SkiResortTicketSystem
{
public function BuyOneDayTicket()
{
return 115;
}
public function BuyHalfDayTicket()
{
return 60;
}
};
class HotelBookingSystem
{
public function BookRoom($roomQuality)
{
switch ($roomQuality)
{
case 3:
return 250;
case 4:
return 500;
case 5:
return 900;
default:
throw new ArgumentException("roomQuality should be in [3;5]");
}
}
};
class SkiResortFacade
{
private $SkiRent;
private $SkiResortTicketSystem;
private $HotelBookingSystem;
private $totalprice;
function __construct()
{
$this->SkiRent = new SkiRent();
$this->SkiResortTicketSystem = new SkiResortTicketSystem();
$this->HotelBookingSystem = new HotelBookingSystem();
}
function HaveGoodRest($height, $weight, $feetSize, $skierLevel, $roomQuality)
{
$skiPrice = $SkiRent->RentSki($weight, $skierLevel);
var_dump($skiPrice);
$skiBootsPrice = $SkiRent->RentBoots($feetSize,$skierLevel);
$polePrice = $SkiRent->RentPole($height);
$oneDayTicketPr = $SkiResortTicketSystem->BuyOneDayTicket();
$hotelPrice = $HotelBookingSystem->BookRoom($roomQuality);
$this->totalprice = $skiPrice + $skiBootsPrice + $polePrice + $oneDayTicketPr + $hotelPrice;
}
public function HaveRestWithOwnSkis($roomQuality)
{
$oneDayTicketPr = $SkiResortTicketSystem->BuyOneDayTicket();
$hotelPrice = $HotelBookingSystem->BookRoom($roomQuality);
return $oneDayTicketPr + $hotelPrice;
}
public function PrintPrice()
{
echo $this->totalprice;
}
};
$rest = new SkiResortFacade();
var_dump($rest);
$height = 181.5;
$weight = 70.1;
$feetSize = 45.2;
$skierLevel = 1.2;
$roomQuality = 3;
$rest->HaveGoodRest($height, $weight, $feetSize, $skierLevel, $roomQuality);
var_dump($rest);
$rest->PrintPrice();
?>
Fatal error: Call to a member function RentSki() on a non-object on line 65
$skiPrice = $SkiRent->RentSki($weight, $skierLevel); // Line 65
$SkiRent isn't an object because you haven't instantiated it or passed it in as an argument in the HaveGoodRest() method
You have multiple calls to non-objects being acted on in your code.
You have defined $this->SkiRent attribute in SkiResortFacade class:
$this->SkiRent = new SkiRent();
but you have referenced it without $this:
$skiPrice = $SkiRent->RentSki($weight, $skierLevel);
it should be:
$skiPrice = $this->SkiRent->RentSki($weight, $skierLevel);
This is a working code, so you can compare woth your version:
<?php
class SkiRent
{
public function RentBoots($feetSize, $skierLevel)
{
return 20*$skierLevel*100/$feetSize;
}
public function RentSki($weight, $skierLevel)
{
return 40*$skierLevel*100/$weight;
}
public function RentPole($height)
{
return 5*$height/100;
}
};
class SkiResortTicketSystem
{
public function BuyOneDayTicket()
{
return 115;
}
public function BuyHalfDayTicket()
{
return 60;
}
};
class HotelBookingSystem
{
public function BookRoom($roomQuality)
{
switch ($roomQuality)
{
case 3:
return 250;
case 4:
return 500;
case 5:
return 900;
default:
throw new ArgumentException("roomQuality should be in [3;5]");
}
}
};
class SkiResortFacade
{
private $SkiRent;
private $SkiResortTicketSystem;
private $HotelBookingSystem;
private $totalprice;
function __construct()
{
$this->SkiRent = new SkiRent();
$this->SkiResortTicketSystem = new SkiResortTicketSystem();
$this->HotelBookingSystem = new HotelBookingSystem();
}
function HaveGoodRest($height, $weight, $feetSize, $skierLevel, $roomQuality)
{
$skiPrice = $this->SkiRent->RentSki($weight, $skierLevel);
var_dump($skiPrice);
$skiBootsPrice = $this->SkiRent->RentBoots($feetSize,$skierLevel);
$polePrice = $this->SkiRent->RentPole($height);
$oneDayTicketPr = $this->SkiResortTicketSystem->BuyOneDayTicket();
$hotelPrice = $this->HotelBookingSystem->BookRoom($roomQuality);
$this->totalprice = $skiPrice + $skiBootsPrice + $polePrice + $oneDayTicketPr + $hotelPrice;
}
public function HaveRestWithOwnSkis($roomQuality)
{
$oneDayTicketPr = $SkiResortTicketSystem->BuyOneDayTicket();
$hotelPrice = $HotelBookingSystem->BookRoom($roomQuality);
return $oneDayTicketPr + $hotelPrice;
}
public function PrintPrice()
{
echo $this->totalprice;
}
};
$rest = new SkiResortFacade();
$height = 181.5;
$weight = 70.1;
$feetSize = 45.2;
$skierLevel = 1.2;
$roomQuality = 3;
$rest->HaveGoodRest($height, $weight, $feetSize, $skierLevel, $roomQuality);
$rest->PrintPrice();
Related
So basically I want to have an Object Class with a bunch of setters that I can manipulate and then convert straight to JSON. In the past I was using an already existing JSON as model(json->object->json). Now I want to just have object->json.
But at the moment I get an empty array when I try to use json_encode.
Also had some trouble with my $index that I'm using because I can have multiple numerical indexes inside "items"
PHP:
<?php
namespace ProjectApi\Models;
use ArrayObject;
use stdClass;
class MagentoInvoice
{
public $capture = true;
public $notify = true;
public function __construct()
{
}
public function setCapture($capture)
{
$this->capture = $capture;
}
public function getCapture()
{
return $this->capture;
}
public function setNotify($notify)
{
$this->notify = $notify;
}
public function getNotify()
{
return $this->notify;
}
public function setItems($itemsCount)
{
$i = 0;
while($i < $itemsCount)
{
$this->items = new stdClass();
$i++;
}
}
public function getItems()
{
return $this->items;
}
public function setProductQty($index, $qty)
{
$this->items->$index->qty = $qty;
}
public function getProductQty($index)
{
return $this->items->$index->qty;
}
public function setProductOrderItemId($index, $id)
{
$this->items->$index->order_item_id = $id;
}
public function getProductOrderItemId($index)
{
return $this->items->$index->order_item_id;
}
}
JSON
{"capture":true,"items":[{"order_item_id":123,"qty":1},{"order_item_id":321,"qty":1}],"notify":true}
$body = new MagentoInvoice();
$body->setCapture(true);
$body->setNotify(true);
if($firstProductId != null && $secondProductId != null)
{
$body->setItems(2);
$body->setProductQty(0, 1);
$body->setProductOrderItemId(0, $firstProductId);
$body->setProductQty(1, 1);
$body->setProductOrderItemId(1, $secondProductId);
}
print_r(json_encode($body));
I have this class,
class Player {
protected static $volume;
protected static $instance = null;
protected function __construct()
{
self::$volume = 5;
$this->maxVolume = 20;
}
protected function __clone() {}
public static function getInstance() {
if (!isset(static::$instance)) {
static::$instance = new static;
}
return static::$instance;
}
public function volumeUp() {
if (self::$volume < $this->maxVolume) {
self::$volume = self::$volume + 1;
}
return static::$volume;
}
public function volumeDown () {
if (self::$volume > 0) {
self::$volume = self::$volume - 1;
}
return static::$volume;
}
}
I wanted to change object values dynamically by calling the method volumeUp or volumeDown.
$player = \Player\Player::getInstance();
if (isset($data['volume']) && isset($data['down'])) {
echo $player->volumeDown();
}
if (isset($data['volume']) && isset($data['up'])) {
echo $player->volumeUp();
}
When I call those methods object act like new instance and gives me always the same result.
Where I make wrong move?
I'm trying to implement a skip list in PHP using the pseudocode from http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html. I managed to get it working fine in java, but not in PHP. My put method is always returning null, and therefore, my get method too returns null.
I don't quite understand where I'm going wrong, so I'd appreciate any assistance!
<?php
interface SkipListEntry {
public function getPrev();
public function getNext();
public function getAbove();
public function getBelow();
public function getKey();
public function getValue();
public function setValue($v);
public function setPrev($v);
public function setNext($v);
public function setAbove($v);
public function setBelow($v);
public function hasPrev();
public function hasNext();
public function hasAbove();
public function hasBelow();
}
class SkipListNode implements SkipListEntry {
private $prev;
private $next;
private $above;
private $below;
private $key;
private $value;
public static $posInf = "+oo";
public static $negInf = "-oo";
function __construct($a, $b) {
$this->key = $a;
$this->value = $b;
}
public function getPrev(){
return $this->prev;
}
public function getNext(){
return $this->next;
}
public function getAbove(){
return $this->above;
}
public function getBelow(){
return $this->below;
}
public function getKey(){
return $this->key;
}
public function getValue(){
return $this->value;
}
public function setValue($n){
$this->value = $n;
}
public function setPrev($n) {
$this->prev = $n;
}
public function setNext($n) {
$this->next = $n;
}
public function setAbove($n) {
$this->above = $n;
}
public function setBelow($n) {
$this->below = $n;
}
public function hasPrev(){
return !is_null($this->prev);
}
public function hasNext(){
return !is_null($this->next);
}
public function hasAbove(){
return !is_null($this->above);
}
public function hasBelow(){
return !is_null($this->below);
}
}
class SkipList{
private $topLeft;
private $topRight;
private $height = 0;
private $totalEntries = 0;
private $head;
function __construct(){
$this->topLeft = new SkipListNode(SkipListNode::$negInf, null);
$this->topRight = new SkipListNode(SkipListNode::$posInf, null);
$this->topLeft->setNext($this->topRight);
$this->topRight->setPrev($this->topLeft);
$this->head = $this->topLeft;
}
public function size() {
return $this->totalEntries;
}
public function isEmpty(){
return $this->totalEntries == 0;
}
public function search($key){
$p = $this->head;
while (true) {
while (!$p->getNext()->getKey() == SkipListNode::$posInf
&& strcmp($p->getNext()->getKey(), $key) <= 0) {
$p = $p->getNext();
}
if ($p->hasBelow()){
$p = $p->getBelow();
}
else {
break;
}
}
return $p;
}
public function put($key, $value){
$searchElement = $this->search($key);
if ($key == $searchElement->getKey()){
$oldValue = $searchElement->getValue();
$searchElement->setValue($value);
return $oldValue;
}
$newEntry = new SkipListNode($key, $value);
$newEntry->setPrev($searchElement);
$newEntry->setNext($searchElement->getNext());
$searchElement->getNext()->setPrev($newEntry);
$searchElement->setNext($newEntry);
$currentHeight = 0;
for ($j = 1; $j <= $this->coinFlip(); $j ++){
if ($currentHeight >= $this->height){
$this->createAdditionalLayer();
}
while (is_null($searchElement->getAbove())){
$searchElement = $searchElement->getprev();
}
$searchElement = $searchElement->getAbove();
$aboveElement = new SkipListNode($key, null);
$aboveElement->setPrev($searchElement);
$aboveElement->setNext($searchElement->getNext());
$aboveElement->setBelow($newEntry);
$searchElement->getNext()->setPrev($aboveElement);
$searchElement->setNext($aboveElement);
$newEntry->setAbove($aboveElement);
$newEntry = $aboveElement;
$currentHeight ++;
}
$this->totalEntries ++;
return null;
}
public function get($key){
$p = $this->search($key);
if ($p->getKey() == $key){
return $p->getValue();
}
return null;
}
private function createAdditionalLayer(){
$newtopLeft = new SkipListNode(SkipListNode::$negInf, null);
$newtopRight = new SkipListNode(SkipListNode::$posInf, null);
$newtopLeft->setNext($newtopRight);
$newtopLeft->setBelow($this->head);
$newtopRight->setPrev($newtopLeft);
$this->head->setAbove($newtopLeft);
$this->head = $newtopLeft;
$this->height ++;
}
private function coinFlip(){
$total = 0;
$current = -1;
while ($current != 1){
$current = rand(0,1);
$total ++;
}
return $total;
}
}
// test
$a = new SkipList();
var_dump($a->put("a", "b"));
var_dump($a->put("a", "c")); // should return c (returns null)
var_dump($a->size()); // should return 1 (returns 2)
var_dump($a->get("a")); // should return c, (returns null)
Thank you!
I found some problems in a search function:
please change your code with this and try:
public function search($key){
$p = $this->head;
while (true) {
while ($p->getNext()->getKey() != SkipListNode::$posInf
&& strcmp($p->getNext()->getKey(), $key) == 0) {
$p = $p->getNext();
}
if ($p->hasBelow()){
$p = $p->getBelow();
}
else {
break;
}
}
return $p;
}
The result is:
var_dump($a->put("a", "b"));
var_dump($a->put("a", "c")); string 'b',
var_dump($a->size()); int 1,
var_dump($a->get("a")); string 'c'
I'm trying to pass an instance of my Generator class to another class to use some of the variables. The Generator class instance works fine but when i passed it to another (SelectStrategy) class it seems it is not passing the variable at all. I'm not sure what I'm doing wrong - I used var_dump on the called function to check what it gives me but it's just blank.
Function
class Generator
{
//properties for self
private $s_charge;
public $connection;
public $task_priority;
public $fog_mode = true;
public $nodes = array();
public $type;
public function generateNodesSpecs() {
$node = array();
for ($i = 0; $i < 100; $i++) {
$charge1 = mt_rand(30,100);
$node['charge'] = $charge1;
//array_push($node, $charge1);
$hops = mt_rand(0,4);
$node['hops'] = $hops;
//array_push($node, $hops);
$resource1 = mt_rand(0,100);
if ($resource1 <= 50) {
if ($resource1 <=10){
$node['connection'] = '4G';
//array_push($node, '4G');
}
else {
$node['connection'] = '3G';
//array_push($node, '3G');
}
}
else if ($resource1 > 50 && $resource1 <= 60) {
$node['connection'] = 'WiFi';
//array_push($node, 'WiFi');
}
else {
}
$resource2 = mt_rand(0,100);
if ($resource2 <=60) {
$node['additional'] = 'CPU';
//array_push($node, 'CPU');
}
else {
$node['additional'] = 'none';
}
$this->nodes[] = $node;
//array_push($nodes, $node);
unset($node);
}
//compare which get the resources
//var_dump($this->nodes[0]);
}
class SelectStrategy {
//take in generator class instance
private $generator;
private $priority;
private $size;
private $slaves = array();
private $found_slave = null; //will hold item with max val;
public function __construct($generator) {
$this->generator = $generator;
}
private function selectSlaves() {
$max = -9999999; //will hold max val
foreach($this->generator->nodes as $k=>$v)
{
if($v['charge']>$max)
{
$max = $v['charge'];
$this->found_slave = $v;
}
}
var_dump($this->found_slave);
}
}
And classes/function calls
$generator = new Generator();
$generator->generateNodesSpecs();
$select_strategy = new SelectStrategy($generator);
$select_strategy->selectSlaves();
The $this->generator->nodes is a 2D array
global $generator;
in every function of SelectSlave should do it
I'm trying to create a priority queue using this code and I can't find where the problem is. Someone tell me where I went wrong.
<?php
class PriorityQueue implements Iterator , Countable
{
public function __construct() {
$flags = self::EXTR_DATA;
$items = array();
}
function compare ( mixed $priority1 , mixed $priority2 ){}
function count (){
return count($this->items);
}
function current (){
switch ($this->flags) {
case self::EXTR_BOTH:
$ret = array();
$ret['Patient'] = current($this->items);
$ret['Priority'] = $this->key();
break;
case self::EXTR_DATA:
$ret = current($this->items);
break;
case self::EXTR_PRIORITY:
$ret = $this->key();
break;
};
return $ret;
}
function extract (){
$ret = $this->current();
$this->next();
return $ret;
}
function insert ($name,$priority){
$patient = array();
return $patient[$name] = $priority;
}
function isEmpty ()
{
return empty($this->items);
}
function key (){
return substr(key($this->items), 0, 9);
}
function next (){
//array_shift($this->items);
return($this->items);
echo "<br />";
}
function recoverFromCorruption (){}
function rewind (){}
function setExtractFlags (int $flags ){
switch ($flags) {
case self::EXTR_BOTH:
case self::EXTR_DATA:
case self::EXTR_PRIORITY:
$this->flags = $flags;
break;
};
}
function top (){
return $this->current();
}
function valid () {
if (NULL !== key($this->items)) {
return TRUE;
}
return FALSE;
}// function valid
/**
* Extract the data.
*/
const EXTR_DATA = 1;
/**
* Extract the priority.
*/
const EXTR_PRIORITY = 2;
/**
* Extract an array containing both priority and data.
*/
const EXTR_BOTH = 3;
};
$objPQ = new splPriorityqueue();
$objPQ->insert('Richard',9);
$objPQ->insert('paul',1);
$objPQ->insert('Ken',8);
$objPQ->insert('peter',2);
$objPQ->insert('Rick',7);
$objPQ->insert('Dan',5);
echo "PATIENTS = ".$objPQ->count()."<br />";
//mode of extraction
$objPQ->setExtractFlags(splPriorityqueue::EXTR_BOTH);
//Go to TOP
$objPQ->top();
for($i=0,$j=$objPQ->count(); $i<$j; $i++){
//print_r($objPQ->current());
$patients = $objPQ->current();
foreach ($patients as $patient=>$value){
echo $patient."<br />".$value;
$objPQ->next();
echo "<br />";
}
}
?>
I'm now getting some weird result
data-patient Richard
priority-9
......
etc
I want to get results to be
Richard - 9
Ken - 8
Rick - 7
Dan - 5
Peter - 2
Paul - 1
Considering the priority given
The Standard PHP Library (SPL) implements the SplPriorityQueue class :
$pq = new SplPriorityQueue();
// The insert method inserts an element in the queue by shifting it up
$pq->insert('A', 3);
$pq->insert('B', 6);
$pq->insert('C', 1);
$pq->insert('D', 2);
// Count the elements
echo "count ->" . $pq->count() . PHP_EOL;
// Sets the mode of extraction (EXTR_DATA, EXTR_PRIORITY, EXTR_BOTH)
$pq->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
// Go at the node from the top of the queue
$pq->top();
// Iterate the queue (by priority) and display each element
while ($pq->valid()) {
print_r($pq->current());
echo PHP_EOL;
$pq->next();
}
Try this modified class:
class PriorityQueue implements Iterator, Countable {
/**
* Extract the data.
*/
const EXTR_DATA = 1;
/**
* Extract the priority.
*/
const EXTR_PRIORITY = 2;
/**
* Extract an array containing both priority and data.
*/
const EXTR_BOTH = 3;
private $flags;
private $items;
public function __construct() {
$this->flags = self::EXTR_DATA;
$this->items = array();
}
function compare($priority1, $priority2) {}
function count() {
return count($this->items);
}
function extract() {
$result = $this->current();
$this->next();
return $result;
}
function current() {
switch ($this->flags) {
case self::EXTR_BOTH:
$result = $this->key() . ' - ' . current($this->items);
break;
case self::EXTR_DATA:
$result = $this->key();
break;
case self::EXTR_PRIORITY:
$result = current($this->items);
break;
default:
$result = '';
}
return $result;
}
function key() {
return key($this->items);
}
function next() {
return next($this->items);
}
function insert($name, $priority) {
$this->items[$name] = $priority;
asort($this->items);
return $this;
}
function isEmpty() {
return empty($this->items);
}
function recoverFromCorruption() {}
function rewind() {}
function setExtractFlags($flags) {
switch ($flags) {
case self::EXTR_BOTH:
case self::EXTR_DATA:
case self::EXTR_PRIORITY:
$this->flags = $flags;
break;
};
}
function valid() {
return (null === key($this->items)) ? false : true;
}
}
Usage:
$patients = new PriorityQueue();
$patients->setExtractFlags(PriorityQueue::EXTR_BOTH);
$patients->insert('Richard', 9)
->insert('paul', 1)
->insert('Ken', 8)
->insert('peter', 2)
->insert('Rick', 7)
->insert('Dan', 5);
foreach($patients as $patient) {
echo $patient->current();
}