I thought I knew how to use arrays until I started storing form filling errors in them. So here is the situation: I want to declare an array at the beginning of my PHP document. Then throughout the document there is validation and at each validation the array is filled with an error if an error should be produced. Then at the end of the document I want to echo these errors into a specific on the page. So here is what I have now:
$errors = array();//declares array
if(/*some qualifier*/) {//username validation
} else {
$errors[] = "<p>Please enter a valid username</p>";
}
if(/*some qualifier*/) {//email validation
} else {
$errors[] = "<p>Please enter a valid email</p>";
}
echo '<div id="errors">';//errors div
foreach ($errors as $value) {//fills error div with the errors LINE 60
echo "$value<br />\n";
}
echo '</div>';
So... what is wrong with that? I keep getting an error that errors is an undefined variable when it tries to echo the errors.
The error as given in the comments:
An error occurred in script 'file path' on line 160: Undefined variable: errors
Update: seems like its a problem with something weird in my code. If you feel like looking through 217 lines of code here is all the code: http://pastebin.com/YkERYpeF
I have seen your code. You did only declare $errors inside a condition:
//if the user has registered
if (isset($_POST['submitted'])) {
require_once (MYSQL); //gets the database connection
$errors = array(); // declares the errors array that will be printed at end of validation if needed
PHP arrays work great. You are declaring variables in a conditional scope and using them in a global scope. And PHP can't imagine you want to use that variable in the global scope.
You ought to indent your code as well, but you can perfectly define $errors just below $bodyId and PHP won't complain anymore.
Chances are something in one of your validation blocks is using $errors for its own purposes, some function called somewhere in there uses global $errors, or something is screwing it up in some other manner.
I've found the quickest way to track down this sort of thing is to insert a check on the variable somewhere in the middle and basically do a binary search on the code until you track down just where the variable is being reset.
Related
You know how PHP errors always show up at the very top of the page. Is there a way to suppress that and turn it in to a $var? Then you could place it somewhere in the page.
Yes, you could set your own error handler to intercept and do something with those error besides simply outputting them wherever they occur. But I don't think it's very useful to display PHP errors elegantly on a page. PHP errors are not meant to be pretty, they're not meant to occur at all. If you see one, it should be as jarring as possible and you should fix it as soon as possible. They're meant as a help during development. Trying to pretty them up is spending time on the wrong part of the code.
In production, those errors should be logged to a log file and not visibly output on the page at all.
$php_errormsg holds the previous error, even the suppressed ones.
#fopen('foo.txt', 'w');
echo $php_errormsg; // You can put this anywhere you want the error to display
If you think you'll have more than one error, then you could store these errors in an array.
$errors = array();
for($files as $f) {
#fopen($f, 'w');
$errors[] = $php_errormsg;
}
Then you could print out all your errors:
print_r($errors);
//or
for($errors as $e) {
echo $e;
}
What I had BEFORE was...
if(DEBUGMODE) $debug_err_msgs[] = 'Some error'; // add a new error to the array
... more code here...
if(DEBUGMODE)$debug_err_msgs[] = 'Some error'; // add a new error to the array
which worked great EXCEPT in functions. SO... I decided to make it GLOBAL by using the $_GLOBALS array. I originally liked the 1st method I chose because it kept adding to the array and I could dump it later on to view what was happening.. Using the $_GLOBALS['debug_err_msgs'] and $_GLOBALS['errorh_string'] is forcing me to .= (append) the string to the previous one (which is ok... I didn't think you could go... $_GLOBALS['something'][] and keep adding to the array like I did before I changed my code. SO.. I made changes as below...
PHP
<?php
error_reporting(E_ALL);
set_error_handler("ErrorHandler");
$_GLOBALS['errorh_string'] = "";
if(DEBUGMODE) $_GLOBALS['debug_err_msgs'] = "";
if(DEBUGMODE) $_GLOBALS['debug_err_msgs'] .= 'La la la, some errors';
if(DEBUGMODE) $_GLOBALS['debug_err_msgs'] .= 'more errors... etc';
function ErrorHandler($errno, $errstr, $errfile, $errline)
{
// if ($errno == 8) return;// 8 is undefined variables
$error = "<b>Error[</b>$errno<b>] </b>$errstr<br />";
$_GLOBALS['errorh_string'] .= $error; // append new error to the global string
return true; // dont execute the php internal error handler
}
?>
ERRORS IM GETTING
Notice: Undefined index: errorh_string in /debugOpenBlock.php on line 14
Notice: Undefined index: errorh_string in /debugOpenBlock.php on line 14
Which in the code above, is INSIDE the function
$_GLOBALS['errorh_string'] .= $error; // GIVES ME UNDEFINED
Here is what's weird... if I change the line to read...
$_GLOBALS['errorh_string'] = $error; // NO ERROR NOW
I even tried
$_GLOBALS['errorh_string'] = $_GLOBALS['errorh_string'] . $error; // GIVES ME UNDEFINED
If 'errorh_string' is a literal? why do I get undefined in it.!?!??! Am I missing something about GLOBALS?
As I was writting this I was thinking I could have used
global $debug_err_msg[]; // make this array global
instead of changing all my code to the way I have it now but... I'm curious what this problem is now... I hate not knowing something :)
BTW - I just recently turned off register_globals in the PHP.INI file. Could this have anything to do with it (note: I NEVER used $_SESSION['somevariable'] as $somevariable (mainly because I didn't know you could do that but... doesn't matter anyways)).
I've read piles of articles about superglobals, register_globals etc but nothing sheds any light on this..
Awaiting wisdom oh greater than I web developers :)
I can't find another problem, so the issue seems that you just used the wrong variable name. It is called $GLOBALS, not $_GLOBALS - unlike the input arrays. (It's not affected by the register_globals setting btw.)
global $debug_err_msg;
You should actually prefer this method. That makes using the variable more legible than with the $GLOBALS[] access, and it also shows that you intentionally share that variable.
The problem
The following code produces this error from the line "print $readerStatus" -
Undefined index: readerStatus
Code
<?php
//Get Cookie Value
if (isset($_COOKIE['readerStatus'])) {
$readerStatus=$_COOKIE['readerStatus'];
} Else {
$readerStatus="Not Set";}
echo "The value of Cookie readerStatus is " . $_COOKIE['readerStatus'];
print $readerStatus;
?>
Background
The goal is simply that if a cookie is set I want to pass the value into a Javascript. My strategy is as follows:
Get the value from the cookie
Set a variable to the value of the cookie
Then use a php echo inside of the Javascript to transfer the value.
It works as expected but Eclipse is giving me the error and so I assume there is something wrong with the above code.
I'd appreciate any pointers on possible sources of the problem.
Thanks
Is this working?
<?php
//Get Cookie Value
if (isset($_COOKIE['readerStatus'])) {
$readerStatus=$_COOKIE['readerStatus'];
} else {
$readerStatus="Not Set";
}
echo ("The value of Cookie readerStatus is ".$readerStatus);
print ($readerStatus);
?>
This is a warning, not an error. However, you can skip the error by using array_key_exists. Generally, I'm not a fan of isset for this kind of checking.
if (array_key_exists('readerStatus', $_COOKIE))
{
$readerStatus=$_COOKIE['readerStatus'];
}
else
{
$readerStatus='Not Set';
}
echo 'The value of Cookie readerStatus is '. $readerStatus;
Some IDEs are less forgiving than the PHP parser itself. That being said, do you get any errors or notices when running the code? Variables in PHP are implicitly declared, so the undefined index message is simply a NOTICE (that can be ignored) regarding the accessing of an array element without it existing first.
If you check it exists prior to accessing it like this, you shouldn't have a problem.
$readerStatus = isset($_COOIKE['readerStatus']) ? $_COOIKE['readerStatus'] : '';
I don't understand why someone is using the # in the code, I have seen it with mysql connections but I don't know what it means.. thanks!
$player_name_orig = #$_GET['player'];
if (!$player_name_orig) {
die('You must specify a player name');
}
The # is the error suppression operator.
In this specific context, it's a (wrong!) way to avoid PHP giving a notice if the player key does not exist in $_GET:
If you try this:
unset($_GET['player']); // to make sure
echo $_GET['player'];
You get:
Notice: Undefined index: player in F:\dev\www\index.php on line 35
While if you try this:
unset($_GET['player']); // to make sure
echo #$_GET['player'];
There is no output.
The correct way to do this:
if (empty($_GET['player']) {
die('You must specify a player name');
}
The # will stop any errors from appearing and return false on an error.
So in your code if $_GET['player'] does not exist then the code will go into the if statement
# Means to ignore errors such as the variable not being set.
the "#" is used to prevent any warning or error message to appear. It's a really bad habit. Doing that a lot of hidden operations are done (removing error handler, and putting it back after).
The right way to do that operation is:
// my_security_filter() is a function that can render FALSE and remove any dangerous thing
$player_name_orig = array_key_exists('player',$_GET)? my_security_filter($_GET['player']) : FALSE;
if (FALSE===$player_name_orig) { ...
I am making a registration system with an e-mail verifier. Your typical "use this code to verify" type of thing.
I want a session variable to be stored, so that when people complete their account registration on the registration page and somehow navigate back to the page on accident, it reminds them that they need to activate their account before use.
What makes this problem so hard to diagnose is that I have used many other session variables in similar ways, but this one is not working at all. Here's my approach:
/* This is placed after the mail script and account creation within the same if
statement. Things get executed after it, so I know it's placed correctly. */
$_SESSION['registrationComplete'] = TRUE;
// I've tried integer 1 and 'Yes' as alternatives.
Now to check for the variable, I placed this at the top of the page.
echo $_SESSION['registrationComplete']; // To see if it's setting. This gives the
// undefined index notice.
if (isset($_SESSION['registrationComplete'])) {
// Alternatively, I have nested another if that simply tests if it's TRUE.
echo $_SESSION['registrationComplete']; // When echo'd here, it displays nothing.
echo '<p>Congratulations, Foo! Go to *link to Bar*.</p>';
}
Now, I used to have the page redirect to a new page, but I took that out to test it. When the page reloads from submit, my message in the if statement above appears and then I get an Notice: Undefined index: registrationComplete blah blah from the echoing of the session var!
Then if I ever go back to the page, it ignores the if statement all together.
I have tested for typos and everything, clearing session variables in case old ones from testing were interfering, but I am having no luck. A lot of Googling just shows people suppressing these errors, but that sounds insane! Not only that, but I am not getting the same persistence of session variables elsewhere on my site. Can someone point out if I'm doing something blatantly wrong? Help! Thanks!
FYI, I read several related questions and I am also a beginner, so I may not know how to utilize certain advice without explanation.
As requested, more code, heavily annotated to keep it brief
var_dump($_SESSION);
// It's here to analyze that index message. I guess it's not important.
echo $_SESSION['registrationComplete'];
if (isset($_SESSION['registrationComplete'])) {
// The golden ticket! This is what I want to appear so badly.
echo 'Congratulations, Foo! Go to *link to Bar*.';
}
// Explanation: I don't want logged in users registering.
// The else statement basically executes the main chunk of code.
if (isset($_SESSION['user_id'])) {
echo 'You are logged in as someone already.';
}
else {
if (isset($_POST['submitRegister'])) {
// Code: Database connection and parsing variables from the form.
if (!empty($email) && !empty($email2) && $email == $email2 && !empty($displayName) && !empty($password) && !empty($password2) && $password == $password2) {
// Code: Query to retrieve data for comparison.
if (mysqli_num_rows($registrationData) == 0) {
// Code: Generates the salt and verification code.
// Code: Password hashing and sending data to verify database.
// E-mail the verification code.
$_SESSION['registrationComplete'] = 'yes';
}
else {
// Some error handling is here.
$registerError = 'The e-mail address you entered is already in use.';
}
}
// the elseif, elseif, and else are more error handling.
elseif ($email != $email2) { $registerError = 'Your e-mails did not match'; }
elseif ($password != $password2) { $registerError = 'Passwords didn\'t match.'; }
else { $registerError = 'Filled out completely?'; }
// If the registration was submitted, but had errors, this will print the form again.
if (!isset($_SESSION['registrationComplete'])) { require_once REF_DIR . REF_REGISTERFORM; }
// IMPORTANT! it turns out my code did not work, I forgot I had the same statement elsewhere.
else { echo 'Congratulations, Foo! Go to *link to Bar*.'; }
}
// Creates form.
else { require_once REF_DIR . REF_REGISTERFORM; }
}
This came down to the basics of debugging/troubleshooting.
Understand as much as you can about the technique/library/function/whatever that you're trying to use.
Inspect the salient bits and make sure that they are what you expect or what they should be. (There's a slight difference between those two, depending on the situation.)
If that doesn't bring you towards a solution, step back and make sure you're understanding the situation. This may mean simplifying things so that you're only dealing with the issue at hand, i.e. create a separate, simpler test case which exposes the same problem. Or, it may simply mean that you stop coding and work through the flow of your code to make sure it is really doing what you think it is doing.
A typical issue with sessions not working is forgetting to use session_start() (near or at the top) of any page which uses sessions.
One of my favorite snippets of PHP code, for debugging:
print '<pre>';
var_dump($some_variable);
print '</pre>';
I try to use print for debugging and echo for regular output. It makes it easier to spot debugging code, once it's goes beyond a few trivial bits of output.
Meanwhile, var_dump will print a bit more info about the variable, like it's type and size. It's important to wrap it in <pre></pre> so that it's easier to read the output.
Try
if (!empty($_SESSION['registrationComplete'])) {
If you get the warning after the message is printed, this cannot come from the variable echoing because according to your code it would be thrown before printing that message. Are you sure you don't use $_SESSION['registrationComplete'] beyond the if statement? Try to add exit or die() before the closing bracket of the if and see if the notice disappears.