OOP and switch statements - php

I have this OOP code in php
class SSE {
static function setSection($opt_name,array $settings){
var_dump($settings["fields"]);
foreach ($settings["fields"] as $field){
self::processField($opt_name,$field);
}
}
static function processField($opt_name,array $field){
switch ($field["type"]){
case "number":
$number = new Number($field["title"],$field["desc"],$field["id"]);
echo "<br>$number";
break;
case "checkbox":
$checkbox = new Checkbox($field["title"],$field["desc"],$field["id"],$field["color"]);
echo "<br>$checkbox";
break;
}
}
}
class Input {
protected $title;
protected $desc;
protected $id;
}
class Number extends Input {
//protected $fields = array();
function __toString(){
return $this->title;
}
public function __construct($title,$desc,$id){
$this->title = $title;
$this->desc = $desc;
$this->id = $id;
}
}
class Checkbox extends Input {
//protected $fields = array();
protected $color;
function __toString(){
return $this->title;
}
public function __construct($title,$desc,$id,$color){
$this->title = $title;
$this->desc = $desc;
$this->id = $id;
$this->color = $color;
}
}
$test1 = array(
"title" => "Ssadassa",
"id" => "basic",
"desc" =>"this is a test",
"fields" => array(
array(
"title" => "Checkbox input",
"id" => "ba32132sic",
"desc" =>"this is a test",
"type" => "checkbox",
"color" => "This is only for checkbox no another input should have this"
),
array(
"title" => "Number input",
"id" => "basic",
"desc" =>"this is a test",
"type" => "number"
)
)
);
SSE::setSection("da",$test1);
What to do about the switch statement?Later I may add textarea input and I have to go and edit the switch statemt.I have looked here https://sourcemaking.com/design_patterns but I don't know with one fits this case maybe factory no idea.This is my first OOP try.
By the way the array $test1 must not be changed I mean the way some one uses those clases must be the same.Any help really appreciated.Thank you.
Edit:The question is:Is anything wrong if I use the switch statement?Is a better way to do this?

You could create class map, and special methods to create inputs from options.
class SSE { // please rename this
static private $mapClass = ['number' => 'Number', 'checkbox' => 'Checkbox'];
static function setSection($opt_name, array $settings) {
// var_dump($settings["fields"]);
foreach ($settings["fields"] as $field) {
self::processField($opt_name, $field);
}
}
static function processField($opt_name, array $field) {
// recognize class from class map
$class = self::$mapClass[$field["type"]];
$input = $class::createFromOptions($field);
echo "<br>$input";
}
}
class Input {
protected $title;
protected $desc;
protected $id;
}
class Number extends Input {
//protected $fields = array();
function __toString() {
return $this->title;
}
public function __construct($title, $desc, $id) {
$this->title = $title;
$this->desc = $desc;
$this->id = $id;
}
// create object from array
static public function createFromOptions(array $options) {
return new self($options["title"], $options["desc"], $options["id"]);
}
}
class Checkbox extends Input {
//protected $fields = array();
protected $color;
function __toString() {
return $this->title;
}
public function __construct($title, $desc, $id, $color) {
$this->title = $title;
$this->desc = $desc;
$this->id = $id;
$this->color = $color;
}
// create object from array
static public function createFromOptions(array $options) {
return new self($options["title"], $options["desc"], $options["id"], $options["color"]);
}
}
$test1 = array(
"title" => "Ssadassa",
"id" => "basic",
"desc" => "this is a test",
"fields" => array(
array(
"title" => "Checkbox input",
"id" => "ba32132sic",
"desc" => "this is a test",
"type" => "checkbox",
"color" => "This is only for checkbox no another input should have this"
),
array(
"title" => "Number input",
"id" => "basic",
"desc" => "this is a test",
"type" => "number"
)
)
);
SSE::setSection("da", $test1);
Also, you could add options validator to make sure that all mandatory options has passed and there is no extra options.
Why not ucfirst? Because you are able to use camel case class name, for example RichText (textarea with wysiwyg). Or write more smart class recognizer.

Related

How to search in an array by value part

