android 取消通知

When I first came to work for my current employer and opened up Zend Studio (don’t worry, they’ve mostly abandoned that atrocity of an IDE), around 2,000 of the 10,000 PHP files that made up our application lit up with errors. The developers before me never properly maintained it, and the horrors of legacy code I was exposed to were unfathomable. I knew right then and there that this wasn’t going to be an easy trip.

当我第一次为现任雇主工作时,打开了Zend Studio(不用担心,他们大多放弃了IDE的这种残酷行为),在构成我们应用程序的10,000个PHP文件中,大约有2,000个出现了错误。 在我之前的开发人员从来没有适当地维护过它,而我所接触到的遗留代码的恐怖令人深不可测。 我那时就知道,那将不会是一件容易的事。

After spending weeks trying (and failing) to fix the mess, I gave up and focused on the more contemporary tasks implementing the new requested features on top of the chaos – a bad idea as most will agree. A job is a job though, and for a while it all worked well. In time, we started to notice the app’s write operations peaking beyond normal limits. Opening the error log revealed why: notices and warnings.

在花了数周时间尝试(并未能解决)混乱之后,我放弃了精力,专注于更现代的任务,即在混乱之上实现新的请求功能-这是一个坏主意,大多数人都会同意。 一份工作就是一份工作,而且一段时间以来一切都很好。 随着时间的流逝,我们开始注意到该应用程序的写操作达到了超出正常限制的峰值。 打开错误日志揭示了原因:通知和警告。

The PHP notice suppression operator is somewhat of a controversial topic in many circles. Some overuse it, some don’t use it at all, and some don’t even know it exists. Apologies in advance for the horrible code you’re about to witness in this article, but it serves a purpose to illustrate the usefulness (or lack thereof) of the suppression operator.

PHP通知抑制操作符在许多圈子中都是一个有争议的话题。 有些人过度使用它,有些根本不使用它,有些甚至不知道它的存在。 对于您将在本文中目睹的可怕代码,我们事先表示歉意,但它旨在说明抑制运算符的有用性(或缺乏抑制作用)。

(Notices and Warnings)

PHP has different error levels categorized by severity. Notices and warnings are the weakest type which means they don’t break the execution of your application – instead, they’re just echoed out to the screen or written to the error log (or both, depending on your settings), and execution continues.

PHP具有根据严重性分类的不同错误级别。 通知和警告是最弱的类型,这意味着它们不会破坏应用程序的执行–相反,它们只是被回显到屏幕上或写入错误日志(或两者,取决于您的设置),并且继续执行。

An example would be the following. If you have an empty array $aArray, and try to access a key that doesn’t exist like so:

一个例子如下。 如果您有一个空数组$aArray ,请尝试访问一个不存在的键,如下所示:

<?php
$aArray = array();
$aArray['someKey'];

You get a notice that the key doesn’t exist.

您会注意到该密钥不存在。

Notice: Undefined index: someKey in /var/www/index.php on line 3

Call Stack:
    0.0009     328920   1. {main}() /var/www/index.php:0

You get a notice that the key doesn’t exist. But this doesn’t break your code – in fact, if you try storing $aArray['someKey'] into a variable, that variable will actually get initialized as expected with a null value.

您会注意到该密钥不存在。 但这并不会破坏您的代码-实际上,如果您尝试将$aArray['someKey']存储到变量中,则该变量实际上将按预期方式初始化为空值。

Let’s take a look at a more concrete example. Assume we have a controller that passes into its view an array of messages; the array can look like this (and in a lot of cases in this legacy code I was introduced to, it did!):

让我们看一个更具体的例子。 假设我们有一个控制器,它将一个消息数组传递给它的视图; 数组可以看起来像这样(在很多情况下,在我介绍的旧代码中,它确实做到了!):

<?php
// $oView = ... our view object
// $aMessages = array();

if (/* some expression that signifies an error */) {
    $aMessages['error'] = 'Error no.2 occurred, contact developer!'; 
}

