可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've suppressed notices for quite some time with no problems whatsoever but I am beginning to wonder if I'm doing the right thing. I can't seem to find any logical reason why I shouldn't just suppress them but some other people seem to think that suppressing them using error_reporting is a horrible thing to do, but why?
The closest thing to an answer I could find was in this question but that's still far from the answer I'm looking for. Is there some sort of unforeseen downside to hiding all the notices that PHP generates? For example, to include a variable from a POST call back into the form because there were errors, I would simply use:
<?= $_POST['variable'] ?>
This would generate a PHP notice. To fix that notice, I could use something like this:
<?= isset($_POST['variable']) ? $_POST['variable'] : '' ?>
But, is this really necessary? Will my code actually benefit any from doing this rather than just echoing the variable whether it exists or not and potentially creating a PHP notice? It seems to me that being able to ignore notices is a benefit of using PHP as then you don't have to worry about whether a variable is defined or not, especially for an example such as this where it doesn't seem to matter.
I also take advantage of PHP's ability to automatically change a variable's type/casting depending on how it's being used and you will often find code snippets such as this:
for ($i = 0; $i < $limit; $i++) $results[] = $i; // Example
where $results
has not been previously defined, but is turned into an array when I try to add a new item to it as an array. I sort of prefer doing it this way because if no results are added to the array and I need to store that information or convert it to JSON for whatever reason, then that particular variable will not be defined and thus save additional bandwidth, even if it's minute.
$data = stdClass; // For reference, in my case this would be defined before this code
$data->results = array();
$limit = 0;
for ($i = 0; $i < $limit; $i++) $data->results[] = $i;
print json_encode($data);
// {"results":[]}
versus
$data = stdClass; // For reference
$limit = 0;
for ($i = 0; $i < $limit; $i++) $data->results[] = $i;
print json_encode($data);
// []
The question again: what real benefit, if any, do I gain from fixing notice errors rather than just suppressing them? How can/would it harm my code?
回答1:
In my point of view, you should never suppress errors, any kind of them, notices or not. It might give you some convenience right now, but down the road, you'll face many, many problems with your code when you are maintaining it.
Suppose you have a variable you want to echo out like the above first example. Yes, using isset is a little complicated, but maybe your application should handle the special empty case anyway, thus improving the experience. Example:
if (isset($var)) {
echo $var;
} else {
echo "Nothing is found. Try again later.";
}
If you only had echo $var;
and if this was a public facing view a user was reading, they would just see nothing there, which may cause confusion. Of course, this is just one special case where fixing PHP Notices can improve your application.
It shouldn't be taken as a trouble or inconvenience when you are taking care of notices in PHP code, because code is supposed to be clean. I'd rather have a notice-free code than seeing clean code when I open it in source. Of course, both is definitely better! :)
Again, the errors (even if they aren't fatal) will cause problems down the road. If you're already doing things like echo $var;
without checking it, that's an assumption that a variable exists, even if you know it might not, it will just give you a habit of assuming things exist and work. This might be small right now, but after a while you'll find out that you'll cause yourself many, many problems.
The notices are there for a reason. If we all did error_reporting(E_ALL ^ E_NOTICE)
in our code, we're just being irresponsible for our code. If you are able to fix it, then why are you being lazy and not doing so? Sure, ship 1.0 with notices, fix them later, that's what we all say. But it is better to do that as a habit, code perfect the first time. If you spend 15 minutes writing code plagued by notices, and then spend 2 hours in later development time fixing them, why not just spend an hour and a half perfecting the code as you write it in the first place?
Writing good code should be a habit, not an inconvenience.
Error messages are there for a reason. Respect them, fix them, and there you go, you're a responsible programmer.
You also pave a path for the future maintainers of your code.
回答2:
Suppose that you have a notice that you shouldn't ignore.
This notice will be hidden into all notices that you usually ignore.
IMHO, warnings should not be ignored. You should always take care of warnings to prevent bug. Every time I have a notice in my log file, I treat it like a bug.
Also, if your site is accessed by a lot of user, you'll get a very big log file.
回答3:
In my experience, notices usually indicate a good chance that there's a bug somewhere in your code, usually of the case where you expect a certain variable to be set at a certain point but there will be cases where it isn't, and you'll start wondering why some part of your page isn't showing up or starts crashing randomly.
Of course computers aren't all that smart, and there will be cases where the code is clear enough and you don't care if there are any warnings, but that's what the @
operator is for.
回答4:
I respectfully disagree with some of the comments that suggest that you should never suppress notices. If you know what you are doing, I do think using @ is very useful, especially for handling unset variables or array elements. Don't get me wrong: I agree that in the hands of an inexperienced or sloppy programmer, @ can be evil. However, consider this example:
public function foo ($array) {
if (isset ($array[0])) {
$bar = $array[0];
} else {
$bar = null;
}
// do something with $bar
}
is functionally identical to
public function foo ($array) {
$bar = @$array[0];
// do something with $bar
}
but is IMHO less readable and more work to type. In these types of cases, I know there are exactly two possibilities: a variable is set or it isn't. I don't know in advance, but I must proceed in both cases. I see nothing wrong with using @ in that case. Yes, you could also write
public function foo ($array) {
$bar = isset ($array[0]) ? $array[0] : null;
// do something with $bar
}
but I find that only marginally better. To me, code readability and brevity are values in and of themselves, and bloating the code with isset-tests just out of principle to me is a little silly.
Of course, if I am not mistaken, using @ takes a tiny bit more time to execute that an isset-test, but let's be honest: how much of our code is truly performance critical? In a loop that is executed a bazillion times, I would probably use isset instead, but in most cases, it makes no difference to the user.