I want to get data from api request. I make a query on the value of oc52. Get $date array. The issuing server adds the MH prefix. Which generates itself relative to the name. I am trying to extract part of the array using the class.
This is the array I get when querying:
$data = [
[
'product' => 'CH C104.12',
'brand' => 'CH C104.12',
'price' => 12.34,
],
[
'product' => 'MH OC52',
'brand' => 'MH OC52',
'price' => 56.78,
],
[
'product' => 'WX WL7074-12',
'brand' => 'WX WL7074-12',
'price' => 90.12,
],
];
Here's the class I'm doing a search for
class ProductFilterIterator extends \FilterIterator
{
protected $filter;
public function __construct(\Iterator $iterator, $filter)
{
$this->filter = $filter;
parent::__construct($iterator);
}
public function accept() : bool
{
$current = $this->getInnerIterator()->current();
return $current['product'] == $this->filter;
}
}
$iterator = (new \ArrayObject($data))->getIterator();
$filter1 = new ProductFilterIterator($iterator, 'OC52');
foreach ($filter1 as $data) {
echo "<pre>";
var_dump($data);
echo "</pre>";
}
Does nothing reflect? If I write in line MH OC52:
$filter1 = new ProductFilterIterator($iterator, 'MH OC52');
Then everything works.
How do I implement it if I don't know the front - MH ???
If you just want to check the end of the string, this stores the length to check after storing the filter. Then in the main accept() method, it just looks at the last part of the string (using substr()) in the array to compare...
class ProductFilterIterator extends \FilterIterator
{
protected $filter;
protected $length;
public function __construct(\Iterator $iterator, $filter)
{
$this->filter = $filter;
$this->length = -strlen($filter);
parent::__construct($iterator);
}
public function accept() : bool
{
$current = $this->getInnerIterator()->current();
return substr($current['product'], $this->length) == $this->filter;
}
}

How to implement a method which accepts a string parameter and returns a JSON format in PHP

Below is an example of a data structure that defines a fruit’s color:
array(
"red" => array("apple, strawberry"),
"yellow" => array("lemon", "ripe mango")
)
Implement the function getFruits method, which accepts color as a
string parameter and returns all fruits for that color in JSON format
(see example below).
For example, the call $fruitcolors->getFruits("red"); should return:
{ "color":"red", "fruits": ["apple", "strawberry"]}
If a call doesn’t have fruits for that $fruitcolors-
getFruits("violet"); color, it should return:
{ "color":"violet", "fruits":[] }
<?php
class FruitColor
{
private $fruitcolor;
function FruitColor($fruitcolor)
{
$this->fruitcolor = $fruitcolor;
}
public function getFruits($color)
{
// #todo: implement here
return NULL;
}
}
$fruitcolor = new FruitColor(array(
"red" => array("apple", "strawberry"),
"yellow" => array("lemon", "ripe mango")
));
echo $fruitcolor->getFruits("red");
echo "\n";
echo $fruitcolor->getFruits("violet");
Try this:
class FruitColor {
private $fruitcolor;
function __construct($fruitcolor)
{
$this->fruitcolor = $fruitcolor;
}
public function getFruits($color)
{
$fruits = array();
if (isset($this->fruitcolor[$color])) {
$fruits = $this->fruitcolor[$color];
}
return json_encode(array("color" => $color, "fruits" => $fruits));
}
}
This probably is what you are looking for:
<?php
class FruitColor {
private $data;
function FruitColor($fruitcolors) {
$this->data = $fruitcolors;
}
public function getFruits($color) {
$fruits = [];
if (isset($this->data[$color]) && is_array($this->data[$color])) {
$fruits = $this->data[$color];
}
return json_encode(array("color" => $color, "fruits" => $fruits));
}
}
$fruitcolor = new FruitColor([
"red" => ["apple", "strawberry"],
"yellow" => ["lemon", "ripe mango"]
]);
var_dump($fruitcolor->getFruits("red"));
var_dump($fruitcolor->getFruits("yellow"));
var_dump($fruitcolor->getFruits("violet"));
The output obviously is:
string(47) "{"color":"red","fruits":["apple","strawberry"]}"
string(50) "{"color":"yellow","fruits":["lemon","ripe mango"]}"
string(30) "{"color":"violet","fruits":[]}"
class FruitColor{
private $fruitcolor;
public function __construct( $fruitcolor ){
$this->fruitcolor = $fruitcolor;
}
public function getFruits( $color ){
if( array_key_exists( $color, $this->fruitcolor ) ){
return json_encode( (object)array('color'=>$color, 'fruits' => $this->fruitcolor[ $color ]) );
}
return json_encode( (object)array('color'=>$color, 'fruits' => array() ) );
}
}
$arr=array(
"red" => array("apple", "strawberry"),
"yellow" => array("lemon", "ripe mango")
);
$obj=new FruitColor( $arr );
$red=$obj->getFruits( 'red' );
$yellow=$obj->getFruits( 'yellow' );
$violet=$obj->getFruits( 'violet' );
printf('<pre>%s</pre>',print_r( $red,1));
printf('<pre>%s</pre>',print_r( $yellow,1));
printf('<pre>%s</pre>',print_r( $violet,1));
Will output:
{"color":"red","fruits":["apple","strawberry"]}
{"color":"yellow","fruits":["lemon","ripe mango"]}
{"color":"violet","fruits":[]}

