Check if method is false then output results - php

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.

Related

PHP variables in function argument is not working

I've retried solving this, by using a condition and a default attribute as recommended.
User-generated data is declared before to $Variable_1:
<?php
$Variable_1 = 'abc123!' //The user inputs the data
if ($booleanvalue == true) { // User selects if they've put data
name($user_data, $Variable_0 = $Variable_1 );
}
//Then the function will use the user's data from $Variable_1
function name($user_data, $Variable_0 = null) {
//Other code...
}
$Variable_2 = name($user_data);
$data['variable_2'] = $Variable_2;
?>
Is it possible to have $Variable_0 pre-declared and then put as an argument?
you have a few mistakes in your code. and I don't think that you can use a function named name.
you could do it this way for example:
<?php
$Variable_1 = 'abc123!';
function test($data) {
global $Variable_1;
//Other calculations...
return $Variable_1 . $data;
}
$testdata = "huhu";
$Variable_2 = test($testdata);
$data['variable_2'] = $Variable_2;
echo $data['variable_2'];
?>
I agree with the comment by El_Vanja, but you can access a global variable through the magic $GLOBALS array anywhere.
<?php
// what you might actually want
function name($variable = 'abc123!')
{
// if no value is passed into the function the default value 'abc123!' is used
}
$variable = 'abc123!';
// what you could do
function name2($variable)
{
// $variable can be any value
// $globalVariable is 'abc123!';
$globalVariable = $GLOBALS['variable'];
}
I'd also like to point out that currently you have no way of controlling what type of data is passed to the function. You might consider adding types.
<?php
<?php
// string means the variable passed to the function has to be a ... well string
function name(string $variable = 'abc123!'): void
{
// void means the function doesn't return any values
}
name(array()); // this throws a TypeError

Handling multiple variable results

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.";
}

How to write short PHP functions that work together

I want to modularize functions, but this is not working...
class Review {
public function show_report($db, $id){
// Query the DB on $id
$x = $this->get_survey($db, 1);
$y = $this->get_survey($db, 2);
// Use x and y to build a report
return $a_report;
}
private function get_survey($db, $n){
// Query the DB for a certain survey number
if($n == 1){
// Perform some logic
} else {
// Perform some other logic
}
return $a_survey;
}
};
Using the class like this..
<?php
include_once('api/Review.class.php');
$r = new Review();
?>
<p>
<?php
echo Review::show_report($db, $id);
?>
</p>
PHP throws this:
Fatal error: Using $this when not in object context in Review.class.php
Thanks for the help!
Your design pattern is good, you just have a syntax error. You have missed the $ sign on your method calls in show_report(), it should look like this:
public function show_report($db, $id){
// Query the DB on $id
$x = $this->get_survey($db, 1);
$y = $this->get_survey($db, 2);
// Use x and y to build a report
return $a_report;
}
Also, the semicolon at the end of the class is unnecessary.
Finally, as another person mentioned, you need to call show_report with parameters, like this:
echo $r->show_report($db, $id);
Inside your function show_report($db, $id) is the this pointer without the prefixing $ sign which causes the syntax error. Additionally in the second part the function isn't called with parameters.
The function has to look like that:
public function show_report($db, $id){
// Query the DB on $id
$x = $this->get_survey($db, 1);
$y = $this->get_survey($db, 2);
// Use x and y to build a report
return $a_report;
}
echo $r->show_report;
In this example, you are attempting to call the function with no arguments. If this is really what you are doing, that would be at least one problem.
Instead, call the function with arguments:
echo $r->show_report('foo', 1);
Thank you all. I fixed all the syntax errors, thanks to https://stackoverflow.com/a/19258788/1004107. This is the root of the issue I do believe:
<?php
include_once('api/Review.class.php');
$r = new Review();
?>
<p>
<?php
echo Review::show_report($db, $id);
?>
</p>
Should be...
<?php
include_once('api/Review.class.php');
$r = new Review();
?>
<p>
<?php
echo $r->show_report($db, $id);
?>
</p>
And this is do to static context? Please comment.

Which variables should be set as the properties of a class in php?

<?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

Simple template var replacement, but with a twist

