How to exit if statement and continue to else - php

This is a long shot question, but is there a way in php to exit an "if" statement and continue on to the "else" statement if an error occurs inside the if block?
example
if ($condition == "good")
{
//do method one
//error occurs during method one, need to exit and continue to else
}
else
{
//do method two
}
Of course it is possible to do a nested if inside the first if, but that seems hacky.
TIA

try {
//do method one
//error occurs during method one, need to exit and continue to else
if ($condition != "good") {
throw new Exception('foo');
}
} catch (Exception $e) {
//do method two
}

I would just use a function so you don't duplicate code:
if ($condition == "good") {
//do method one
//error occurs during method one
if($error == true) {
elsefunction();
}
} else {
elsefunction();
}
function elsefunction() {
//else code here
}

Should that be possible?
Anyway you might consider changing it to.
$error = "";
if ($condition == "good") {
if (/*errorhappens*/) { $error = "somerror"; }
}
if (($condition != "good") || ($error != "") ) {
//dostuff
}

You could modify methodOne() such that it returns true on success and false on error:
if($condition == "good" && methodOne()){
// Both $condition == "good" and methodOne() returned true
}else{
// Either $condition != "good" or methodOne() returned false
}

Assuming that methodOne returns false on error :
if !($condition == "good" && methodOne())
{
//do method two
}

you really need this? i think no... but you can hack..
do{
$repeat = false;
if ($condition == "good")
{
//do method one
$condition = "bad";
$repeat = true;
}
else
{
//do method two
}
}while( $ok ) ;
I advise on methods to separate...

I find using switches instead of if...else are handy for doing this: Omitting a break statement makes the switch fall through to the next case:
switch ($condition) {
case 'good':
try {
// method to handle good case.
break;
}
catch (Exception $e) {
// method to handle exception
// No break, so switch continues to default case.
}
default:
// 'else' method
// got here if condition wasn't good, or good method failed.
}

if ($condition == "good") {
try{
method_1();
}
catch(Exception $e){
method_2();
}
}
else {
method_2();
}
function method_2(){
//some statement
}

Related

How to check my statement but like individually if it is coded as one

This is a function i am currently using for registering of user account in php.
function checkpost($input, $mandatory, $pattern) {
$inputvalue=$_POST[$input];
if (empty($inputvalue)) {
printmessage("$input field is empty");
if ($mandatory) return false;
else printmessage("but $input is not mandatory");
}
if (strlen($pattern) > 0) { //Checks for Input Validation
$ismatch=preg_match($pattern,$inputvalue);
if (!$ismatch || $ismatch==0) { // If is not match or is match = 0
printmessage("$input field wrong format <br>");
if ($mandatory) return false;
// header("location: registerform.php");
}
}
return true;
}
$checkall=true;
$checkall=$checkall && checkpost("name",true,""); //Mandatory
$checkall=$checkall && checkpost("email",true,"/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i");
$checkall=$checkall && checkpost("password",true,"/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{8,}$/");
$checkall=$checkall && checkpost("nric",true,""); //Mandatory
$checkall=$checkall && checkpost("mobile",true,"");
$checkall=$checkall && checkpost("address",true,"");
I tried doing this way of method to check for the statement I have about but I am unsure how can i check like individually like email, password,nric. Is there something wrong with my ifelse cause when I do
// if (!$checkall) { The default error
// printmessage("Error checking inputs<br>Please return to the registration form");
// die();
// }
This will work but I want to check each individual field and print it out. Please help me I'm struggling right now
This is the one I tried but the regex statement suddenly does not work and it will print out the wrong echo statement even if the email format is correct. Seeking help please help me thank you in advance
if (!$checkall=$checkall && checkpost("email",true,"/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i")) {
echo "Invalid email";
die();
}
elseif (!$checkall && checkpost("password",true,"")) {
echo "Invalid password";
die();
}
You could reorder your code for some prettier logic by wrapping the validation into a try/catch block. This will validate each entry, but throw an exception on the first error. When one happens the helper variable $hasErrors is set to true. So you know after validation if any one failed or not.
$hasErrors = false;
try {
if (!checkpost("name", true, "")) throw new Exception("Name is missing");
if (!checkpost("email", true, "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i")) throw new Exception("Wrong email format");
if (!checkpost("password", true, "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{8,}$/")) throw new Exception("Password insecure");
if (!checkpost("nric", true, "")) throw new Exception("Nric?");;
if (!checkpost("mobile", true, "")) throw new Exception("Mobile missing");
if (!checkpost("address", true, "")) throw new Exception("Address missing");
} catch (Exception $e) {
$hasErrors = true;
echo "Error: " . $e->getMessage();
}
if (!$hasErrors) {
echo "Success";
}
Note: You don't need the message for exception at all or print it! I've added it for demonstration purpose.

If statement inside another one is false, return to the else of original if statement

