views:

69

answers:

4

I've been happily using the error suppression operator on my PHP dev setup. But recently have gotten hit with Notices like so:

Notice: Uninitialized string offset: 0 in C:\websites\xxx\htdocs\includes\myscript.php on line 35

Line 35:

$file_name = @$File['file_name'];

I have display_errors on, and error_reporting set to 6143 (E_ALL).

Am I missing something? Shouldn't the error be suppressed?

Edit:

Tested in virgin script:

$a = array();
$b = @$a['f5'];

Suppressed the error. So I'm thinking we're changing the error_reporting value somehow. (Film at 11)

Thx for yr help.

A: 

No, the @ suppressor avoids showing warnings from function calls, not variable access and declarations. The Notice is telling you that you are accessing a string element [0] that is not defined, thus not initialized. If you want to suppress these, try to check for all uninitialized variables and give them a value according, as you may do it with C.

Ast Derek
The manual disagrees with you, Derek:http://ca.php.net/manual/en/language.operators.errorcontrol.php
NotoriousWebmaster
+1  A: 

Since the error involves a string offset of 0, it must not apply to the line of code provided. There is no integer offset; you're using the string 'file_name' there.

Also, using '@' is a really terrible idea. Functions can fail, causing the script to exit with absolutely no indication as to where or why. A better way to handle the line of code you've pasted is this:

if (isset($File['file_name'])) {
  $file_name = $File['file_name'];
} else {
  // throw exception, return FALSE, print an error and exit, whatever
}
Lucas Oman
I would normally use ($isset($File['file_name']) ? $File['file_name'] : ''). But I'll have to disagree with you on the index issue: it seems to be a bug in the version of PHP I'm using (5.2.2). See the answer I put up.
NotoriousWebmaster
Bizarre. Thanks for the heads-up.
Lucas Oman
A: 

OK, here's the thing: PHP doesn't deal well with subscripts to non-array vars. For instance:

$a = 0;
$b = $a['f5'];

Doesn't generate an error.

Whereas:

$a = '';
$b = $a['f5'];

Generates this error:

Notice: Uninitialized string offset: 0 in C:\websites\tcv3\wc2009\htdocs\aatest_array.php on line 3

And that's the problem I was having. If I switch it around to initializing $a with array(), the error suppression works. Moreover, without error suppression it gives the proper index in the error.

I suspect this is a bug in PHP 5.2.2. Can someone test this in a more up to date version?

Thx for your help guys.

NotoriousWebmaster
When you say "a bug in PHP"... you're talking about the first bit of code not generating an error, right? The error you get from the other code is perfectly valid.
DisgruntledGoat
+1  A: 

Not a big fan of error suppression here except for throw-away scripts or instances where there really is no good way to catch an error.

Let me explain the behavior of the Uninitialized string offset error. It's not a bug:

Example #1

$a = 0;
$b = $a['f5'];

$a is a numeric scalar value. In the second line PHP is implicitly casting this numeric value to a string. The string '0' has a length of 1.

In PHP you can lookup a character in a string using an array index, as PHP stores strings as arrays internally. For instance:

$s= 'abcd';
print_r($s[1]);

The output of this code will be b as it is the second character in the string. In example #1 the lookup 'f5' is being converted to a number as strings can only be indexed by character position. echo intval('f5'); shows us what PHP interprets the 'f5' string as 0 in a numeric context.

With me so far? Here's what happens when we apply this to example #2

Example #2

$a = '';
$b = $a['f5'];

$a is zero-length string. The second line is the same as $b= $a[0]; - i.e., the second line is asking for the first character of a zero-length string, but the string contains no characters. So PHP throws the following error, letting you know the index simply does not exist:

Notice: Uninitialized string offset: 0 in C:\websites\tcv3\wc2009\htdocs\aatest_array.php on line 3

These are the hard knocks of programming in a loosely typed language.

pygorex1
Thx for a clear and succinct explanation, pygorex1.
NotoriousWebmaster