$aMessages['status'] = 'Finished operation';
$oView->aMessages = $aMessages;

You’ll notice that the “error” key is only set if the error actually occurs, that is, if the if-expression in the parentheses evaluates true.

您会注意到,仅当错误实际发生时(即,括号中的if-expression计算为true时)才设置“错误”键。

The view code looked something like this (simplified for the purposes of this article):

视图代码看起来像这样(为本文的目的而简化):

<h1>Operation completed</h1>
<?php 
    echo @$this->aMessages['error'];
    echo '<hr />';
    echo $this->aMessages['status'];
    echo '<hr />';
    // ...

The status of the operation and the error is echoed out. But seeing as they were aware of the fact that “error” might not be set, they used the suppression operator @ to prevent the notice from being printed on screen.

操作状态和错误将被回显。 但是,当他们意识到可能未设置“错误”的事实时,他们使用了抑制运算符@来防止在屏幕上打印该通知。

A surprising amount of PHP developers don’t actually know that even if you suppress a notice on screen that it still gets logged if logging is turned on – so your error log is getting littered with pointless and relatively large lines of text. Developers often think @ is just legit shorthand for “ignore”, but it’s not – it’s shorthand for “I know my code here sucks, but let’s pretend everything is OK because I’m not going to make it better.”

数量惊人PHP开发人员实际上并不知道,即使您取消显示在屏幕上的通知,如果打开日志记录,该通知仍然会被记录-因此您的错误日志会被乱七八糟的毫无意义的文本行所困扰。 开发人员经常认为@只是“忽略”的合法简写,但不是-简写为“我知道我的代码很烂,但是我们假装一切正常,因为我不会做得更好。”

(When to Use It?)

So when is using suppressions actually acceptable?

那么什么时候使用抑制实际上可以接受?

Never!

决不!

When you use suppressions, it means you’re aware your code might suck but you just don’t care. This tells developers who run into your code after you that you’re a bad developer.

当使用抑制时,这意味着您知道您的代码可能很烂,但是您根本不在乎。 这告诉在您之后遇到您的代码的开发人员您是一个糟糕的开发人员。

It also slows down your app because it constantly has to write something into the error log. Imagine the code above being called by 1,000,000 visitors on a high traffic day. That’s one million lines of text in the error log! The impact on performance is hardly negligible.

它还会减慢您的应用程序的速度,因为它经常需要向错误日志中写入一些内容。 想象上面的代码在交通繁忙的一天被1,000,000的访客调用。 这就是错误日志中的一百万行文本! 对性能的影响几乎可以忽略不计。

Really? Never?

真? 决不?

While developing, the error messages are there for a reason. They help you find bugs in your code before you inflict the same fate on your users and customers. They point you in the right direction as to what’s wrong and what needs to be fixed. This is true for notices as much as it is for fatal errors – they all serve to help you, the developer, make the best product possible. Sometimes, however, you might need to test some functionality before handling any remaining notices that are left over from before – when outputting generated files for example. If a notice gets printed before the file generation begins, that means headers were already sent (because without headers your browser has no idea how to echo the content it is being given) and that means your file won’t display properly because it needs to send its own headers to the browser in order for the browser to recognize we’re dealing with an actual file.

在开发过程中,错误消息在那里是有原因的。 它们可以帮助您在对用户和客户施加相同的命运之前,在代码中查找错误。 他们为您指出了错误的正确方向和正确的方向。 通知和致命错误都是如此,它们都可以帮助开发人员帮助您开发出最好的产品。 但是,有时候,例如在输出生成的文件时,您可能需要先测试一些功能,然后再处理之前留下的所有剩余通知。 如果在文件生成开始之前打印了通知,则意味着已经发送了标头(因为没有标头,浏览器就不知道如何回显所给出的内容),这意味着文件将无法正确显示,因为它需要发送自己的标头到浏览器,以使浏览器识别出我们正在处理的是实际文件。

