Jump to content

Strange undefined variable and undefined index notices


Recommended Posts

Hello,

 

I have just upgraded my wampserver and with it MySQL, PHP and PhpMyAdmin versions. And my scripts, which ran normally before, not burst hundreds of undefined variable and undefined index notices. I realize it's "notices", not "errors" but this is quite irritating. I believe it might be due to some upgrade in PHP scripting rules or something but I don't know what. I hope you can help me.

 

The first type of notice is "undefined variable". This function will return the notice if I remove the bold red line, where I define the variable as empty before I use it in the loop. I didn't need to do this before.

function statistics($array) {

[color=red][b]$list = '';[/b][/color]

if(is_array($array)) {
	foreach($array as $name => $value) {
		// Rip out the name of the client.
		$list .= "<li>".$name." - ";
		// set an integer so we know how many tier2 values we have read.
		$x = 0;
		foreach($value as $difference => $sum_total) {
			// if this is the more than the first tier2 values, use a '+' between the units.
			$list .= (++$x > 1) ? " + ".$sum_total." ".$difference : $sum_total." ".$difference;
		}
		// close the line out.
		$list .= "</li>";
	}
}
return $list;
}

To avoid the 10+ like notices on the page I declare them empty before the variable's first occurrence. But this sounds stupid to me. Wasn't this one of PHP's benefits, not to have to declare the variable before using it?

 

I also get about 30+ undefined index notices, e.g.

Notice: Undefined index: COMPANY XXX in F:\wamp\www\Project Management\main.php on line 37

 

Notice: Undefined index: USD in F:\wamp\www\Project Management\main.php on line 37

 

Notice: Undefined index: USD in F:\wamp\www\Project Management\main.php on line 41

 

Here are those lines:

$income_total = calculate("income");
foreach($income_total as $row) {
$clientID	= $row['clientID'];
$clientname	= $row['clientname'];
//$client		= "<a href=\"index.php?page=Client&do=view&clientID=$clientID\">".$clientname."</a>";
$client		= "<a href=\"index.php?page=Project&do=view&sortby=$clientID\">".$clientname."</a>";
$currency	= $row['currency'];
$client_sum = $row['client_sum'];
$year_sum = '';
$year_sum 	+= $client_sum;
$income = '';
$income[$client][$currency] += $client_sum;

$income_list = statistics($income);
$income_all = '';
$income_all[$currency] += $client_sum;
}

 

Line 37 is:

$income[$client][$currency] =

It's the values assigned to $client and to $currency that seem to cause the notice.

 

How do I deal with this? I don't just want to turn error/notice display off, I want to resolve this issue.

I want to resolve this issue.

 

Then you will need to write proper code.

 

For your first example, $list = '';. You are correct in that you don't need to define a variable before you use it, but that is not the problem. You are referencing the variable (in the dot . part of the .= assignment operator) before it has been assigned a value the first time. It does not exist yet, but the dot is referencing its current value. The solution is to set it to an empty string like you did.

OK, I will try to write proper code and to do that I need to know what I'm doing wrong.

 

Is it the same kind of mistake here (this is the complete file). I get two notices about the same undefined variable $currency on line 44:

<td>".$currency."</td>

here:

<?php

$list = "<table>
		<tr><td colspan=\"6\"><h3>Client List</h3></td></tr>
		<tr>
			<th>ID</th>
			<th>Name</th>
			<th>No. Projects</th>
			<th>Revenue</th>
			<th>New</th>
			<th>View all</th>
		</tr>";



$client_list = showClients();
foreach($client_list as $row) {
	$clientname = $row['clientname'];
	$clientID	= $row['clientID'];

	$client_work = showClientWork($clientID);

	$np = 0;

	foreach($client_work as $row) {
		$projectname	= $row['projectname'];
		$projecttype	= $row['projecttype'];
		$sourcelang		= $row['sourcelang'];
		$targetlang		= $row['targetlang'];
		$totalprice		= $row['totalprice'];
		$subprice		= $row['subprice'];
		$currency		= $row['currency'];
		$paid			= $row['paid'];

		$np += 1;
	}

	$list .= "<tr>
				<td><a href=\"index.php?page=Client&do=edit&clientID=$clientID\" title=\"EDIT $clientname INFO\">".$clientID."</a></td>
				<td><a href=\"index.php?page=Client&do=edit&clientID=$clientID\" title=\"EDIT $clientname INFO\">".$clientname."</a></td>
				<td>".$np."</td>
				<td>".$currency."</td>
				<td><a href=\"index.php?page=Project&do=new&clientID=$clientID\" title=\"New Project for ".$clientname."\">
					<img src=\"images/add.gif\" alt=\"add.gif\" border=\"0\" /></a></td>
				<td><a href=\"index.php?page=Project&do=view&sortby=$clientID\" title=\"All projects by ".$clientname."\">
					view all</a></td>
			  </tr>";
}

$list .= "</table>";

echo $list;
?>

 

$currency gets its value above, in

$currency		= $row['currency'];

 