php with Nested JSON

These Items should be put together into a JSON variable, including shop details:
{
"Name": "Shop 1",
"Time": "2015-12-01 12:50",
"Items": [
{
"Name": "Item-1",
"Count": "4",
"Charge": "100"
},
{
"Name": "Item-3",
"Count": "4",
"Charge": "100"
}
],
"Total": "800"
}
To get the outer JSON part I use:
class PrintData {
public $Name = "";
public $Time = "";
// ??
public $Total = "";
}
$printdata = new PrintData();
$printdata->Name=$shop_name;
$printdata->Time=$os_tsready;
// ?? $printdata->Item=$printitems;
$printdata->Total=1007;
However, I cannot figure out how I can get the two Item lines into JSON.
foreach($orderrecords as $or) {
$o_name=escape($or->o_name);
$o_cout=escape($or->o_count);
$o_charge=escape($or->o_charge);
How can I add the Item records correctly?
Fully OOP approach:
class Item {
public $Name;
public $Count;
public $Charge;
public function __construct($name, $count, $charge) {
$this->Name = $name;
$this->Count = $count;
$this->Charge = $charge;
}
}
class PrintData {
public $Items;
public $Name;
public $Time;
public $Total;
public function __construct($name, $time, $items, $total) {
$this->Name = $name;
$this->Time = $time;
$this->Total = $total;
$this->Items = $items;
}
}
$res = new PrintData(
"Shop 1",
"2015-12-01 12:50",
array(
new Item("Item-1", "4", "100"),
new Item("Item-3", "4", "100"),
),
"800"
);
echo json_encode($res);
Try this:
class PrintData {
public $Name = "";
public $Time = "";
public $Items = [];
public $Total = "";
}
$printdata = new PrintData();
$printdata->Name=$shop_name;
$printdata->Time=$os_tsready;
$printdata->Items=$printitems;
$printdata->Total=1007;
Where $printitems is an array of $item elements (like below)
And individually,
$item = array(
"Name" => "Item-1",
"Count" => "4",
"Charge" => "100"
);
$printdata->Items[0] = $item;
Online code: https://3v4l.org/R4s2C
$printitems should be an array here.
$printitems = array(
array('Name' => 'Item-1', 'Count' => '4', 'Charge' => '100'),
array('Name' => 'Item-3', 'Count' => '4', 'Charge' => '100')
);
Final Code
<?php
class PrintData {
public $Name = "";
public $Time = "";
// ??
public $Total = "";
}
$printdata = new PrintData();
$printdata->Name= 'Shop 1';
$printdata->Time='2015-12-01 12:50';
// ?? $printdata->Item=$printitems;
$printdata->Total='800';
$printitems = array(
array('Name' => 'Item-1', 'Count' => '4', 'Charge' => '100'),
array('Name' => 'Item-3', 'Count' => '4', 'Charge' => '100')
);
$printdata->Item = $printitems;
echo '<pre>';
// TILL NOW $printdata is an Object
// json_encode() converts $printdata into JSON Object
print_r(json_encode($printdata)); // THIS WILL GIVE YOUR DESIRED RESULT

How to merge the array value into single array based on group

Hi i m looking for a way to merge multiple array value into single array based on the application group. Is there someone who can help me with this problem?
My Array:
Array{
[0]=>Application{
[id]=>1
[name]=>facebook
[group]=>mobile_app
}
[1]=>Application{
[id]=>2
[name]=>youtube
[group]=>mobile_app
}
[2]=>Application{
[id]=>3
[name]=>whatsapp
[group]=>messenger
}
[3]=>Application{
[id]=>4
[name]=>skype
[group]=>messenger
}
}
Requested output:
Array{
[0]=>application{
[id]=>1
[app_name_1]=>facebook
[app_name_2]=>youtube
[group]=>mobile_app
}
[1]=>application{
[id]=>2
[app_name_1]=>whatsapp
[app_name_2]=>skype
[group]=>messenger
}
}
Assume:
$array is equal to:
Array{
[0]=>Application{
[id]=>1
[name]=>facebook
[group]=>mobile_app
}
[1]=>Application{
[id]=>2
[name]=>youtube
[group]=>mobile_app
}
[2]=>Application{
[id]=>3
[name]=>whatsapp
[group]=>messenger
}
[3]=>Application{
[id]=>4
[name]=>skype
[group]=>messenger
}
}
So, for the first array, each element in the array is an instance of the Application Object which should like this:
class Application {
public $id;
public $name;
public $group;
public function __construct($id, $name, $group) {
$this->id = $id;
$this->name = $name;
$this->group = $group;
}
}
And, a few instances of that object make up the array $array
To format it the way you want, you have to first sort them like this:
foreach($array as $element) {
$newAppName = $element->name;
$newArray[$element->group][] = $element->name;
}
And to store objects of them, you need to design a new class like this:
class ApplicationObjectTwo {
public $id;
public $group;
public function __construct($id, $group) {
$this->id = $id;
$this->group = $group;
}
}
And once you do that, you want to create instances of the object and store them in the array like this:
$counter = 1;
$counterTwo = 1;
$otherArray = [];
foreach($newArray as $group => $data) {
$otherArray[] = new ApplicationObjectTwo($counter, $group);
foreach($data as $app) {
$varName = "app_name_" . $counterTwo;
$index = $counter - 1;
$otherArray[$index]->$varName = $app;
$counterTwo++;
}
$counter++;
$counterTwo = 1;
}
And once you do that, you want to print_r($otherArray)
Pastebin for the entire code: http://pastebin.com/S07BMBuV
As I was unsure exactly what you asked for because of youtube being under mobile andmessenger, I just assumed that was a typo. <br>
I have made this example for youbr>
We start off by creating your array and the array you are going to filter into.
$array = array(
array(
"id" => 1,
"name" => "facebook",
"group" => "mobile"
),
array(
"id" => 2,
"name" => "youtube",
"group" => "mobile"
),
array(
"id" => 3,
"name" => "whatsapp",
"group" => "messenger"
),
array(
"id" => 4,
"name" => "skype",
"group" => "messenger"
)
);
$req_array = array(
"mobile" => array(
),
"messenger" => array(
)
);
Then we loop through all our sub arrays in our $array variable.
Here we take out the group name and group app name and then we push the name into the group in $our req_array.
foreach($array as $app){
$group = $app["group"];
$name = $app["name"];
array_push($req_array[$group], $name);
}

php: additional output from foreach of array

i'm trying to refresh my memory of OO & array structure. i have,
class room{
private $people = array(
'name' => array(
'height' => null,
'age' => null
)
);
function set($list){
foreach($list as $person){
$this->people[$person['name']]['height'] = $person['height'];
$this->people[$person['name']]['age'] = $person['age'];
}
}
function print(){
foreach($this->people as $k => $v){
echo $k . "<br>";
echo $v['height'] . ":" . $v['age'] . "<br><br>";
}
}
}
$input = array( array('name' => 'John', 'height' => '6.4', 'age' => '20'),
array('name' => 'Jane', 'height' => '5.2', 'age' => '21')
);
$i = new room;
$i->set($input);
$i->print();
the output is,
name
:
John
6.4:20
Jane
5.2:21
i'm confused as why name : appears first, when the input array only contains 2 values of each person. i am unsure if i am using my arrays correctly, could someone point out my mistake?
My overall aim of this is to have correct understanding of arrays within arrays & how to best set & get the values
It's because you've initialised the $people array to contain those values
private $people = array(
'name' => array(
'height' => null,
'age' => null
)
);
Change it to:
private $people = array();
that's the good way to do it
your people class
class people {
//properties
private $name;
private $height;
private $age;
//setters
public function setName($name) {
$this->name = $name;
}
public function setHeight($height) {
$this->height = $height;
}
public function setAge($age) {
$this->age = $age;
}
//getters
public function getName() {
return $this->name;
}
public function getHeight() {
return $this->height;
}
public function getAge() {
return $this->age;
}
}
your room class
class room {
//properties
private $people = array();
//setters
public function setPeople($people) {
$this->people[] = $people;
}
//getters
public function getPeoples() {
return $this->people;
}
}
and how to control it in OOP
$people1 = new people();
$people1->setName('John');
$people1->setHeight('6.4');
$people1->setAge('20');
$people2 = new people();
$people2->setName('Jane');
$people2->setHeight('5.2');
$people2->setAge('21');
$room = new room();
$room->setPeople($people1);
$room->setPeople($people2);
// Removing people array initial data will solve the issue :)
class room{
private $people = array();
function set($list){
foreach($list as $person){
$this->people[$person['name']]['height'] = $person['height'];
$this->people[$person['name']]['age'] = $person['age'];
}
}
function print(){
foreach($this->people as $k => $v){
echo $k . "<br>";
echo $v['height'] . ":" . $v['age'] . "<br><br>";
}
}
}
$input = array( array('name' => 'John', 'height' => '6.4', 'age' => '20'),
array('name' => 'Jane', 'height' => '5.2', 'age' => '21')
);
$i = new room;
$i->set($input);
$i->print();

Categories