I have an old script that uses the variable $action and then the switch statement. My problem is that in PHP 5. 7 I must declare the variable before it is used - so what do I declare the value to be for a variable that switches?
if(isset($pwd) && ($action == "login") &&
($pwd == $admin_password))
{
$admintest = 1;
$cookie_value = base64_encode("jmkads:$pwd");
// 86400 secs is 24 hours
setcookie("jmkads",$cookie_value, time()+86400);
}
else if(isset($jmkads)) {
$cookie_value = base64_decode($jmkads);
$cookie_value = explode(":", $cookie_value);
if(($cookie_value[0] == "jmkads") &&
($cookie_value[1] == $admin_password))
{
$admintest = 1;
}
}
if(!$admintest) {
Login_Page();
exit;
}
$db = connect_to_db();
if($db == 0) {
echo "Unable to connect to database, check if the MySQL".
" server is active and the settings of ad_config.php".
" are correct.\n";
}
else {
switch($action) {
case "add_client":
Page_Header("Add Client");
add_client();
break;
case "add_client2":
Page_Header("Add Client");
insert_client_data();
break;
and so on and so forth (there are many options) - I just wanted to show enough of the script so it was clear.
In your case, that variable would be declared as a string since your cases are matching strings.
Related
I made the script to do what is expected, so it work ok but there must be a more elegant way to achieve the same result. I know that using switch will make it look nicer but not sure if the result will be the same as the 'default:' behavior:
This is the section of the script i want to refactor:
foreach ($free_slots as $val) { // here i am looping through some time slots
$slot_out = $free_slots[$x][1];
$slot_in = $free_slots[$x][0];
$slot_hours = $slot_out - $slot_in;
// tasks
if ($slot_out != '00:00:00') {
// Here i call a function that do a mysql query and
// return the user active tasks
$result = tasks($deadline,$user);
$row_task = mysql_fetch_array($result);
// HERE IS THE UGLY PART <<<<<----------------
// the array will return a list of tasks where this current
// users involved, in some cases it may show active tasks
// for other users as the same task may be divided between
// users, like i start the task and you continue it, so for
// the records, user 1 and 2 are involved in the same task.
// The elseif conditions are to extract the info related
// to the current $user so if no condition apply i need
// to change function to return only unnasigned tasks.
// so the i need the first section of the elseif with the
// same conditions of the second section, that is where i
// actually take actions, just to be able to change of
// change of function in case no condition apply and insert
// tasks that are unassigned.
if ($row_task['condition1'] == 1 && etc...) {
} else if ($row_task['condition2'] == 1 && etc...) {
} else if ($row_task['condition3'] == 1 && etc...) {
} else if ($row_task['condition4'] == 1 && etc...) {
} else {
// in case no condition found i change function
// and overwrite the variables
$result = tasks($deadline,'');
$row_task = mysql_fetch_array($result);
}
if ($row_task['condition1'] == 1 && etc...) {
// insert into database
} else if ($row_task['condition2'] == 1 && etc...) {
// insert into database
} else if ($row_task['condition3'] == 1 && etc...) {
// insert into database
} else if ($row_task['condition4'] == 1 && etc...) {
} else {
echo 'nothing to insert</br>';
}
}
}
Basically i run the else if block twice just to be able to change of function in case nothing is found in the first loop and be able to allocate records unassigned.
I haven't changed the functionality of your code, but this is definitely a lot cleaner.
The main problem was that your logic for your if/else statements was confused. When you're writing:
if($a == 1){ } else if($b == 1){ } else if($c == 1){ }else{ //do something }
You're saying If a is 1 do nothing, if b is 1 do nothing, if c is 1 do nothing, but if all of those did nothing, do something when you can just say if a is not 1 and b is not 1 and c is not 1, do something.
I wasn't too sure on your second if statements, but generally it's not good to have an if else with no body within it. However, if the "insert into database" comment does the same thing, you can merge the 3 if statements that do the same code.
I hope i've cleared a few things up for you.
Here's what I ended up with:
foreach ($free_slots as $val) { // here i am looping through some time slots
$slot_out = $free_slots[$x][1];
$slot_in = $free_slots[$x][0];
$slot_hours = $slot_out - $slot_in;
// tasks
if ($slot_out != '00:00:00') {
$result = tasks($deadline, $user);
$row_task = mysql_fetch_array($result);
if (!($row_task['condition1'] == 1 || $row_task['condition2'] == 1 || $row_task['condition3'] == 1 || $row_task['condition4'] == 1)) {
$result = tasks($deadline,'');
$row_task = mysql_fetch_array($result);
}
if ($row_task['condition1'] == 1 && etc...) {
// insert into database
} else if ($row_task['condition2'] == 1) {
// insert into database
} else if ($row_task['condition3'] == 1) {
// insert into database
} else if ($row_task['condition4'] == 1) {
} else {
echo 'nothing to insert</br>';
}
}
}
I wasn't too sure how to title this question - Here's a snippet of what I'm doing:
<?php
if ($result_rows >= 1 && $membership = 'active') {
if ($when_next_allowed > $today_date) {
$output = 'You cannot renew your membership for another <b>' . $days_left . 'days</b>.';
}
/*
What if the membership is set to active, but it's been over a year since they
activated it? We don't have any server-side functions for determining such
at the time.
*/
else {
/* do database stuff to change the database entry to inactive */
/* skip to elseif below */
}
}
elseif (2 == 2) {
/* create new database entry for user's membership */
}
?>
If the first nested argument is false, it should move onto else which should continue from there and 'escape' the 'parent' if and move onto elseif. Other wise, if the first nested argument is true, then it should stay put.
Is that even a possible occurrence? The only thing I could think of was to add multiple continue; commands. That, of course, threw an error.
One other idea I had was setting a variable to equal continue; within the else, then set that right before the end of the parent if:
if (1 == 1) {
...
else {
$escape = 'continue;';
}
/* $escape here */
}
But I've never heard of, nor do I know of any method of using variables in a 'raw' form like that. Of course I've done research on it, though I've yet to find out how. I'm not sure if that's common knowledge or anything - But I've never heard of, or considered such a thing until now.
Solution? This is something I always thought about, though I never knew I'd have to use it.
Cleanest I could come up with:
$run = false;
if (1 == 1) {
$run = true;
if (1 == 2) {
/* Do something */
} else {
$run = false;
/* Do something else */
}
}
if (!$run && 2 == 2) {
}
Alternatively, you could use a goto between [Do something else] and the 2nd if block, but it'll be messy either way.
if (1 == 1) {
if (1 == 2) {
/* Do something */
} else {
/* Do something else */
goto 1
}
} else if (!$run && 2 == 2) {
1:
}
If I understand the problem correctly, then you could just do something like this:
if (1==1 && 1==2) {
/* ... */
}
elseif (2==2) {
$success = 'Success';
}
Obviously, I don't need to point out that 1==1 && 1==2 is completely illogical and is just used as an example of two boolean statements.
Update based on update to question:
Unless there are additional steps that you are omitting, this replicates your logic. Hard to know if this really solves your problem, because I don't know what 2==2 represents, or what other steps you might need to perform based on what other conditions.
if (($result_rows >= 1 && $membership == 'active') &&
($when_next_allowed > $today_date)) {
$output = 'You cannot renew your membership for another <b>' . $days_left . 'days</b>.';
}
elseif (2 == 2) {
/* create new database entry for user's membership */
}
This should do what you want to do.
If you have a variable to false and switch it to true if you go into the else you want, you just have to test the value of this variable right after to go into elseif you wanted to go in.
<?php
$test = false;
if (1 == 1) {
if (1 == 2) {
/* ... */
}
else {
/* Skip to elseif below */
$test = true;
}
}
if ($test == true) {
$success = 'Success';
}
echo $success;
?>
Not an easy question as it's really hard to understand what you're trying to achieve but I think this is the solution you're looking for.
<?php
$success = False;
if (1 == 1) {
if (1 == 2) {
/* ... */
} else {
$success = True;
/* True case code can go here */
}
}
echo $success;
?>
pseudo code is your friend.
Alternatively;
<?php
$success = False;
if (1 == 1) {
if (1 == 2) {
/* ... */
} else {
$success = True;
}
}
if $success == True {
/* ... */
}
echo $success;
?>
<?php
$continue = false;
if (1 == 1) {
if (1 == 2) {
/* ... */
}
else {
$continue = true;
}
}
if ($continue==true) {
$success = 'Success';
}
echo $success;
?>
I have a method that can return 3 different cases
public function check_verification_status($user_id) {
global $db;
$sql = "SELECT * FROM `users`
WHERE `id` = ".clean($user_id)."
AND `type_id` = 1";
$result = #mysql_query($sql,$db); check_sql(mysql_error(), $sql, 0);
$list = mysql_fetch_array($result);
if ($list['verification_key'] == '' && !$list['verified']) {
//No key or verified
return 0;
} elseif ($list['verification_key'] != '' && !$list['verified']) {
//key exists but not verified = email sent
return 2;
} elseif ($list['verification_key'] != '' && $list['verified']) {
//verified
return 1;
}
}
A form / message is output depending on the return value from this
I would have used bool for return values when comparing 2 cases, what is the proper way of handling more than 2 cases and what would the ideal return value be.
The way i call this:
$v_status = $ver->check_verification_status($user_id);
if ($v_status === 0) {
//do something
} elseif ($v_status === 1) {
//do something else
} elseif ($v_status === 2) {
//do something totally different
}
I want to learn the right way of handling such cases as I run into them often.
note: I know I need to upgrage to mysqli or PDO, its coming soon
What you have is fine, but you can also use a switch statement:
$v_status = $ver->check_verification_status($user_id);
switch ($v_status) {
case 0: {
//do something
break;
}
case 1: {
//do something else
break;
}
case 2: {
//do something totally different
break;
}
}
I am unable to set session for $_SESSION['next'] under switch/case condition, while $_SESSION['user_id'] works perfectly before the condition. The script run into each condition of switch/case condition and redirect without setting $_SESSION['next']. Is there any specific reason why it fails to work? How to solve this?
require_once ('../src/facebook.php');
require_once ('../src/fbconfig.php');
//Facebook Authentication part
$user_id = $facebook->getUser();
if ($user_id <> '0' && $user_id <> '') {
session_start();
$_SESSION['user_id'] = $user_id;
switch((isset($_GET['page']) ? $_GET['page'] : '')){
case 'abc';{
$_SESSION['next'] = 'AAA';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
exit;}
case 'def';{
$_SESSION['next'] = 'BBB';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
exit;}
case 'ghi';{
$_SESSION['next'] = 'CCC';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
exit;}
default;{
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
exit;}
}
} else {
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
exit;
}
Your switch is all wrong. Read the manual and try this:
<?php
switch ((isset($_GET['page']) ? $_GET['page'] : '')){
case 'abc':
$_SESSION['next'] = 'AAA';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
break;
case 'def':
$_SESSION['next'] = 'BBB';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
break;
case 'ghi':
$_SESSION['next'] = 'CCC';
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
break;
default:
echo "<script>top.location.href = 'https://www.example.com/xxx/'</script>";
break;
}
You're using exit in your switch, which (unless you want your script to end at the switch) is a no-no. Instead, you have to use the break keyword.
You also use semicolons and curly braces for each case.
case 'ghi';{ ... }
NO! Proper usage is
case 'ghi':
.
.
.
break;
Update: I just noticed you use this line:
if ($user_id <> '0' && $user_id <> '') { ... }
What is <> doing in PHP code? The "standard" operator for "not equals" is != in PHP. Use it correctly or no one will want to use your code.
Second update: You never set $_SESSION['next'] in your default case. It's very likely that your switch is always going to the default case. This would cause the behavior you're experiencing.
I suggest:
if (($user_id != '0') && ($user_id != ''))
(parentheses, and the != operator)
and also a DRYer switch:
$page = array_key_exists('page', $_GET) ? $_GET['page'] : '';
switch ($page) {
case 'abc':
$next = 'AAA';
$loc = 'https://www.example.com/xxx/';
break;
case 'def':
$next = 'BBB';
$loc = 'https://www.example.com/yyy/';
break;
... // and so on
}
if (isset($next)) {
$_SESSION['next'] = $next;
// If it does not work, you have problems with your session ID, maybe?
}
// I find this syntax easier
print <<<SCRIPT
<script type="text/javascript">
top.location.href = '$loc';
</script>
SCRIPT;
exit();
I'm attempting to optimise the following PHP If/Else statement. Could I rewrite the code to make use to case and switch, or should I leave it as it is, or what?
Code:
if(empty($_GET['id'])){
include('pages/home.php');
}elseif ($_GET['id'] === '13') {
include('pages/servicestatus.php');
}elseif(!empty($_GET['id'])){
$rawdata = fetch_article($db->real_escape_string($_GET['id']));
if(!$rawdata){
$title = "";
$meta['keywords'] = "";
$meta['description'] = "";
}else{
$title = stripslashes($rawdata['title']);
$meta['keywords'] = stripslashes($rawdata['htmlkeywords']);
$meta['description'] = stripslashes($rawdata['htmldesc']);
$subs = stripslashes($rawdata['subs']);
$pagecontent = "<article>" . stripslashes($rawdata['content']) . "</article>";
}
include("includes/header.php");
echo $pagecontent;
if(!$rawdata){
error_404();
}
}
Thanks
I hate switch statements, but its personal preference to be honest. As far as further optimization i'd suggest taking a look at some form of assembly language. It will give you some general ideas on how to make conditional statements more efficient. That is, it will give you a different out look on things.
if(!empty($_GET['id']))
{
if($_GET['id'] == '13')
{
include('pages/servicestatus.php');
}
else
{
$rawdata = fetch_article($db->real_escape_string($_GET['id']));
if (!$rawdata) {
$title = "";
$meta['keywords'] = "";
$meta['description'] = "";
} else {
$title = stripslashes($rawdata['title']);
$meta['keywords'] = stripslashes($rawdata['htmlkeywords']);
$meta['description'] = stripslashes($rawdata['htmldesc']);
$subs = stripslashes($rawdata['subs']);
$pagecontent = "<article>" . stripslashes($rawdata['content']) . "</article>";
}
include("includes/header.php");
echo $pagecontent;
if (!$rawdata) {
error_404();
}
}
}
else
{
include('pages/home.php');
}
switch would be appropriate if you had several discrete values for $_GET['id'] that you were checking for.
One suggestion I can make for the sake of readability is that
} elseif (!empty($_GET['id'])) {
only needs to be
} else {
Well i don't think it's necessary to switch to a swith
but you could change
} elseif (!empty($_GET['id'])) {
to just
}else{
You may want to look into breaking up your code into a MVC form; that would make it much easier to maintain your code. At least put the last clause into another file, probably called default.php and include it. Also, you might create an array of id => file key/value sets, lookup the id, and include the file.
if (isset($_GET['id'])) {
$pages = array(
0 => 'home.php',
13 => 'servicestatus.php'
);
if (isset($pages[$_GET['id']])) {
include('pages/' . $pages[$_GET['id']]);
} else {
include('pages/default.php');
}
}
Yes, switch is evaluate once, is efficient than if elseif,
and is easier to maintain with this given structure
switch ($_GET['id'])
{
case 13: ... break;
case 0 : ... break;
default: ... break;
}
I dont know, if you should, or should not, but here I wouldnt. The main reason is, that there is at least one statement, you can omit, and then, you will have just a if-elseif-else-Statement
if (empty($_GET['id'])) { /* code */ }
elseif ($_GET['id'] === '13') { /* code */ }
elseif (!empty($_GET['id'])) { /* code* }
is the same as
if (empty($_GET['id'])) { /* code */ }
elseif ($_GET['id'] === '13') { /* code */ }
else { /* code* }
In the block after that, the statement if(!$rawdata) is also duplicated.