Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Something I've never been sure about is how many variable checks to do in PHP. For example take the following piece of code. I am not checking any of the variables before I assign them or pass them to a function to see if they contain what I expect
$carId = '12';
$aCar = fetchCar($carId);
$make = $aCar['make'];
$model = $aCar['model'];
$yearMade = $aCar['year'];
$age = calcAge($yearMade);
Now if I add some checks
$carId = '12';
if(is_numeric($carId))
{
$aCar = fetchCar($carId);
if(isset($aCar['make']) && is_string($aCar['make']))
{
$make = $aCar['make'];
}
else
{
//Report error
}
if(isset($aCar['model']) && is_string($aCar['model']))
{
$model = $aCar['model'];
}
else
{
//Report error
}
if(isset($aCar['year']) && is_numeric($aCar['year']))
{
$yearMade = $aCar['year'];
$age = calcAge($yearMade);
}
else
{
//Report error
}
}
else
{
//Report errors
}
The code is now better but is it a bit too excessive and bloated? Should I be doing this many checks?
If I shouldn't be doing this many checks where do you draw the line between what you should and shouldn't check?
This is the dilemma of a dynamic type language.
It depends heavily on what fetchCar() function is doing.
The approach i would take is assume fetchCar is returning a car array or throwing exception.
If you combine this with good exception handling logic you can end up with clean and stable code.
For example:
function fetchCar($id) {
$car = queryDatabaseSomehow();
if (empty($car)) {
throw new ExceptionNotFound();
}
//eventually you can put your type checking here?
if (!isset($car['x']) || !is_string($car['x'])) {
throw new ExceptionDb();
}
}
echo fetchCar(3)['make'];
Also if you would like to do this super-proper and go fully OOP, Car should become a class with make,model and year as its members. fetchCar() would return Car or throw Exception. But this is not always desirable of course.
One issue that some people haven't noticed. Be wary of using is_string:
<?php
$var = "test";
$var['something'] = 2;
if(is_string($var['something'])) {
echo "Hello world!"; // Will echo this because $var is a string!
} else {
echo "Hello hell!";
}
echo "<br/>";
echo $var['something']; // returns 2
?>
PHPFiddle.
Compare it with this:
$var = array('something' => 2);
if(is_string($var['something'])) {
echo "Hello world!"; // $var is now an array
} else if (is_numeric($var['something'])) {
echo "Hello hell!"; // Will echo this because $var is string!
}
echo "<br/>";
echo $var['something'];
You need to check whether $var is an array, as it might give you unexpected results. isset($var['something']) will return true in the first example.
To answer your question, I don't think those are too many checks. It really depends on what fetchCar() does and how it gets the data. If you can't trust it (say, it's based on user data) then you should perform all these checks. If not, then there is no point really.
I rather turn it all into a function that can be reused for these cases.
function check_keys($arr_check, $arr_cond) {
$boo_success = TRUE;
foreach(array_keys($arr_cond) as $h)
if (in_array($arr_cond[$h], array('is_string', 'is_numeric'))) {
if ( ! isset($arr_check[$h]) or ! ($arr_cond[$h]($arr_check[$h]))) {
$boo_success = FALSE;
echo "The key {$h} is missing!";
// If run through a class, $this->errors[] = 'error message';
}
} else {
$boo_success = FALSE;
echo 'Invalid function';
}
return $boo_success;
}
$arr_keys = array('make' => 'is_string',
'model' => 'is_string',
'year' => 'is_numeric');
if (check_keys($aCar, $arr_keys)) {
// Run successful stuff
}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I need to make a conditional statement where the 5 variables should be empty before perform an action. The problem is some variables can be zero, false or NULL value. How to catch all of them?
Which one is better?
If (!$a && !$b && !$c && !$d && !$e) {
// do some action
} else {
exit;
}
OR
If (empty($a) && empty($b) && empty($c) && empty($d) && empty($e)) {
// do some action
} else {
exit;
}
Thank you.
First of all, use "code sample" to show code.
When you use !$a you are actually casting $a to boolean.
The problem here is
$a = 0;
if (!$a) {
echo 'NOT EMPTY';
} else {
echo 'EMPTY';
}
//OUTPUT EMPTY BECAUSE 0 to boolean is FALSE
Same example with NULL value.
About empty i advice you to check the documentation
Read it and choose the way that fit your needs.
Hope this helps
This could be an approach to check multiple variables are empty at once.
<?php
$a = $b = $c = $d = $e = '';
#$b = 5; // comment out to go on else block
if (empty($a . $b . $c . $d . $e)){
echo "All variables are empty, do what you want to do man";
}else{
echo "One of variable is not empty";
}
?>
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have the following code and want to know if there is a better way to use the if-else with same result other than using the same else three times?
if($condition1) {
// some code to get condition 2
if($condition2) {
// some code to get condition 3
if($condition3) {
$dt = $something;
} else {
$dt = "";
}
} else {
$dt = "";
}
} else {
$dt = "";
}
You could easily get rid of some of the extra else statements.
$dt = ""; // Assign $dt in the beginning
if ($condition1) {
// some code to get condition 2
if ($condition2 && $condition3) {
// some code to get condition 3
$dt = $something;
}
}
Two ways to avoid nested statements.
using a function
$dt = doSomething($params);
function someFunction ($params) {
if (!$condition1) {
return "";
}
// do stuff for condition 1
if (!$condition2) {
return "";
}
// do stuff for condition 2
if (!$condition3) {
return "";
}
return $something;
}
using a do/while statement
do {
$dt = "";
if (!$condition1) {
break;
}
// do stuff for condition 1
if (!$condition2) {
break;
}
// do stuff for condition 2
if (!$condition3) {
break;
}
$dt = $something;
} while (0); // since this will evaluate to false it will not loop at all.
This question already has answers here:
How to use return inside a recursive function in PHP
(4 answers)
Closed 9 months ago.
I am trying to calculate parent names of a person recursively to a specific person ID. I've written recursive call for this but it is behaving weirdly. I've tried to debug it but still don't get what I am doing wrong with it.
Here is my script:
public function full_name_to_root()
{
$name = $this->name;
// printf('caller');
$full_name = FamilyTree::getNameToRoot($this,$name,1);
dd($full_name);
return $full_name;
}
public static function getNameToRoot($daleel,$name,$c)
{
$halt = false;
$c+=1;
echo 'in rec. <br>';
$parent = $daleel->parent;
if(!$parent){
$halt = true;
return $c;
}elseif ($parent && $parent->family_tree_id==6) {
echo 'Reached to where we want to stop <br>';
$name .= ' '.$parent->name;
$halt = true;
return $c; // As you can see in output when control reaches it is not stopping the execution, but it is always going to end
}elseif($parent){
echo 'call again <br>';
$name .= ' '.$parent->name;
$halt = false;
FamilyTree::getNameToRoot($parent,$name,$c);
}
// Control should never reach here but it is coming here every time and more annoying thing is that it is printing highest count(or in case of name the most large, which also the required one) at first time and then gradually prints lower
echo "<br>";
echo $c;
echo "<br>";
// function executes above echo statements 6-7 times but only executes the return statement last time.
return $c; // I am sending count in response for just testing purpose. It is behaving same as $name is behaving.
}
I have adding some flags for debugging purpose here is the output of this function.
Any help sorting out this issue would be amazing. Thanks!
To give you are starting point I would say, that your main problem is caused when you enter this if branch.
elseif($parent){
echo 'call again <br>';
$name .= ' '.$parent->name;
$halt = false;
FamilyTree::getNameToRoot($parent,$name,$c);
}
You don't have a return statement at FamilyTree::getNameToRoot(...)
So the the method does not return and continues to run after the subsequent calls to FamilyTree::getNameToRoot() are finished.
So just use
return FamilyTree::getNameToRoot($parent,$name,$c);
The $halt variable is not needed at all.
Yes, it will always continue because you are not stopping it. You have to manually stop with something like this :
....
$halt = false;
while ( !$halt )
{
echo 'in rec. <br>';
$parent = $daleel->parent;
...
elseif($parent){
echo 'call again <br>';
$name .= ' '.$parent->name;
$halt = false;
FamilyTree::getNameToRoot($parent,$name,$c);
}
}
You may have to rearrange a few things inside the while loop but at least it will stop running as soon as $halt is true.
Try this, if it does not work, I may have missed something.
Good luck mate!
For quite a while now we experience a very weird problem with our hosting server. Once a while (seems randomly) variables in PHP become NULLs.
In general everything works perfectly fine, but once a while it happens. All accounts on the server are affected and all PHP apps (including PHPMyAdmin, Wordpress our own scripts). We contacted our hosting company, but they are unable to find any solution.
I had few ideas, the most promising one was an issue with Suhosin. But I do not get any message in the log directly from it.
We made a simplest possible script to reproduce the error:
<?php
class Example
{
protected $stringVar = 'this is a string value';
public function accessParameter()
{
$error = false;
if (isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : " . $this->toStringWithType($this->stringVar) . "\n";
} else {
echo "string var is not set\n";
$error = true;
}
if ($error) {
$logfile = dirname(__FILE__)."/random_bug_log.log";
file_put_contents($logfile, date('Y-m-d H:i:s')."\n", FILE_APPEND);
file_put_contents($logfile, $this->toStringWithType($this->stringVar) . "\n", FILE_APPEND);
}
}
public function toStringWithType($var)
{
$type = gettype($var);
return "($type) '$var'";
}
}
$e = new Example();
$e->accessParameter();
Normal output:
string var : (string) 'this is a string value'
Output when the weird thing happens:
string var is not set
I open to any ideas or suggestions how to solve this problem. I guess the ultimate solution is to change the hosting company. I did not manage to create this issue on localhost or any other server.
Test piece that have been made, including your suggestions:
<?php
class Example
{
protected $stringVar = 'this is a string value';
public function accessParameter() {
$error = false;
if(isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : "
.$this->toStringWithType($this->stringVar)
."\n";
} else {
echo "string var is not set\n";
$error = true;
}
if($error) {
$logfile = dirname(__FILE__)."/random_bug_log.log";
file_put_contents($logfile, date('Y-m-d H:i:s')." ", FILE_APPEND);
file_put_contents($logfile,
$this->toStringWithType($this->stringVar) . "\n",
FILE_APPEND);
}
}
public function writeParameter() {
$this->stringVar="variable assigned";
if(isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : "
.$this->toStringWithType($this->stringVar)
."\n";
} else {
echo "string var is not set\n";
$error = true;
}
}
public function toStringWithType($var)
{
$type = gettype($var);
return "($type) '$var'";
}
}
$e = new Example();
$e->accessParameter();
$e->writeParameter();
The output while the thing happens:
string var is not set
string var is not set
it is very strange problem.
it may not be a solution but worth to try;
protected $stringVar;
function __construct() {
$this->stringVar = 'this is a string value';
}
I would recommend to use !== instead of is_null to see if the variable is actually null.
if (isset($this->stringVar) && ($this->stringVar !== null)) {
or
if (isset($this->stringVar) && (!empty($this->stringVar)) {
should do the work too.
In case of theses type of issues check with the value that you have in if condition and do what you want in else. Like in your situation do like:
if(isset($this->stringVar) && ($this->stringVar == "this is a string value")) {
}else{
// your code here...
}
I'd like some help please, if its possible.
I have created two functions in order to display some messages when is set a $_GET after a redirect.Here's the code:
function display(){
if(isset($_GET['cnf_upd']) && $_GET['cnf_upd'] == '1'){
$value = "The update was successful!";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_upd']) && $_GET['err_upd'] == '1'){
$value = "The Update failed.";
$type = "error";
construct_the_div($value, $type);
}
if(isset($_GET['cnf_del']) && $_GET['cnf_del'] == '1'){
$value = "Deleted completely.";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_del']) && $_GET['err_del'] == '1'){
$value = "Unable to delete.";
$type = "error";
construct_the_div($value, $type);
}
}
function construct_the_div($value, $type){
// creating a div to display the message results
$div = "<div class=\"{$type}Msg\">\n";
$div .= "<p>{$value}</p>\n";
$div .= "</div><!-- end of {$type}Msg -->\n";
echo $div;
}
What I'd like to make is to try to improve the display function, as it gets longer and longer, so that there whould be only one (or two at most) if statement(s) if possible. So the value of the GET will be dynamicly inside the if condition and also if it has the preffix 'cnf_' it wil be a 'confirmMsg' and if it has the preffix 'err_' it wil be a 'errorMsg'.
Is it possible to make something like this???
function display() {
$messages = array(
'cnf_upd' => 'The update was successful!',
'cnf_err' => 'The Update failed.!',
// ...
// add all error and confirm there
// ...
);
foreach($_GET as $key => $value) {
if(strpos($key, 'cnf_')===0) {
$type = 'confirm';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
if(strpos($key, 'err_')===0) {
$type = 'error';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
}
}
The approach is not correct, it seems that only one message should occur at once (there cannot be "deleted completely" and "unable to delete" at once).
Try construct the parameters this way: ?msg=upd&msgType=cnf
function display(){
if (isset($_GET['msg']) && isset($_GET['msgType']))
{
$messages = array('cnf_upd'=>'The update was successful!',
'err_upd'=>'The update failed!',
'cnf_del'=>'The deletion was successful!',
'cnf_upd'=>'The deletion failed!',
);
if (isset($messages[$_GET['msgType'].'_'.$_GET['msg']))
construct_the_div($messages[$_GET['msgType'].'_'.$_GET['msg']], htmlspecialchars($_GET['msgType']));
}
there is still much to improve, but for start this is cleaner and safer.
I'm going to propose a different solution. Instead of setting different parameters in $_GET based on the message to be sent, set one parameter and parse its value.
// Start by setting integer constants:
define(CNF_UPD, 1);
define(ERR_UPD, 2);
define(CNF_DEL, 3);
define(ERR_DEL, 4);
Then when you set the value un $_GET, use the constant:
// Build the URL with a deletion error...
header("Location: http://example.com/script.php?msg=" . ERR_DEL);
Finally, use a switch to parse them
if (isset($_GET['msg'])) {
switch ($_GET['msg']) {
case CNF_UPD:
// Updated...
break;
case ERR_UPD:
// failed...
break;
// etc...
default:
// invalid code.
}
}
If you use a pattern of confirm/error/confirm/error for your integer constants, you can determine which it is by taking $_GET['msg'] % 2. Odd numbers are confirmations, evens are errors. There are of course many other ways you could lay this out, I just happen to have typed them in the alternating order you used. You could also do positive integers for confirmations and negatives for errors, for example.
$type = $_GET['msg'] % 2 == 1 ? $confirm : $error;
This is easily expanded to use multiple messages as well. Since they are integer values, you can safely construct a comma-separated list and explode() them when received.
$messages = implode(array(ERR_DEL,CNF_UPD));
header("Location: http://example.com/script.php?msg=$messages");
Unless you can somehow generate $value and $type based on the $_GET parameter (which I can't see how you would do), you could do something like:
$messages = array();
$messages[] = array('id' => 'cnf_upd', 'value' => 'The update was successful!', 'type' => 'Confirm');
$messages[] = array('id' => 'err_upd', 'value' => 'The Update failed.', 'type' => 'error');
...
foreach ($messages as $message) {
if(isset($_GET[$message['id']]) && $_GET[$message['id']] == '1'){
construct_the_div($message['value'], $message['type']);
}
}