And, what about the "undefined index" issues?

I have fixed this error - turns out the notice appeared because I had a clientname but no projects and no currency were added for the client. Now that the variable is not empty, it's OK.

 

However, I have the same kind of notice on another page. Now that all variables have a value, I don't understand what else is wrong.

 

As I posted earlier here, this is where I get 12 x 3 notices of undefined indexes (because there are 12 clients in the DB):

	$income_total = calculate("income");
foreach($income_total as $row) {
	$clientID	= $row['clientID'];
	$clientname	= $row['clientname'];
	$client		= "<a href=\"index.php?page=Project&do=view&sortby=$clientID\">".$clientname."</a>";
	$currency	= $row['currency'];
	$client_sum = $row['client_sum'];
	$year_sum 	= '';
	$year_sum 	+= $client_sum;
	$income 	= '';
	$income[$client][$currency] += $client_sum;

	$income_list = statistics($income);
	$income_all = '';
	$income_all[$currency] += $client_sum;
}

 

The calculate("income") function returns the results expected, which I fill in the $income_total array that I then break into separate values. The "bad" line is this:

$income[$client][$currency] += $client_sum;

But the variable $client gets a value, so it's not the first time I declare it. At first I thought it could be because $client contains HTML + $clientname, but when I changed it to

$income[$clientname][$currency] += $client_sum;

and comment out the line where I assign a value to $client, I still get the same notice, on the same line. What puzzles me is that the notices have the actual clientname/currency name as a undefined index, e.g.

Notice: Undefined index: Babylon Expert in F:\wamp\www\Project Management\main.php on line 37

 

Notice: Undefined index: USD in F:\wamp\www\Project Management\main.php on line 37

 

Notice: Undefined index: USD in F:\wamp\www\Project Management\main.php on line 41

 

Please help me comprehend this.

You are adding to an array key that is not defined.

 

This is the one situation that I suppress the error (@).

 

OK, and how do I define an array key? By declaring an empty array before I start filling the array? (this doesn't work) :-\

	$income[] 	= array();
	$income[$client][$currency] += $client_sum;

 

And is this the same situation:

 

When validating a form, I check if $_POST[] is empty. If empty I call an error display function:

if(empty($_POST['country'])) {
	formError("Country");
}
.....
function formError($err_message) {	
if(isset($err_message)) {
	$_SESSION['errors'] .= $err_message;
}
}

Here I get an undefined index notice for the $_SESSION value: "Undefined index: errors... "

 

For the session variable. You are concatenating it.  Which means PHP is looking for the variable so it can ADD to it.  It gives the notice because it didn't find the index of that variable.

 

For the Income, if it is not set, then just declare it. If it is set, then add to it.

if(isset($income[$client][$currency])) {
$income[$client][$currency] += $client_sum;
}
else {
$income[$client][$currency] = $client_sum;
}

 

For the session variable. You are concatenating it.  Which means PHP is looking for the variable so it can ADD to it.  It gives the notice because it didn't find the index of that variable.

 

For the Income, if it is not set, then just declare it. If it is set, then add to it.

if(isset($income[$client][$currency])) {
$income[$client][$currency] += $client_sum;
}
else {
$income[$client][$currency] = $client_sum;
}

 

 

Thank you! I wrote isset checks for every array I create and got rid of all the warnings :)

 

Now, the session... Yes, I am concatenating it. That's the way I decided to get all the missing post values after submitting the form and display them - by storing the errors array in a session. Maybe that's not a very good idea then?

 

But, if I stick to this way of displaying error feedback, how do I collect all the missing $_POST values AND get rid of the warning?

 

I tried adding a line where I create an index value, to which to add the $err_messages but this way only the first of the missing fields is printed (and no warning).


function formError($err_message) {	

$_SESSION['errors'] = "fields: ";
if(isset($err_message)) {
	$_SESSION['errors'] .= $err_message.", ";
}

}

Why do you need to store the errors in $_SESSION? Is there some reason the script validating the form input isn't the same one that displays feedback about it? You're also not giving the user anything specific about what the problem was. I often use something like:

 

$checks = 0;
$passes = 0;
$errors = array();

$checks++;
if(!empty($_POST['username'])) {
    $passes++;
    $checks++;
    if(ctype_alnum($_POST['username'])) {
        $passes++;
    } else {
        $errors[] = "Usernames must be alphanumeric.";
    }
} else {
    $errors[] = "You did not provide a username.";
}

if($passes == $checks) {
    // proceed
} else {
    foreach($errors as $val) {
        echo $val."<br />\n";
    }
}

 

If you really need the error text to be a session variable, define

 

$_SESSION['errors'] = "";

and append it in the foreach loop

 

$_SESSION['errors'] .= $val."<br />\n";

You're right, I don't need that function for error reporting outside the form check script.

 

I have done it as you suggest, much easier indeed.

 

What I'm working on is a system for my own use that will not go online, so detailed error reporting is unnecessary.

 

Thank you all for your help!

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.