There’s also the rare case of having to deal with some of PHP’s iffy implementation details – for example, using the mail() function will throw an error if the mail server isn’t up, so doing @mail() is justified.

在极少数情况下,必须处理PHP的一些实施细节-例如,如果邮件服务器未启动,则使用mail()函数将引发错误,因此使用@mail()是合理的。

But these are all exceptions to the general rule. With training, you’ll be able to recognize the instances in which using a suppressor is unavoidable. Then and only then should you suppress anything, but you should strive to avoid even this. A good developer fixes ALL possible notices as soon as they detect a chance of encountering them.

但是这些都是一般规则的例外。 通过训练,您将能够识别不可避免使用抑制器的实例。 那时并且只有那时,您才应该压制任何东西,但即使如此,您也应努力避免。 优秀的开发人员在发现所有可能的通知后立即修复所有可能的通知。

How can you force yourself to do this, you might ask? By doing the same thing I did when I built my framework:

您可能会问,如何才能强迫自己做到这一点? 通过执行与构建框架时相同的操作:

<?php
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
    if (!(error_reporting() & $errno)) {
        // This error code is not included in error_reporting         
        return;
    }
    echo "<b>ERROR!</b> [$errno] $errstr<br>n";
    echo "  Fatal error on line $errline in file $errfile";
    echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br>n";
    echo "Aborting...<br>n";
    exit(1);
    break;
}
$old_error_handler = set_error_handler("myErrorHandler");

The snippet above replaces the default error handler with a custom function, which makes the application die on absolutely any error, warning, or notice.

上面的代码片段用自定义函数替换了默认的错误处理程序,这使应用程序在出现任何错误,警告或通知时都会死亡。

This is, of course, simplified. A proper error reporting class is far more advanced than this and outputs much more info, but the gist of it is as follows: break your app on purpose whenever a notice or warning is encountered, or, in other words, treat your warnings and notices as fatal errors.

当然,这是简化的。 适当的错误报告类要比这高级得多,并且可以输出更多信息,但是其要点如下:每当遇到通知或警告时就故意中断您的应用程序,或者换句话说,对待您的警告和通知作为致命错误。

By doing this, your app will break during development and testing, giving you the chance to write your code as bulletproof as possible. You’re making your life and the lives of those coming into your code after you’re gone all much easier.

这样,您的应用将在开发和测试过程中损坏,从而使您有机会尽可能地编写代码以防弹。 在您离开之后,您正在使自己的生活以及那些进入代码的人们的生活变得更加容易。

Adding a custom error handler which breaks your app with every notice and warning will make sure you and your developers take much more care of the cleanliness of your code. In the long term, it keeps the error log clean and reserved for only the most serious of errors. It might slow down development a bit for rookie programmers, but experienced developers will appreciate this extra effort. After all, it’s better to spend an extra week writing cleaner code than to spend months later down the line trying to fix it.

添加一个自定义错误处理程序,它会在每次发出通知和警告时中断您的应用程序,以确保您和您的开发人员更加注意代码的整洁性。 从长远来看,它可以使错误日志保持干净,并仅保留最严重的错误。 对于新手程序员来说,这可能会减慢开发速度,但是有经验的开发人员会对此付出的努力表示赞赏。 毕竟,比花几个月的时间来尝试修复更干净的代码要花额外的一周时间。

(Conclusion)

Good code is a medal you can strap onto your chest. It’s a trophy you wear proudly. Good code follows you after you leave it behind, and the tales it tells to those that inherit it will feature you as the main character. It’s up to you to make sure you’re the protagonist of those stories, and not an antagonist.

好的密码是可以戴在胸前的勋章。 这是您骄傲地穿着的奖杯。 留下良好的代码后,您会跟随它,并且它告诉继承者的故事将以您为主要角色。 您有责任确保自己是这些故事的主角,而不是反对者。

翻译自: https://www.sitepoint.com/why-suppressing-notices-is-wrong/

android 取消通知