Is there any way in PHP to return at else of first statement, if the second statement which is inside of first, is false
if($first == true) {
//other code which is not necessary to mention here!
if($second == true){
// do smth
}
else{
return to the else of $first statement
}
//other code which is not necessary to mention here!
}
else{
//do smth else
}
Yes, there are multiple ways. For starters, just combine both the statements and give another condition:
if ($first == true && $second == true) {
// do smth
} elseif ($first == true && $second == false) {
// else of$first statement
} else {
//do smth else
}
This can be used as a guidance to get an idea to start. But if you can get a real world example, there can be conditions grouped, tailored to your requirement.
While there is no native way to jump to outer elses from an inner else, but you can set a flag for later processing:
$do_else = false;
if($first == true) {
//other code which is not necessary to mention here!
if($second == true){
// do smth
}
else{
$do_else = true;
}
//other code which is not necessary to mention here!
}
else{
$do_else = true;
//do smth else
}
if($do_else){
//do smth else
}
If the answers above doesn t help you in the real situation, you can create a function for execute in 'else' statements to avoid code duplication

PHP ternary operators

I have written a ternary function in PHP and it seems to work, although I am not sure if it is correct, can someone take a look and tell me if it is right?
I have added the ternary and the if of what should be happening.
//Foreach Loop
foreach ($post as $item) {
//If of what should occur
if ($passed == true) {
if (is_numeric($item)) {
if ($item > 0) {
$passed = true;
}
else {
$passed = false;
}
}
else {
if ($item != "") {
$passed = true;
}
else {
$passed = false;
}
}
//Ternary operator.
$passed = (is_numeric($item) ? ($item > 0 ? true : false) : ($item != "" ? true : false));
}
else {
return $passed;
}
}
please have a look on corrected code
$passed = (is_numeric($item))?($item>0?true:false):($item !="" ? true:false);
Honestly I do not really understand why you do not use a
if (!empty($item)) {
$passed = true;
} else {
return false;
}
In any case, ternaries are less readable than if /elseif / else, they are also slower (note that it is not an universal truth but a more general use case thing http://fabien.potencier.org/the-php-ternary-operator-fast-or-not.html).
I would recommend, if you really need all these if and elses to keep them rather than using ternaries (for readability's purpose).

PHP Catch Error

I need to be able to catch an error. I have the following code
if($call['status_id'] != '' && $call['datetime_required'] != '')
{
//do stuff
}
else
{
// tell them how it failed
}
How would I go about displaying the section on which ti failed. So for example I can return a dynamic error message ie
return 'You did not fill in the field $errorField';
Where
$errorField
Is the if check on which it failed.
UPDATE
I currently code like so
if($call['status_id'] != '')
{
if ($call['datetime_required'] != '')
{
//do stuff
}
else
{
// tell them it failed due to the second condition
}
}
else
{
// tell them it failed due to the first condition
}
But would like to do the check in one line and change the message depending on where ti failed.
Note #jack had already posted his answer before this update.
I'm not sure I fully understand you, you mean something like this?
function check($call, $req_fields) {
$failed = array();
foreach($req_fields as $field) {
if(!$call[$field]) {
$failed[] = $field;
}
}
if(count($failed)) {
return join(', ', $failed) . ' are required.';
}
return 'success?' ;
}
$message = check($call, array('status_id', 'datetime_required'));
if($call['status_id'] != '')
{
if ($call['datetime_required'] != '')
//do stuff
}
else
{
// tell them it failed due to the second condition
}
}
else
{
// tell them it failed due to the first condition
}

PHP multiple if / elseif and error messaging / handling best practices

This is a problem I come accross fairly regularly and I've never found / figured out a best practices situation. Exceptions are probably the way to go however the application I'm working makes no use of them so I'm trying to stick to the currently used methods.
What is the best way to lay out if statements, returns, messages etc. in the event that 3, 4, 5 or more different conditions are required to be checked and either an error message is set or the processing continues. Is it best practice to have all error checking physically at the start of the code?
Here's an example with some real-world type conditions.
function process($objectId,$userId,$newData)
{
$error = '';
if(($object = $this->getObject($objectId)) && $object->userOwnsObject($userId))
{
if($this->isValid($newData))
{
if($object->isWriteable())
{
if($object->write($newData))
{
// No error. Success!
}
else
{
$error = 'Unable to write object';
}
}
else
{
$error = 'Object not writeable';
}
}
else
{
$error = 'Data invalid';
}
}
else
{
$error = 'Object invalid';
}
return $error;
}
OR
function process($objectId,$userId,$newData)
{
$error = '';
if((!$object = $this->getObject($objectId)) && !$object->userOwnsObject($userId))
{
$error = 'Object invalid';
}
elseif(!$this->isValid($newData))
{
$error = 'Data invalid';
}
elseif(!$object->isWriteable())
{
$error = 'Object not writeable';
}
elseif(!$object->write($newData))
{
$error = 'Unable to write to object';
}
else
{
// Success!
}
return $error;
}
It's clear to me that in this case option 2 is the way to go. It's much clearer. Now, we can make it a bit more complex:
function process($objectId,$userId,$newData)
{
$error = '';
if(($object = $this->getObject($objectId)) && $object->userOwnsObject($userId))
{
$this->setValidationRules();
$parent = $object->getParentObject();
$parent->prepareForChildUpdate();
if($this->isValid($newData,$parent))
{
$newData = $this->preProcessData($newData);
if($object->isWriteable())
{
// doServerIntensiveProcess() has no return value and must be done between these two steps
$this->doServerIntensiveProcess();
if($object->write($newData))
{
// No error. Success!
$parent->childUpdated();
}
else
{
$error = 'Unable to write object';
}
}
else
{
$error = 'Object not writeable';
}
}
else
{
$error = 'Data invalid';
}
}
else
{
$error = 'Object invalid';
}
return $error;
}
OR this which has some issues with it
function process($objectId,$userId,$newData)
{
$error = '';
if((!$object = $this->getObject($objectId)) && !$object->userOwnsObject($userId))
{
$error = 'Object invalid';
}
// Is it wrong to hate multi-line conditionals?
elseif(!$this->setValidationRules() || (!$parent = $object->getParentObject()) ||
!$parent->prepareForChildUpdate() || !$this->isValid($newData,$parent))
{
$error = 'Data invalid';
}
elseif((!$newData = $this->preProcessData($newData)) || !$object->isWriteable())
{
$error = 'Object not writeable';
}
// Where does doServerIntensiveProcess() with no return value go??
elseif(!$object->write($newData))
{
$error = 'Unable to write to object';
}
else
{
// Success!
$parent->childUpdated();
}
return $error;
}
I'm just not sure of the best way to handle this nested if-this-then-do-that-then-if-this-then-do-that kind of functionality. Thank you indvance for any insight you can provide!
What I tend to do to keep code clean is like so:
function process($objectId,$userId,$newData)
{
$object = $this->getObject($objectId);
if($object === false)
{
return "message";
}
if($object->userOwnsObject($userId) === false)
{
return "message";
}
if($this->setValidationRules() === false)
{
return "unable to set validation rules";
}
if(false !== ($parent = $object->getParentObject()))
{
return "unable to get parent object";
}
/*... etc ...*/
//if your here the all the checks above passed.
}
by doing it this way your also saving resources as your your directly returning in place, the code looks cleaner and no need for 2 many nests
but if your building the function from scratch I don't see why you cant use exceptions in in your new code, it will not interfere with the current app, and makes live simpler
function process($objectId,$userId,$newData)
{
if(false !== ($parent = $object->getParentObject()))
{
throw Exception("unable to get parent object");
}
/*... etc ...*/
}
and
try
{
$this->process(....);
}
catch(Exception $e)
{
show_error_page('invalid.php',$e);
}
or another way is to create an error handling class with a static method called InternalError like so
abstract class Error
{
public static InternalError(Exception $Ex)
{
Logger::LogException($Ex);
//Then flush all buffers and show internal error,
}
}
so instead of of the show_error_page above you can do:
try
{
$this->process(....);
}
catch(Exception $e)
{
Error::InternalError($e); //this provides user with an interface to report the error that has just been logged.
}
this way all your Exception(s) are logged and can be viewed within your administration system, meaning you can track errors faster and not rely on members to visibly see errors, but get a nice apology with an email form asking them to describe what they was trying to do, the error ID will be attached to the form, so you can trace the user to the error.
That's the best form of error handling IMO.
What about this?
function process($objectId,$userId,$newData)
{
if((!$object = $this->getObject($objectId)) && !$object->userOwnsObject($userId))
return 'Object invalid';
elseif(!$this->isValid($newData))
return 'Data invalid';
elseif(!$object->isWriteable())
return 'Object not writeable';
elseif(!$object->write($newData))
return 'Unable to write to object';
// Success!
}
For the more complex example::
function process($objectId,$userId,$newData)
{
if(!($object = $this->getObject($objectId)) || !$object->userOwnsObject($userId))
return 'Object invalid';
$this->setValidationRules();
$parent = $object->getParentObject();
$parent->prepareForChildUpdate();
if(!$this->isValid($newData,$parent))
return 'Data Invalid';
$newData = $this->preProcessData($newData);
if(!$object->isWriteable())
return 'Object not writable';
// doServerIntensiveProcess() has no return value and must be done between these two steps
$this->doServerIntensiveProcess();
if(!$object->write($newData))
return 'Unable to write object';
// No error. Success!
$parent->childUpdated();
return '';
}
I would completely omit
if($object->isWriteable())
{
if($object->write($newData))
{
// ..
}
}
And throw Exceptions when calling object-write() (without a return value) instead. Same for the other examples
if ($something->isValid($data)) {
$op->doSomething($data); // throws XyException on error
}
If you really want to use such constructs, you can also use the swtch-Statement
switch (true) {
case !$something->isValid($data):
$errors = "error";
break;
// and so an
}
But I really recommend Exceptions.
I don't think it is wrong per se to write multi-line conditionals, but you can make it more readable by putting conditions into a variable and use that in your if-statment. I think the elseif constuct is better.

Categories