OriginalMacBabe Posted September 16, 2010 Share Posted September 16, 2010 Please bear with me in the following exercise. I'm fairly new to php (but not coding) and am trying to push my skills for the future, so I'm going beyond a problem for which I already have a solution to see if I understand the coding principles correctly. I am trying to understand just how far I can push the ternary operator shorthand. I know how to do simple tasks, but I'm wondering if I can perform more than one command in the same statement? I'm a little confused because I'd like to both set a session variable and do a page redirect and I have a feeling that the order of these operations matters, so all I've done here may be incorrect. I have a form on the front page of my site that includes a checkbox that is required in order to enter the site. The form action goes to a page where this is checked, a $_SESSION variable is set, and the page is redirected. I am also not sure if I need the session_write_close(); command, or if it is in the right place. In the full length version, it could be moved into the set of commands following the IF. Here is the full length code that I would like to translate into shorthand: <?php session_start(); if (isset($_POST['ConsentCheckbox']) { $_SESSION['Consented'] = 'true'; header('Location: http://www.mySite/welcome'); } else { header('Location: http://www.mySite/errors/NotConsented'); } session_write_close(); ?> The if/else conditions translate easily into these two lines of code, which could be one line if I didn't also need to set the session variable: <?php session_start(); $_SESSION['Consented'] = isset($_POST['ConsentCheckbox']) ? 'true' : 'false'; header('Location: http://mySite.com/'.($_SESSION['Consented'] ? 'welcome' : 'error/NotConsented')); session_write_close(); ?> But, I really only need to set the $_SESSION variable if the $_POST['ConsentCheckbox'] is set. This makes the test on the following pages of my site much simpler (where I test to see if the $_SESSION variable is set and then either redirect to the consent form or load the desired page). SO, I'm wondering if it can be further condensed. I've come up with these possibilities, but am not totally sure. This has now become a theoretical exercise in coding for me. Here is what I think is possible, but I have a couple of outstanding questions, so I'd like some input, please. I first translated it into the following. I think this is correct, although I'm not sure if I need brackets around the multiple commands in the TRUE section. <?php session_start(); isset($_POST['ConsentCheckbox']) ? $_SESSION['Consented']='true'; header('Location: http://www.mySite.com/welcome') : header('Location: http://www.mySite/errors/NotConsented'); session_write_close(); ?> Then, I wondered if I can even further condense it in the following way? Here is where the order of the commands is likely to break the code - and I'm not entirely sure that my use of double quotes will suffice instead of escaping out the end bracket of the header() command: <?php session_start(); header('Location: http://www.mySite.com/'.(isset($_Post['ConsentCheckbox']) ? "welcome')"; $_SESSION['Consented'] = 'true' : "errors/NotConsented')"); session_write_close(); ?> Have I gone too far? Thanks Quote Link to comment Share on other sites More sharing options...
Psycho Posted September 16, 2010 Share Posted September 16, 2010 Have I gone too far? Probably, LOL. The second to last code block above is probably the best way to achieve what you want using the ternary operator. But, here is my two cents... I love using the ternary operator - especially for setting a variable to one of two values based on a condition. But, I only use it when it will help simplify my code. In the above, I feel, that by trying to condense the code down you are reducing the readability of the code. That will make the code more difficult to read/review/debug/etc. But, I really only need to set the $_SESSION variable if the $_POST['ConsentCheckbox'] is set. This makes the test on the following pages of my site much simpler (where I test to see if the $_SESSION variable is set ... Then why set the value to the string value of 'true'. Personally, I would set the value to the boolean true and do a test such as if($_SESSION['ConsentCheckbox']===true) That makes more sense to someone reading the code than just using isset() since that person might not know that just being set is the determination as to whether the user actually accepted. To put it another way, I am all for simplification but not at the expense of clarity. Quote Link to comment Share on other sites More sharing options...
OriginalMacBabe Posted September 16, 2010 Author Share Posted September 16, 2010 Thank you for that. I, too, realize that the last version was extreme, but as I said, it had become a theoretical exercise by that point - the ternary operator is such an elegant solution. Despite the readability issue, did I actually get the code right? Would it work? Moving along to the practical, I also think the second last version is more readable, I just wasn't sure I could put the two commands into the statement. Because the form consists only of the single checkbox and the submit button, if it is not checked, it is not set (as far as I understand). Thus, I thought using isset would be the most efficient test. In the first condensed version, the first line could reasonably be changed (and shortened) to obtain a boolean result: $_SESSION['Consented'] = isset($_POST['ConsentCheckbox']); Sticking with the second condensed (second last) version, am I reading you correctly when you say I should remove the quotes from the assignment and change it to this (remembering that this code represents the form's action)? <?php session_start(); isset($_POST['ConsentCheckbox']) ? $_SESSION['Consented']=true; header('Location: http://www.mySite.com/welcome') : header('Location: http://www.mySite/errors/NotConsented'); session_write_close(); ?> And follow up with this simple test at the top of subsequent pages on the site (actually a template): <?php session start(); if($_SESSION['Consented'] !=== true) header('Location: http://mySite.com'); ?> Thanx Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted September 17, 2010 Share Posted September 17, 2010 isset($_POST['ConsentCheckbox']) ? $_SESSION['Consented']=true; header('Location: http://www.mySite.com/welcome') : Syntax error at the first semi-colon. Quote Link to comment Share on other sites More sharing options...
OriginalMacBabe Posted September 17, 2010 Author Share Posted September 17, 2010 Well, that was the question. Are you suggesting that I cannot put both commands (setting the session variable and then declaring the header) into the statement? Or, do they need to be placed inside a bracket? Or, is there no way to achieve this in one statement? Quote Link to comment Share on other sites More sharing options...
rwwd Posted September 17, 2010 Share Posted September 17, 2010 Hi all, May I make a suggestion here:- <?php session_start(); $_SESSION['Consented'] = ((isset($_POST['ConsentCheckbox']) && !empty($_POST['ConsentCheckbox']))) ? 'true' : 'false'); header('Location: http://mySite.com/'.(isset($_SESSION['Consented']) ? 'welcome' : 'error/NotConsented')); session_write_close(); ?> Though instead of checking then setting to true or false, it would be easier to set as a bool. I have just put the empty function there purely to check to see if the $_POST has been set correctly and to see if it contains a value, I find this to be helpful in checking to see if the form has been completed in the correct manor, instead of MR S.Bot filling the form in.. Rw Quote Link to comment Share on other sites More sharing options...
OriginalMacBabe Posted September 17, 2010 Author Share Posted September 17, 2010 Ok. So back to the first iteration. Yes, clearly, the boolean option is a better choice. And, I'm getting the message that I cannot reduce the process to a single ternary operation, although no one has explicitly answered this question. @rwwd: I agree that checking to see if the form has been properly submitted is generally a good idea, but I thought that since the only item in the form is the checkbox and the form's action consists entirely of the code discussed here (i.e., there is nothing that might be of advantage to a bot) that in this case the test was superfluous. However, your comment does leave me a bit confused. I thought that if the checkbox had not been checked it would not be set. So what is the difference between the variable being set and it being empty? Quote Link to comment Share on other sites More sharing options...
Psycho Posted September 17, 2010 Share Posted September 17, 2010 Thank you for that. I, too, realize that the last version was extreme, ... did I actually get the code right? Would it work? No, it would not. Despite the syntax error roopurt18 pointed out you can't do a redirect and then set a session variable. Once the redirect occurs, all subsequent code is not executed. Because the form consists only of the single checkbox and the submit button, if it is not checked, it is not set (as far as I understand). Thus, I thought using isset would be the most efficient test. My response was specifically about how you check if the value is set on subsequent pages using the session variable. If you have made a determination as to whether the checkbox was set or not, you should set the session variable to either true/false instead of relying upon isset() of the session variable. This is just good coding practice. This would make sense to anyone reading the code as to what the condition being checked is for if($_SESSION['ConsentCheckbox']===true) This could be easily misinterpreted if(isset($_SESSION['ConsentCheckbox'])) ... I'm getting the message that I cannot reduce the process to a single ternary operation, although no one has explicitly answered this question. I already stated that the 2nd to last example you posted should work. You state this is a "theoretical exercise", but I would counter this is a useless exercise. Just because something can be done doesn't mean it should be done. I could probably reduce an entire page of code to a long combination of nested ternary operators. So what? What would be the benefit in doing so? Quote Link to comment Share on other sites More sharing options...
rwwd Posted September 17, 2010 Share Posted September 17, 2010 And, I'm getting the message that I cannot reduce the process to a single ternary operation, although no one has explicitly answered this question. Short answer; no you can't, I see two DISTINCT operations; $_SESSION assignment & header() call, so because the logic is to have two actions depending on how something is set, this results in two separate statements, with the second excerpt of code, this has been condensed into the most efficient way possible, other than that I don't know what to suggest. However, your comment does leave me a bit confused. I thought that if the checkbox had not been checked it would not be set. So what is the difference between the variable being set and it being empty? I just do that by force of habit There is a huge difference between isset() and empty() This is the best way to check to see if something has been correctly access and not done through a bot or something like that, it is quite easy to circumnavigate a form.. I'm just thinking purely for security, and there is a difference from (x)html and html in the way that you set a check box, I think that with xhtml you need to explicitly set is as 'selected', though I may have that backwards.. Hope that explains that for you anyway, Rw Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted September 17, 2010 Share Posted September 17, 2010 No' date=' it would not. Despite the syntax error roopurt18 pointed out you can't do a redirect and then set a session variable. Once the redirect occurs, all subsequent code is not executed.[/quote'] The subsequent code will execute in this case. All he did was call header and set the location; the subsequent call was not to exit() so the session assignment will occur. On a side note, if you order things carefully you can probably perform a session assignment and header() call in the same piece of a ternary operator. <?php echo (true ? ($_SESSION['foo'] = 'xyz' && false) || (header( 'Location: http://www.mydomain.com' ) && false) || exit() : 'false condition met'); ?> However you'll probably agree that this does nothing to help with readability and maintainability of the code. Quote Link to comment Share on other sites More sharing options...
Psycho Posted September 17, 2010 Share Posted September 17, 2010 No' date=' it would not. Despite the syntax error roopurt18 pointed out you can't do a redirect and then set a session variable. Once the redirect occurs, all subsequent code is not executed.[/quote'] The subsequent code will execute in this case. All he did was call header and set the location; the subsequent call was not to exit() so the session assignment will occur. Hmm... I always thought that execution on the current page stopped when a header redirect was encountered. I always used exit() only for "completeness" of the code. I did some testing and setting a session variable after the redirect seems to work. But, any variable setting or output statements (e.g. echo) after a redirect have no effect on the output to the user. Good to know. Could do some interesting things with that. Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted September 17, 2010 Share Posted September 17, 2010 I would imagine that most browsers, even if receiving a Location header, would wait until the end of the response from the server to redirect. For example, let's say that an implicit flush and no output buffering was enabled on the server. Then every single echo or header request would immediately be sent to the browser. If the script was intending to first set the location and then add a cookie and the browser immediately redirected after receiving location, the cookie would not be set. I always have my scripts output everything at once at the end and my best practice is to do all my processing and make the following my last two lines of code I want executed: header( 'Location: http://somewhere' );exit(); Quote Link to comment Share on other sites More sharing options...
OriginalMacBabe Posted September 18, 2010 Author Share Posted September 18, 2010 My response was specifically about how you check if the value is set on subsequent pages using the session variable. If you have made a determination as to whether the checkbox was set or not, you should set the session variable to either true/false instead of relying upon isset() of the session variable. This is just good coding practice. Yes, thank you. That is exactly how I read it. I already stated that the 2nd to last example you posted should work. You state this is a "theoretical exercise", but I would counter this is a useless exercise. I disagree. In learning how to code, I find it useful to understand the limits. It doesn't mean I would necessarily use it in its extreme iterations. Nonetheless, practicing the application of correct syntax options is never a "useless exercise" IMHO, and is particularly useful for facilitating/avoiding future debugging. Those slips of semicolons, for example, are often pretty hard to spot, especially when one's understanding of where they are/not supposed to be used is insufficiently comprehensive. On a side note, if you order things carefully you can probably perform a session assignment and header() call in the same piece of a ternary operator. ... However you'll probably agree that this does nothing to help with readability and maintainability of the code. Thank you for the explanation of isset() and empty(). I will implement as suggested. It'll take me a bit to decipher the example you provided - proving your point exactly. I did some testing and setting a session variable after the redirect seems to work. But, any variable setting or output statements (e.g. echo) after a redirect have no effect on the output to the user. So in this particular application, it would be fine since the session variable will only be evaluated on subsequent page calls. That is good to know. But, are you saying that for best practice, I should add exit() after the session_write_close()? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.