Below is the implementation in PHP. I aim to have a different coupon code and a different discount returned, based on the type of book (vintage or new).
<?php
interface BookOffer {
function generateCoupon();
function generateDiscount();
}
class VintageBookOffer implements BookOffer {
function generateCoupon() {
return "VINTAGECOUPONCODE";
}
function generateDiscount() {
return 10.0;
}
}
class NewBookOffer implements BookOffer {
function generateCoupon() {
return "NEWBOOKCOUPONCODE";
}
function generateDiscount() {
return 5.0;
}
}
class OfferGenerator {
function generateOffer($bookType) {
if($bookType == "vintage") {
$bookObject = new VintageBookOffer();
}
else if($bookType == "newbook") {
$bookObject = new NewBookOffer();
}
return $bookObject;
}
}
$bookType1 = "vintage";
$bookType2 = "newbook";
$offerGenerator = new OfferGenerator();
$bookOffer1 = $offerGenerator->generateOffer($bookType1);
$bookOffer2 = $offerGenerator->generateOffer($bookType2);
echo "You chose book type " . $bookType1 . ". Your coupon code is " . $bookOffer1->generateDiscount() . ", and your discount is " . $bookOffer1->generateCoupon();
echo "You chose book type " . $bookType2 . ". Your coupon code is " . $bookOffer2->generateDiscount() . ", and your discount is " . $bookOffer2->generateCoupon();
?>
Does this look correct? I believe it is. But any feedback from the community would be welcome. The only reason I think it might be incorrect is because it does not use type hinting, which is frequently seen in the Strategy Pattern.
Related
This question already has answers here:
Fatal error: Declaration of .. must be compatible with .. PHP
(6 answers)
Closed last year.
VSCode doesn't accept a child and parent method with the same name but they have the same purpose.
The book I use doesn't use different name for this exercise and I don't understand why it doesn't work with me.
I found a solution by giving a different name to the child method but it doesn't help me to understand the problem.
Index.php
function monAutoLoad($class) {
include(str_replace("\\", "/", $class). ".php");
}
spl_autoload_register('monAutoLoad');
use MesProduits\Produit;
$ordinateur = new Produit("ordinateur",10,1200,false);
echo $ordinateur . "<br>";
echo $ordinateur->supprimerProduit(5) . "<br>";
use MesProduits\ProduitParLots;
$cartouchesEncre=new ProduitParLots("Cartouches d'encre",3,50,false);
$cartouchesEncre->setNbArticlesParLot(10);
$cartouchesEncre->ajouterProduit(6);
echo $cartouchesEncre . "<br>";
Produit.php (parent class file)
namespace MesProduits; //donner le même nom que le dossier parent
class Produit{
protected $nom = "mon produit";
protected $quantite = 10;
protected $prix = 120;
protected $rupture = false;
function __construct($nom,$quantite,$prix,$rupture)
{
$this->nom=$nom;
$this->quantite=$quantite;
$this->prix=$prix;
$this->$rupture=$rupture;
}
function __toString(){
return "nom: " . $this->nom . "<br>".
"quantité: " . $this->quantite . "<br>".
"prix: " . $this->prix . "<br>".
(($this->rupture)? "no stock <br>" : "in stock <br>");
}
function ajouterProduit($quantite){ //parent method and I want the same name in the child file
$this->quantite+=$quantite;
if($this->quantite >=0){
$this->rupture = false;
}
return "a product has been add <br>" .
"there is: " . $this->quantite . " in stock <br>";
}
function supprimerProduit($quantite){
$this->quantite-=$quantite;
if($this->quantite <=0){
$this->rupture = true;
}
return "a product has been removed <br>" .
"there is " . $this->quantite . " in stock <br>";
}
}
ProduitParLots.php (child file class)
namespace MesProduits;
class ProduitParLots extends Produit{
private $nbArticlesParLot;
function getNbArticlesParLot(){
return $this->nbArticlesParLot;
}
function setNbArticlesParLot($valeur){
if(!is_integer($valeur)){
echo "the property must be an integer <br>";
}else{
$this->nbArticlesParLot=$valeur;
}
}
function ajouterProduit2(){ //need to choose a different name for the child method
$this->quantite+=$this->nbArticlesParLot;
if($this->quantite>0) $this->rupture=false;
}
}
This is because the "child" method has not the same signature as the parent method. You missed the $quantite parameter.
class ProduitParLots extends Produit
{
function ajouterProduit($quantite) { /* ... */ }
}
I am working on displaying information from my database. When I did print_r in the model/itemTile.php below to check on my array, $this->display, I noticed it had stored 2 copies of the data from my database. I checked my database, and there was definitely only one copy of the data.
I created a counter variable, $this->counter, to see what the surrounding while loop was doing. The original data had 6 non-duplicating rows. As you may see in the jpg attached below, the program increments and echo the counter to 6, then it does the "print_r($this->display)" line that is outside of the while loop, then for some strange reason goes back to the while loop, increment the counter, and print the $this->counter and $this->display again!
I can remove the duplicate, but I would much prefer to figure out why exactly there are two copies of the value to begin with.
Since this was originally a PHP class project that focus on MVC, everything is placed into controller, model, and view. I have included the relevant model and view code below:
Jpg:
PHP Site
model/itemTile.php
<?php
require_once('siteInfo.php');
class itemTile implements siteInfo {
private $term;
private $session;
private $result;
private $display = array();
private $counter = 0;
public function __construct($session) {
$this->session = $session;
}
public function getContent() {
$this->result = $this->session->db->prepare("SELECT productName, sciName, price FROM products");
$this->result->execute();
$this->result->bind_result($pN, $sN, $pz);
while ($this->result->fetch()) {
if (array_key_exists($pN, $this->display)) {
$this->display[$pN]["price"][] = $pz;
} else {
$this->display += [
$pN => [ //Product Name was used to id array because not all item have sciName,
"sciName" => [$sN], //and not all item have only 1 sku (1 item with different size = multiple pid).
"price" => [$pz]
]
];
}
$this->counter++;
echo $this->counter . "<br />";
}
$this->result->close();
print_r($this->display);
echo "<br />";
}
public function setContent() {
$this->getContent();
return $this->display;
}
}
?>
view/itemTile.php
<?php
class itemTileView {
private $model;
public function __construct(itemTile $model) {
$this->model = $model;
}
public function output(){
foreach ($this->model->setContent() as $item => $detail) {
$itemLink = preg_replace('/\s+/','_', $item);
echo "<div class= 'tileSpace'>";
echo "<a href='itemPages/" . $itemLink. "/home.php'>";
echo "<img alt='" . $item . "' src='itemPages/" . $itemLink . "/thumbnail.jpg' width='100' height='100'>";
echo "</a>";
echo "<p>" . $item . ": " . $detail["sciName"][0] . "</p>";
if (count($detail["price"]) > 1) {
echo "<p>" . min($detail["price"]). " - " . max($detail["price"]). "</p>";
} else {
echo "<p>" . $detail["price"][0] . "</p>";
}
echo "</div>";
}
}
}
?>
Can anyone spot where is the problem occurring?
use php function array_unique();
array_unique($arrayname);
using this you will get unique values from array.it avoids duplicate values
Well, ive been trying to get my crm to print multiple contacts for each company but i cant get it to work
Company is a class,companycontactis a class
//class called company
function __construct($idklanten,$naam,$adres,$postcode,$stad,$contacten){
$this->idklanten=$idklanten;
$this->naam=$naam;
$this->adres=$adres;
$this->postcode=$postcode;
$this->stad=$stad;
$this->contacten=$contacten;
}
//class called contact
function __construct($idcontactklanten,$voornaam,$tussenvoegsel,$achternaam,$tel,$email,$klantID){
$this->idcontactklanten=$idcontactklanten;
$this->voornaam=$voornaam;
$this->tussenvoegsel=$tussenvoegsel;
$this->achternaam=$achternaam;
$this->tel=$tel;
$this->email=$email;
$this->klantID=$klantID;
}
//getname for a contact
function getNaam() {
if(strlen($this->gettussenvoegsel()) == 0) {
return $this->getvoornaam()." ".$this->getachternaam()."";
}
else {
return $this->getvoornaam() . " " . $this->gettussenvoegsel() . " " . $this->getachternaam();
}
}
//function for getting the names from my object company,array with objects of contacts
function getcontacten(){
$ct=$this->contacten[$teller];
$txt="";
for($teller=0;$teller<10;$teller++){
$txt+=$ct->getNaam()."<br>";
}
return $txt;
}
then on my index page when i call getcontacten() it does not work comparing to my other get function which do work. it just outputs a 0
Any help is appreciated
Your biggest error would be the following:
$txt+=$ct->getNaam()."<br>";
Should be
$txt.=$ct->getNaam()."<br>";
Because to append to a string you use ".=", not "+=".
Also I don't know if the other part of you code works, I would write something like the following:
$txt = "";
foreach ($this->contacten as $ct){
$txt .= $ct->getNaam() . "<br />";
}
return $txt;
or
$txt = "";
for ($i = 0; $i < count($this->contacten); $i++){
$txt .= $this->contacten[$i]->getNaam() . "<br />";
}
return $txt;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to create a class function but somehow it won’t work and I can’t figure out what’s the problem. Is it the way I declare the variable or what so ever?
<?php
class Car{
var $model;
var $make;
var $speed;
function Car ( $model, $make, $speed)
{
$this->model = $model;
$this->make = $make;
$this->speed = $speed;
}
function accelerate ($speed)
{
$add = 5;
$speed = $speed + $add;
return $speed;
}
function get_status()
{
echo "Car status : \n";
echo "Model :" $this-> model "\n";
echo "Make :" $this-> make "\n\n";
}
function get_speed()
{
return $this->speed;
}
}
?>
<?php
$car1 = new Car();
$car1 -> get_status("Vios", "Toyota");
for( $i = 0; $i < 5 ; $i++)
{
echo "Accelerating... <br> \n";
echo "Current speed : accelerate(5) km/h <br>";
}
?>
Lots of issues with your code. But at least this cleaned up version should work without the script dying completely. Here is a breakdown of what I did:
Set the variables that were set as var to public since that is the preferred method of setting variables.
In function Car, I set default values for $model, $make & $speed so if they are not passed—like in your example—there is at least a default value to act on.
Your echo lines in get_status did not have the . for concatenation so they were not properly concatenating the strings.
Then you setting $this-> make and $this-> model with empty spaces is syntactically incorrect. So set those to $this->make and $this->model.
Then when you are calling the class, you set this "Current speed : accelerate(5) km/h <br>"; which is syntactically incorrect as well. So set that to echo "Current speed : " . $car1->accelerate(5) . " km/h <br>"; so it can actually echo values.
But that said, unclear on what the output is for this code. The logic is a bit of a mess. But at least it’s not completely dying like it did before!
And here is the cleaned up code:
class Car {
public $model;
public $make;
public $speed;
function Car ($model = 0, $make = 0, $speed = 0) {
$this->model = $model;
$this->make = $make;
$this->speed = $speed;
}
function accelerate ($speed) {
$add = 5;
$speed = $speed + $add;
return $speed;
}
function get_status () {
echo "Car status : \n";
echo "Model :" . $this->model . "\n";
echo "Make :" . $this->make . "\n\n";
}
function get_speed () {
return $this->speed;
}
}
$car1 = new Car();
$car1->get_status("Vios", "Toyota");
for( $i = 0; $i < 5 ; $i++) {
echo "Accelerating... <br> \n";
echo "Current speed : " . $car1->accelerate(5) . " km/h <br>";
}
And—like I said before—since the way you are calling the class makes little sense to the structure you have, I slightly reworked the code above so it loops through an array of car values like this:
$car_array = array("Vios", "Toyota");
foreach ($car_array as $car_value) {
$car1 = new Car($car_value);
$car1->get_status();
for( $i = 0; $i < 5 ; $i++) {
echo "Accelerating... <br> \n";
echo "Current speed : " . $car1->accelerate(5) . " km/h <br>";
}
}
Add a constructor like this:
public function __construct($model = 0, $make = 0, $speed = 0) {
$this->model = $model;
$this->make = $make;
$this->speed = $speed;
}
http://us3.php.net/manual/en/language.oop5.decon.php
When concatenating strings, you must use the dot operator:
echo "abcd" . "efgh";
I am quite new to OOPS and Zend. I am converting a part of web app code to Zend framework, I can't post all the code in here coz its quite lengthy. I created a model as in the code below(I can post only two functions) and I want to access the variables inside the functions from the controller and then print them out in HTML tables(I guess I will have to use "views" for that", below is my model:
public function getVenueTypes()
{
$poiTypes = array();
if($this->_cache)
{
$key = $this->getCacheKey()."poiTypes_stats:{$this->language}";
}
if(!$poiTypes)
{
$sql = "SELECT poi_type_id, poi_type_name_".$this->language."
AS
poi_type_name
FROM
poi_types
ORDER BY
poi_type_name_".$this->language." ASC";
$result = mysql_query($sql);
if(!$result)
{
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= "Whole query: \n\n$sql\n";
die($message);
}
while($row = mysql_fetch_array($result))
{
$poiTypes[] = array('id' => $row['poi_type_id'] ,'name' => $row['poi_type_name']);
}
print_r($poiTypes);
if ($this->_cache)
{
$this->_cache->save($key, $poiTypes);
}
}
foreach($poiTypes as $poiType)
{
$count_type = null;
if($this->_cache)
{
$key = $this->getCacheKey()."poiTypeCount:{$poiType['id']}:{$this->metro_id}";
$count_type = $this->_cache->load($key);
}
if(!$count_type)
{
$sql = "SELECT COUNT(*) FROM
poi
WHERE
find_in_set('{$poiType['id']}', poi_type_id_array)
AND poi_status = 1 AND poi_address_prefecture_id = '$this->metro_id'";
$result = mysql_query($sql) or die(mysql_error());
}
if(!$result)
{
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= "Whole query: \n\n$sql\n";
die($message);
}
while($count = mysql_fetch_array($result))
{
$count_type[$poiType['id']][$this->metro_id] = $count['COUNT(*)'];
}
if($this->_cache)
{
$this->_cache->save($key, $count_type);
}
}
}
Any help is Highly appreciated, I hope I am being clear enough and thanks in advance.
I'm noy sure if this will help you, but you have several options to access those values.
Option 1: return an array with the variables you need
return array($myVar1, $myVar2, ..., $myVarN);
Option 2 (less modular): create the html string inside that function and then echo or return the string.
Im assuming that you have a basic knowledge of Zend
The basic idea of Zend framework is the link between controller ,models and view
Your model file,BlaBla.php
Class Namespace_models_BlaBla extends Zend_Db_Table_Abstract{
public function foo(){
return 'hello world';
}
}
Your controller say BarController and an action say test
class BarController extends extends Zend_Controller_Action{
public function testAction(){
$class = new Namespace_models_BlaBla();
$this->view->string = $class->foo();
}
}
Your html side // test.phtml
<?php echo $this->string; ?> /**this will output hello world **/