So here is my case:
I have three functions performing some chemical reactions(synthesis1(), synthesis2() & synthesis3() ).
All of these functions will give an answer or a fail in the results.
They were originally separate scripts but are now in a class.
NB: the functions work fine by themselves, even in the class.
Below is my script to instantiate the class and start the functions.
My problem is that since i am running a reaction which fires all the functions;
i get one 1 correct answer and two fails or three fail at once.
What is the best way to handle the situation.
I want one correct answer and suppress the two fails or just show one fail in case of three fails(all fails). I don't expect three right answers.
P.s. All answers are strings.
<?php
// create an object for class name
$aaa = new synthesis();
$abc = new synthesis();
$abcd = new synthesis();
// call the functions in the class
$synthesis1 = $aaa->synthesis1();
$synthesis2 = $abc->synthesis2();
$synthesis3 = $abcd->synthesis3();
// call the if functions
$searches = array($synthesis1, $synthesis2, $synthesis3);
foreach($searches as $search) {
if ($aaa->synthesis1($search)){
echo 'Match found: ' . $search;
break;
}
elseif ($abc->synthesis2($search)){
echo 'Match found: ' . $search;
break;
}
elseif ($abcd->synthesis3($search)){
echo 'Match found: ' . $search;
break;
}
else{ echo"Please try again or try another reaction";}
}
?>
I don't know why you need to instantiate three different objects if you have three individually named methods.
I would think you might want to add a method to your class to simply run all synthesis methods all at once and return the result. So something like:
class synthesis {
protected $synthesis_methods = array(
'synthesis1',
'synthesis2',
'synthesis3',
// add more methods here if needed
}
public function synthesis1() {
// your method logic here
}
public function synthesis2() {
// your method logic here
}
public function synthesis2() {
// your method logic here
}
public function synthesize_all() {
$result = false;
$i = 0;
while(false === $result && $i < count($this->synthesis_methods)) {
$result = call_user_func(array($this, $this->synthesis_methods[$i]));
$i++;
}
return $result;
}
}
You would then only instantiate a single object. Usage would be:
$synth_obj = new synthesis();
var_dump($synth_obj->synthesize_all());
An easy way to handle this is to use OR logic:
if($aaa->synthesis1($search) or $abc->synthesis2($search) or $abcd->synthesis3($search))
{
echo "Match Found: $search";
break;
}
else
{
echo "Please try again or try another reaction.";
}
Related
A better way than multiple if condition in php? Is too many if condition there, so i need something more simple and efficient...and you can show me examples?!
if($_GET['id']=="4") {
try {
$ids = '4,246,226';
$notin = '1';
$parent_forum = 'php_forums.parent_id';
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
if($_GET['id']=="246") {
try {
$ids = '246';
$notin = '1';
$parent_forum = 'php_forums.parent_id';
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
if($_GET['id']=="226") {
try {
$ids = '226';
$notin = '1';
$parent_forum = 'php_forums.parent_id';
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
The thing about code is that you can tackle one problem in many different ways. It is all justified depending on the environment and how you want to organise your problem and the dimension of your project.
So, for example, as mentioned in the comments, a good replacement for if conditions are switch cases.
Switch cases example
I am not aware of the entire structure behind your question, but I will provide a solution on how I would do it.
/**
* #throws Exception
*/
public function doSomethingWithGET()
{
$notin = 1;
$parent_forum = 'php_forums.parent_id';
switch ($_GET['id']) {
case '4':
case '246':
case '226':
$ids = $_GET['id'];
break;
default:
throw new Exception('Specify your error message here');
}
}
The only reason why i grouped the switch cases is because nothing seemed to change in your code that would justify clear separation, BUT to make you aware you can both separate the cases to be very specific depending on your IDs OR group certain IDS if only a few behave equally, while separating specific IDS for very specific behaviours.
Method calls
This scenario is just a different way to tackle the same problem. Just for giggles and playfulness of it :) I am sure it has its own play cases, just like get_class can avoid us to constantly create a switch case for factory classes, but as mentioned before, it all depends on your idea :)
class Test
{
/**
* #var array $idsAndActions
**/
protect $idsAndActions;
public function __construct ()
{
$this->idsAndActions = [
'4' => 'doSomethingWithGET',
'246' => 'doSomethingWithGET',
'226' => 'somethingDifferent',
];
}
public function parseGet ()
{
if (array_key_exists($_GET['id'], $this->idsAndActions)) {
$methodCall = $this->idsAndActions[$_GET['id']];
if (method_exists($this, $methodCall)) {
$this->$methodCall();
//add here more code for success events
}
}
echo '[Error] Your message';
//You can also throw an exception, which I would advice depending on who calls this :)
}
public function doSomethingWithGET ()
{
$this->notin = 1;
$this->parent_forum = 'php_forums.parent_id';
$this->ids = $_GET['id'];
}
public function somethingDifferent ()
{
$this->notin = 20;
$this->parent_forum = 'another_thing_here';
$this->ids = $_GET['id'];
}
}
Hope it helps you giving some ideas on how you can tackle this or find a solution that best suits you! :)
NOTE: I know it is not mentioned, BUT if you are using the $_GET['id'] do do some kind of access to DBs or execute system commands do not forget the possibility of system breach and sql injection. Never trust variables external to the system
Until yesterday I was burning my brain trying to switch from a procedural thinking to a OOP thinking; this morning I gave up. I said to my self I wasn't probably ready yet to understand it.
I started then coding in the usual way, writing a function to check if there's the cookie "logged" or not
function chkCookieLogin() {
if(isset($_COOKIE["logged"])) {
$logged = 'true';
$cookieValue = $_COOKIE["logged"];
return $logged;
return $cookieValue;
}
else {
$logged = 'false';
return $logged;
}
}
$result = chkCookieLogin();
if($result == 'true'){
echo $cookieValue;
}
else {
echo 'NO COOKIE';
}
since I run across a problem: I wanted to return two variables ($logged and $cookieValue) instead of just one. I google it and I found this answer where Jasper explains a method using an OOP point of view (or this is what I can see).
That answer opened me a new vision on the OOP so I tried to rewrite what I was trying to achieve this way:
class chkCookie {
public $logged;
public $cookieValue;
public function __construct($logged, $cookieValue) {
$this->logged = $logged;
$this->cookieValue = $cookieValue;
}
function chkCookieLogin() {
$out = new chkCookie();
if(isset($_COOKIE["logged"])) {
$out->logged = 'true';
$out->cookieValue = $_COOKIE["logged"];
return $out;
}
else {
$out->logged = 'false';
return $out;
}
}
}
$vars = chkCookieLogin();
$logged = $vars->logged;
$cookieValue = $vars->cookieValue;
echo $logged; echo $cookieValue;
Obviously it didn't work at the first attempt...and neither at the second and the third. But for the first time I feel I'm at one step to "really touch" the OOP (or this is what I think!).
My questions are:
is this attempt correctly written from the OOP point of view?
If yes, what are the problems? ('cause I guess there's more than one)
Thank you so much!
Credit to #NiettheDarkAbsol for the idea of returning an Array data-type.
Using dependency injection, you can set-up an object like this:
class Factory {
private $Data = [];
public function set($index, $data) {
$this->Data[$index] = $data;
}
public function get($index) {
return $this->Data[$index];
}
}
Then to use the DI module, you can set methods like so (using anonymous functions):
$f = new Factory();
$f->set('Cookies', $_SESSION);
$f->set('Check-Cookie', function() use ($f) {
return $f->get('Cookies')['logged'] ? [true, $f->get('Cookies')['logged']] : [false, null];
});
Using error checks, we can then call the method when and as we need it:
$cookieArr = is_callable($f->get('Check-Cookie')) ? call_user_func($f->get('Check-Cookie')) : [];
echo $cookieArr[0] ? $cookieArr[1] : 'Logged is not set';
I'd also consider adding constants to your DI class, allowing more dynamic approaches rather than doing error checks each time. IE, on set() include a constant like Factory::FUNC_ARRAY so your get() method can return the closure already executed.
You can look into using ternary operators if you're confused.
See it working over at 3v4l.org.
If it means anything, here is an OOP styled approach.
I have a class that contains a method which carries out various database checks. It then returns the value, if exists.
Here is a very basic setup example:
PHP Class
class myClass{
var $aVar1;
var $aVar2;
function myMethod()
{
// database query
// if results from query return **results**
// else return false
}
}
HTML/PHP File
// setup $myClass object var
<?php if($myClass->myMethod(): ?>
// lots of html
<?php echo $myClass->myMethod() ?>
// lots of html
<?php endif; ?>
This occurance happens multiple times throughout my file with different methods. My question is, I am calling the method initially and checking if it's false and then calling it again to echo the output.
I could do the following but would end up with a variable declaration on every method. There must be a more professional approach?
<?php
$myMethod = $myClass->myMethod();
if($myMethod): ?>
// lots of html
<?php echo $myMethod ?>
// lots of html
<?php endif; ?>
Is there a cleaner more efficient way of doing this?
Age old problem. One common technique is to store the return val in a temporary variable
$result=$myClass->myMethod();
if($result!=FALSE)
echo $result;
You can also use a simpler version
if($result=$myClass->myMethod())
echo $result;
And you can also use the simplest one!
echo $myClass->myMethod() ?: '';
Simpler than the simplest one!
echo $result=$myClass->myMethod();
You can do this to reduce verbosity:
<?php
function foo($bool = true) {
$result = array();
if($bool) {
$result = array('bar');
}
return $result;
}
if(! array()) {
echo 'empty array evaluates to false.';
}
if($result = foo()) {
var_export($result); // Will dump array with 'bar'.
}
if($result = foo(false)) {
var_export($result); // Won't happen.
}
If your return is truish then the contents of the if will execute.
<?php
class oopClass{
function __construct($editingtext, $searchfor, $replacewith){
if(!empty($editingtext) && !empty($searchfor) && !empty($replacewith)){
$editingtext = str_replace($searchfor,$replacewith,$editingtext);
echo $editingtext;
}else{
echo 'All Fields Are Required.';
}
}
}
//closing php
The code is working , but as there is no properties of the class are set which is a bad practice, which variables of this code should be set as a class property and why?
There are other things wrong with your code, and it is not the absence of properties. You are constructing an object and in the constructor you output the result. THAT is bad practice.
I'd fix it something like this:
class TextReplacer {
var $search;
var $replace;
function __construct($s, $r) {
$this->search = $s;
$this->replace = $r;
}
function replace($text) {
// your code, using the properties for search and replace, RETURNING the result
return $ret;
}
}
then call like:
$oo = new TextReplacer("bar", "baz");
echo $oo->replace("let's replace some bars in here");
In short:
Nothing wrong with not using properties, if your class is designed like that.
Please use useful class, method and variable names.
Don't do more than one thing in a method ("side effects").
Don't output the result, but return it. It is up to the user of the class to decide what happens to the results.
(most importantly): Think before you code.
It's not necessarily bad practice if the above code is ALL you plan on doing with this code. If you needed to expand its functionality, I might imagine $editingtext could be a property.
class oopClass{
private $editingtext;
function __construct($editingtext, $searchfor, $replacewith){
$this->editingtext = $editingtext;
if(!empty($this->editingtext) && !empty($searchfor) && !empty($replacewith)){
$this->editingtext = str_replace($searchfor,$replacewith,$this->editingtext);
echo $this->editingtext;
}else{
echo 'All Fields Are Required.';
}
}
}
//closing php
Hi I've recently started yet another project and my boss is insisting that we use the MVC model, the problem being that due to many articles showing different ways to do this we havent managed to agree on what a proper MVC model should look like.
So here's my problem for this project (whether this is the correct way to do it or not) I am using the following baseline rules
Controller classes manage both getting the data from the model classes and passing the data to the view classes and retrieving the view and displaying it
Model classes managhe all database actions and return the data using mysql_fetch_assoc
View classes create the views using the data etc.
So my issue is with processing the information from mysql_fetch_assoc normally you would do something like this (assuming we have already run a query)
while ($row = mysql_fetch_assoc($result)) {
echo $row["username"];
}
but as I'm processing the results in the view class rather than the model how do I cycle through all of the results when I have already passed the assoc array to the view, currently I'm getting a problem where it keeps looping through the results until it hits a memory size error so for some reason it isn't able to figure out how many results it needs to cycle through
My current code snippets are below sorry for the bad explainations.
Controller
require_once 'admin_model.php';
require_once 'admin_view.php';
class admin_controller {
public $model;
public $view;
public function __construct() {
$this->model = new admin_model;
$this->view = new admin_view;
}
public function get_group_view() {
$in_model = $this->model->get_group_view();
$in_view = $this->view->get_group_view ($in_model);
echo $in_view;
}
Model
class admin_model {
public function get_group_view() {
$query = mysql_query("
SELECT
group_id,
group_name
FROM
user_groups
");
return mysql_fetch_assoc($query);
}
}
View
class admin_view {
public function get_group_view($group_data) {
while($group_data) {
$output .= $group_data['group_id'] . '###' . $group_data['group_name'] . '<hr />';
}
return $output;
}
}
Which currently returns the error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 133693393 bytes)
So can someone please advise me on the best way to go through the results without moving 'mysql_fetch_assoc' function from the model class?
PS I know I'm probably doing MVC completely wrong but it works for us and we don't want to have to research and change our code yet again thanks.
You should not return the MySQL Result - you should do:
$return = array();
$query = mysql_query("SELECT group_id, group_name FROM user_groups");
while($row = mysql_fetch_assoc($query)) {
$return[] = $row;
}
mysql_free_result($row);
return $return;
And you should fix the $group_data bug per #Roman_S . The correct use, along with the above code is
public function get_group_view($group_data) {
$output = '';
foreach($group_data as $group) {
$output .= $group['group_id'] . '###' . $group['group_name'] . '<hr />';
}
return $output;
}
Finally you should migrate to MySQLi or PDO if possible.
You have en error here
while($group_data) {
$output .= $group_data['group_id'] . '###' . $group_data['group_name'] . '<hr />';
}
If $group_data is not empty - your loop will never end.
To give a suggestion on how to handle database control.
When using PDO for instance
$pdoInst = new PDO( .. );
and we have a method somewhere that validates every statement the $pdoInst produces
abstract class .. {
public static function validateStmt($stmt) {
if($stmt !== false) { .. }
// everything else you like, even error handling, log files, etc.
}
}
}
a prepared statement like the get_group_view method will look like the following
public function get_group_view {
$stmt = $pdoInst->prepare(" .. QUERY .. ");
// the return can be wrapped in a method to handle errors, etc, which can be done
// here or else where.
$stmt->execute() // returns true or false
return $stmt;
}
now for iteration
public function get_group_view($group_data) {
$output = "";
// validate the statement, can be done here or else where as said before
if($pdoInst::validateStmt($group_data)) {
// many ways how to iterate, foreach is just one.
foreach($group_data as $index => $group) {
$output .= $group['group_id'] . '###' . $group['group_name'] . '<hr />';
}
}
return $output;
}
The nicest thing about PDO is that you can extend the classes with custom ones. You can add functionality that adds more value to your Model.