I keep getting
Notice: Undefined index: action
When I use the following code. I use it to see which page is required. Anyway to sort this out? I know you're not supposed to just include files from user input (without checking the input first), but this switch statement only works if action is set to view or blah, otherwise it just shows the main page.
?action=view or ?action=blah
switch ($_GET['action'])
{
case 'view':
echo "We are in view";
require FORUM_ROOT . 'view2.php';
break;
case 'blah':
echo "We are in blah";
break;
default:
"This is default";
require FORUM_ROOT . 'main.php';
}
Rewrite your code in this way:
$action = isset($_GET['action']) ? $_GET['action'] : null;
switch ($action) { ... }
The error means that you are attempting to use $_GET['action'] when it doesn't exist. Like for instance, when you go to the page without passing page.html?action=xxx
You're using an array element without checking whether it exists. You should make sure that your code does not try to read $_GET['action'] when that might not be defined.
You can do this in a way that doesn't require altering your switch logic, by giving $_GET['action'] a defined (but "empty") value if action wasn't given in the query string:
if (!isset($_GET['action']))
$_GET['action'] = null;
switch ($_GET['action']) {
...
}
There is a specific syntax construct # for ignoring notices when they are provably redundant.
switch (#$_GET['action']) {
The isset ternary is used as microoptimization workaround, but otherwise has no practical benefit in your case.
Related
Correct me if I'm wrong. I saw many people write condition header as this format.
if(isset($var) && $var!=""){}
Basically it just checking if $var isn't null value right? In my understanding this would be enough.
if($var){}
Am I missing something? Did my method unreliable? My colleague already pointed out that I should use the first one. Sometime I just lazy to write so I just want to make it simple.
They are not the same thing.
if (expr) is evaluated with these rules -> http://php.net/manual/en/types.comparisons.php#types.comparisons
<?php
$var = "0";
if (isset($var) && $var != "") {
echo "first block\n";
}
if ($var) {
echo "second block\n";
}
Example
Suppose $var is "0", then it is definitely isset, and not equal to an empty string, but fails the if ($var) test.
php
if($var){}
will check if $var is true. In this scenario, if $var is used for first time in condition, notice will be generated that you are trying to use undefined variable.
The isset () function is used to check whether a variable is set or not. If variable is not set, possibly it will enter to the else condition.
In your case if $var is not available, Possibly you will hit by this error Undefined variable: var. So checking isset is always good for your code.
Case 1:
if($var){
echo 'pass';
}else{
echo 'fail';
}
Output:Notice: Undefined variable: var in E:\siva\htdocs\test.php on line 48
fail
Case 2:
if(isset($var)){
echo 'pass';
}else{
echo 'fail';
}
Output : fail
Case 3:
$var = '';
if($var){
echo 'pass';
}else{
echo 'fail';
}
Output :Fail
In this case 3 is more interesting, If you failed to use isset, Defined the variable as null, So you will not get the error
I can't understand that if sentence. Why can't I just check if $view is set? 2 more questions -What does "$_GET("$view")!" "!" sign mean there? What does ! change? Moreover, why does it equal = " "?
<?php
$myurl=htmlspecialchars($_SERVER["PHP_SELF"]);
$view="";
if(isset($_GET["$view"]) && $_GET("$view")! = "") { $view =$_GET["$view"];};
include(head.html);
switch($view] {
case "" :
include(main.html);
break;
case "people" :
include(people.html);
break;
case:"contact":
include(contact.html);
break;
default :
include(404.html);
break;
};
include_once(foot.html;
?>
Thanks for all the help
I think you messed up your code. This will not execute, due to numerous errors. The if statement is probably
if(isset($_GET[$view]) && $_GET[$view] != "")
Ie, first check that the $view key exists, then check that key it is not empty. Note the difference between a key that does not exist, and a key that exist but is empty, and why you check for both in this case.
Why can't I just check if $view is set?
Because apparently the author of that code didn't want the empty string to be valid. This will be the case if, say, there is a field called $view and the user does not put anything in it.
Actually, you could do that, since $view is initialized to the empty string anyway! This code was probably copy/pasted or written by a novice.
What does ! change?
It's actually !=, written in a confusing way. These two are the same:
&& $_GET("$view")! = "")
&& $_GET("$view") != "")
Also, your code has a bug. $_GET("$view") is not valid, the () should be []. So, here is the corrected and readable code:
if (isset($_GET["$view"]) && $_GET["$view"] != "") {
$view = $_GET["$view"];
}
Also:
switch($view] // ...what is this?
include_once(foot.html; // and this?
case:"contact": // ummmm
$view="";
if(isset($_GET["$view"]) && $_GET("$view")! = "") { $view =$_GET["$view"];};
You actually set $view=""; as an empty parameter
There for isset($_GET["$view"] looks like this isset($_GET[""]
You whole if statement with the above code is ignored
Likewise your switch($view); also looks like switch("")
This means only your first case will be executed no matter what you have in your $_GET
Check this portion of your code too for errors. the colon after case needs to be removed
case:"contact":
include(contact.html);
break;
For first, use correctly [] and (). Then you have to learn about operators: http://www.w3schools.com/php/php_operators.asp
For now your code is non-sense.
I have a small switch statement in the header of a portfolio website I'm working on which governs which links are shown on which page. The value of $id comes from the GET variable, ie - '?id=index'.
switch($id) {
case "index":
//Show links to content
case !"index":
//Show link to index
case !"about":
//show link to about page
}
The issue is that the NOT operator isn't working in the final two cases. I want the link to the index to show when the user is NOT on the index page, and likewise with the about page. Currently, ALL links are shown on the index page (when $id == "index), and NONE are shown on any other pages.
Why might this be?
This is so, because it is supposed to be so.
switch compares using the == operator. So in the second case, you are actually testing whether
$id == (!"index")
Which will always evaluate to false since any string would be trueand not true would be false.
Which means, in your case it would be better to use if and else.
Sorry, but what you're trying to do is simply not valid syntax for a switch / case construct.
The closest you'll come to what you're looking for is to use the default option. This works like a final case option, that deals with all values that were not caught by any of the preceding cases.
switch($id) {
case "index":
//Show links to content
case "about":
//Show link to about page
default:
//show link to default page.
}
Also - don't forget the break; at the end of each case block, otherwise it'll fall through to the next one, which can lead to some unexpected bugs.
!"index" will probably evaluate as false (but I'm little surprised it didn't cause syntax error) and you'll actually having this statement:
switch($id){
case "index": //...
case false: // ...
case false: // ...
}
When you want to use switch, you'll need to do is this way:
switch($id){
case "index": // ...
case "about": // ...
default:
// Additional statements here, note that $id != "index" is already covered
// by not entering into case "index"
}
What your code is doing is comparing $id against three values: "index", !"index" (whatever it means) and !"about".
I'm not sure about your approach. You should try if/else or ternary operators.
Hope that it helps.
Switch doesn't offer custom operators.
switch ( $id ) {
case 'index':
// $id == 'index'
break;
case 'about':
// $id == 'about'
break;
case 'help':
case 'info':
// $id == 'info' or $id == 'help'
break;
default:
// all other cases
}
The switch case does not accept complex expressions. The not ! operator is a logical operator. It works in expressions like this.
!$x; // true if $x = false
or as a comparison operator:
$a != $b; // Not equal
// or
$a !== $b // not identical
From the manual.
The case expression of the switch statement may be any expression
that evaluates to a simple type, that is, integer or floating-point
numbers and strings. Arrays or objects cannot be used here unless they
are dereferenced to a simple type.
surely you can fix this with:
switch($id){
case ($id != 'index'):
echo 'this is not index';
break;
case 'index':
echo 'this is index';
break;
case 'foo':
echo 'this is foo!';
break;
default:
break;
}
However, this example is flawed, because the first case statement will just catch anything that isn't 'index' thus you shouldn't ever get to the case 'foo' nor the default statement
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR
if((!empty($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR just
if($_GET['example']=='somevalue'){ ... }
I am asking that why I have seen many example where people check first if $_GET['example'] is set and then if $_GET['example']=='somevalue' ( first and second example above ).
I don't understand why not just use the last solution ( if $_GET['example']=='somevalue' then $_GET['example'] is obviously set ).
This question refers to any other variable ( $_POST, $_SERVER, ecc ).
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
Is the right one, you want to know that the "variable" exists (or is set) in order to use it. Empty just checks wether it has data of any kind or not.
For example:
<?php
$foo= 0;
if (empty($foo)) { // True because $foo is empty
echo '$foo is either 0, empty, or not set at all';
}
if (isset($foo)) { // True because $foo is set
echo '$foo is set even though it is empty';
}
if (isset($var)) { // FALSE because $var was not declared before
...
}
?>
The differences between isset and empty are subtle but important. They are most relevant when used alone. If you are checking that a variable exists and is a truethy value (e.g. any string that is not all spaces or 0s) you can use either interchangeably.
When to use isset
Use isset when it's important to know if the variable has been defined and is not null:
if (isset($maybeExistsMaybeNull)) {
// variable defined and is not NULL
}
When to use !empty
Use !empty when it's important to know if the variable has be defined and is truthy
if (!empty($mightBeEmpty)) {
// variable defined, and isn't "", " ", 0, "0" etc.
}
!empty is a great shorthand for exists and is something.
When to use array_key_exists
Use array_key_exists when it's important to know if the key exists and the value is of no importance:
if (array_key_exists('something', $array)) {
// $array['something'] exists, could be literally anything including null
}
When not to use isset
If your code looks like this:
if (isset($something) && $something) {
// code is shorter with !empty
}
When not to use !empty
If your code looks like this:
if (!empty($something) && $something === "") {
// you meant isset. this is unreachable.
}
Then you're writing code that can't be executed
Code that throws errors is error prone
Avoid writing code that issues notices/warnings that you are ignoring. For example in the question:
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
The first use of example is an undeclared constant. Or is it undeclared - what if you've got define('example', "foo"); somewhere else in the code.
if($_GET['example']=='somevalue'){ ... }
If the url doesn't contain ?example=.. that's going to issue a notice too.
Writing code without displaying errors means you can very easily miss mistakes like the first.
In context: isset and !empty are equivalent
For the example given, these two language constructs act exactly the same.
There is no case where one will act differently than the other, neither will issue a notice if the variable is undefined, and no measurable difference in performance between the two.
As others have said for checking things like $_GET and $_POST you would ideally want to use:
if ( isset($_GET['example']) && $_GET['example'] =='somevalue' ) {
// process data
}
So you always want to firstly make sure that the variable has been set (and not set to null) or in other words exists. Then proceed to check if the variable contains the data that you were expecting. If you try to make reference to a variable which doesn't exist (by not checking isset()) php will give you a notice saying 'undefined variable...etc etc'.
If you wanted to find out if a variable is set but are not concerned too much by what then you could use:
if ( !empty($_GET['example']) ) {
// process data
}
But I would be careful about using empty() on strings in this regard as empty can behave strangely with string data like '0' or ' '.
So I would always do the first one, to a) make sure the variable exists and b) is what you were expecting it to be.
This is something that you'll probably do a lot of and it helps to put together a class/functions which handles this checking for you so you dont have to do it everytime.
function checkValue($key, $value) {
if(array_key_exists($key, $_REQUEST)){
if ($_REQUEST[$key] == $value) {
return true;
} else {
return false;
}
} else {
return false;
}
}
I just use Request as a default instead of switching out (though it is preferable to switch in some cases between POST and GET for security (imo)).
Now you can just call this function anywhere
if (checkValue('Item', 'Tom') === true){} etc
the best is
if((isset($_GET[example]))&&('somevalue'==$_GET['example'])){ ... }
The difference between
'somevalue'==$_GET['example']
AND
$_GET['example']=='somevalue'
If you mistype the == and type = instead, the first notaion will raise an error to notify you.
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
A new problem has arisen for me as I tried to run my script on a different PHP Server.
ON my old server the following code appears to work fine - even when no s parameter is declared.
<?php
if ($_GET['s'] == 'jwshxnsyllabus')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')\">";
if ($_GET['s'] == 'aquinas')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">";
if ($_GET['s'] == 'POP2')
echo "<body onload=\"loadSyllabi('POP2')\">";
elseif ($_GET['s'] == null)
echo "<body>"
?>
But now, on a my local server on my local machine (XAMPP - Apache) I get the following error when no value for s is defined.
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 43
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 45
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 47
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 49
What I want to happen for the script to call certain javascript functions if a value is declared for s, but if nothing is declared i would like the page to load normally.
Can you help me?
Error reporting will have not included notices on the previous server which is why you haven't seen the errors.
You should be checking whether the index s actually exists in the $_GET array before attempting to use it.
Something like this would be suffice:
if (isset($_GET['s'])) {
if ($_GET['s'] == 'jwshxnsyllabus')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')\">";
else if ($_GET['s'] == 'aquinas')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">";
else if ($_GET['s'] == 'POP2')
echo "<body onload=\"loadSyllabi('POP2')\">";
} else {
echo "<body>";
}
It may be beneficial (if you plan on adding more cases) to use a switch statement to make your code more readable.
switch ((isset($_GET['s']) ? $_GET['s'] : '')) {
case 'jwshxnsyllabus':
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')\">";
break;
case 'aquinas':
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">";
break;
case 'POP2':
echo "<body onload=\"loadSyllabi('POP2')\">";
break;
default:
echo "<body>";
break;
}
EDIT: BTW, the first set of code I wrote mimics what yours is meant to do in it's entirety. Is the expected outcome of an unexpected value in ?s= meant to output no <body> tag or was this an oversight? Note that the switch will fix this by always defaulting to <body>.
Get into the habit of checking if a variable is available with isset, e.g.
if (isset($_GET['s']))
{
//do stuff that requires 's'
}
else
{
//do stuff that doesn't need 's'
}
You could disable notice reporting, but dealing them is good hygiene, and can allow you to spot problems you might otherwise miss.
I always use a utility function/class for reading from the $_GET and $_POST arrays to avoid having to always check the index exists... Something like this will do the trick.
class Input {
function get($name) {
return isset($_GET[$name]) ? $_GET[$name] : null;
}
function post($name) {
return isset($_POST[$name]) ? $_POST[$name] : null;
}
function get_post($name) {
return $this->get($name) ? $this->get($name) : $this->post($name);
}
}
$input = new Input;
$page = $input->get_post('page');
I was having the same problem in localhost with xampp. Now I'm using this combination of parameters:
// Report all errors except E_NOTICE
// This is the default value set in php.ini
error_reporting(E_ALL ^ E_NOTICE);
php.net: http://php.net/manual/pt_BR/function.error-reporting.php
First check the $_GET['s'] is set or not. Change your conditions like this
<?php
if (isset($_GET['s']) && $_GET['s'] == 'jwshxnsyllabus')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')\">";
elseif (isset($_GET['s']) && $_GET['s'] == 'aquinas')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">";
elseif (isset($_GET['s']) && $_GET['s'] == 'POP2')
echo "<body onload=\"loadSyllabi('POP2')\">";
elseif (isset($_GET['s']) && $_GET['s'] == null)
echo "<body>"
?>
And also handle properly your ifelse conditions
I recommend you check your arrays before you blindly access them :
if(isset($_GET['s'])){
if ($_GET['s'] == 'jwshxnsyllabus')
/* your code here*/
}
Another (quick) fix is to disable the error reporting by writing this on the top of the script :
error_reporting(0);
In your case, it is very probable that your other server had the error reporting configuration in php.ini set to 0 as default.
By calling the error_reporting with 0 as parameter, you are turning off all notices/warnings and errors. For more details check the php manual.
Remeber that this is a quick fix and it's highly recommended to avoid errors rather than ignore them.
You should check wheter the index exists before use it (compare it)
if (isset($_GET['s']) AND $_GET['s'] == 'foobar') {
echo "foo";
}
Use E_ALL | E_STRICT while developing!
Actually none of the proposed answers, although a good practice, would remove the warning.
For the sake of correctness, I'd do the following:
function getParameter($param, $defaultValue) {
if (array_key_exists($param, $_GET)) {
$value=$_GET[$param];
return isSet($value)?$value:$defaultValue;
}
return $defaultValue;
}
This way, I check the _GET array for the key to exist without triggering the Warning. It's not a good idea to disable the warnings because a lot of times they are at least interesting to take a look.
To use the function you just do:
$myvar = getParameter("getparamer", "defaultValue")
so if the parameter exists, you get the value, and if it doesnt, you get the defaultValue.
Avoid if, else and elseifs!
$loadMethod = "";
if(isset($_GET['s'])){
switch($_GET['s']){
case 'jwshxnsyllabus':
$loadMethod = "loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')";
break;
case 'aquinas':
$loadMethod = "loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')";
break;
case 'POP2':
$loadMethod = "loadSyllabi('POP2')";
}
}
echo '<body onload="'.$loadMethod.'">';
clean, readable code is maintainable code
Simple function, works with GET or POST. Plus you can assign a default value.
function GetPost($var,$default='') {
return isset($_GET[$var]) ? $_GET[$var] : (isset($_POST[$var]) ? $_POST[$var] : $default);
}
Another option would be to suppress the PHP undefined index notice with the # symbol in front of the GET variable like so:
$s = #$_GET['s'];
This will disable the notice. It is better to check if the variable has been set and act accordingly.
But this also works.
The real answer to this is to put a # At symbol before the variable which will suppress the error
#$_GET["field"]
#$_POST["field"]
It will work some slower, but will keep the code clean.
When something saves time for the programmer, and costs time for the website users (or requires more hardware), it depends on how much people will use it.