So I'm setting up a system that has a lot of emails, and variable replacement within it, so I'm writing a class to manage some variable replacement for templates stored in the database.
Here's a brief example:
// template is stored in db, so that's how this would get loaded in
$template = "Hello, %customer_name%, thank you for contacting %website_name%";
// The array of replacements is built manually and passed to the class
// with actual values being called from db
$replacements = array('%customer_name%'=>'Bob', '%website_name%'=>'Acme');
$rendered = str_replace(array_keys($replacements), $replacements, $template);
Now, that works well and good for single var replacements, basic stuff. However, there are some places where there should be a for loop, and I'm lost how to implement it.
The idea is there'd be a template like this:
"hello, %customer_name%, thank you for
requesting information on {products}"
Where, {products} would be an array passed to the template, which the is looped over for products requested, with a format like:
Our product %product_name% has a cost
of %product_price%. Learn more at
%product_url%.
So an example rendered version of this would be:
"hello, bob, thank you for requesting
information on:
Our product WidgetA has a cost of $1.
Learn more at example/A
Our product WidgetB has a cost of $2.
Learn more at example/B
Our product WidgetC has a cost of $3.
Learn more at example/C.
What's the best way to accomplish this?
Well, I really dont see the point in a template engine that uses repalcements/regex
PHP Is already a template engine, when you write <?php echo $var?> its just like doing <{$var}> or {$var}
Think of it this way, PHP Already translates <?php echo '<b>hello</b>'?> into <b>hello</b> by its engine, so why make it do everything 2 times over.
The way i would implement a template engine is like so
Firstly create a template class
class Template
{
var $vars = array();
function __set($key,$val)
{
$this->vars[$key] = $val;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : false;
}
function output($tpl = false)
{
if($tpl === false)
{
die('No template file selected in Template::output(...)');
}
if(!file_exists(($dir = 'templates/' . $tpl . '.php')))
{
die(sprintf('Tpl file does not exists (%s)',$dir));
}
new TemplateLoader($dir,$this->vars);
return true;
}
}
This is what you use in your login such as index.php, you will set data just like an stdClass just google it if your unsure. and when you run the output command it sends the data and tpl to the next class below.
And then create a standalone class to compile the tpl file within.
class TemplateLoader
{
private $vars = array();
private $_vars = array(); //hold vars set within the tpl file
function __construct($file,$variables)
{
$this->vars = $variables;
//Start the capture;
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean(); //Clean it
//Return here if you wish
echo $contents;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : (isset($this->_vars[$key]) ? $this->_vars[$key] : false) : false;
}
function __set($key,$val)
{
$this->_vars[$key] = $val;
return true;
}
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
}
The reason we keep this seperate is so it has its own space to run in, you just load your tpl file as an include in your constructor so it only can be loaded once, then when the file is included it has access to all the data and methods within TemplateLoader.
Index.php
<?php
require_once 'includes/Template.php';
require_once 'includes/TemplateLoader.php';
$Template = new Template();
$Template->foo = 'somestring';
$Template->bar = array('some' => 'array');
$Template->zed = new stdClass(); // Showing Objects
$Template->output('index'); // loads templates/index.php
?>
Now here we dont really want to mix html with this page because by seperating the php and the view / templates you making sure all your php has completed because when you send html or use html it stops certain aspects of your script from running.
templates/index.php
header
<h1><?php $this->foo;?></h1>
<ul>
<?php foreach($this->bar as $this->_foo):?>
<li><?php echo $this->_foo; ?></li>
<?php endforeach; ?>
</ul>
<p>Testing Objects</p>
<?php $this->sidebar = $this->foo->show_sidebar ? $this->foo->show_sidebar : false;?>
<?php if($this->sidebar):?>
Showing my sidebar.
<?php endif;?>
footer
Now here we can see that were mixing html with php but this is ok because in ehre you should only use basic stuff such as Foreach,For etc. and Variables.
NOTE: IN the TemplateLoader Class you can add a function like..
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
This will allow you to increase your actions in your templates so bold,italic,atuoloop,css_secure,stripslashs..
You still have all the normal tools such as stripslashes/htmlentites etc.
Heres a small example of the bold.
$this->bold('foo'); //Returns <strong>somestring</string>
You can add lots of tools into the TempalteLoader class such as inc() to load other tpl files, you can develop a helper system so you can go $this->helpers->jquery->googleSource
If you have any more questions feel free to ask me.
----------
An example of storing in your database.
<?php
if(false != ($data = mysql_query('SELECT * FROM tpl_catch where item_name = \'index\' AND item_save_time > '.time() - 3600 .' LIMIT 1 ORDER BY item_save_time DESC')))
{
if(myslq_num_rows($data) > 0)
{
$row = mysql_fetch_assc($data);
die($row[0]['item_content']);
}else
{
//Compile it with the sample code in first section (index.php)
//Followed by inserting it into the database
then print out the content.
}
}
?>
If you wish to store your tpl files including PHP then that's not a problem, within Template where you passing in the tpl file name just search db instead of the filesystem
$products = array('...');
function parse_products($matches)
{
global $products;
$str = '';
foreach($products as $product) {
$str .= str_replace('%product_name%', $product, $matches[1]); // $matches[1] is whatever is between {products} and {/products}
}
return $str;
}
$str = preg_replace_callback('#\{products}(.*)\{/products}#s', 'parse_products', $str);
The idea is to find string between {products} and {products}, pass it to some function, do whatever you need to do with it, iterating over $products array.
Whatever the function returns replaces whole "{products}[anything here]{/products}".
The input string would look like that:
Requested products: {products}%product_name%{/products}

Categories