1
python 2013-04-29 12:57:29 +08:00
用E_ALL,写好了,各个环境都能通过...
对于用户的输入,要用isset处理, 程序不应该改变用户的原输入,即使是恶性的. |
2
AlloVince 2013-04-29 13:04:38 +08:00
关掉E_NOTICE不是一个好习惯,正是因为写法中可能存在隐患,所以才会有NOTICE报出,php稍微注意一下完全可以写出通过E_ALL的代码。这样对项目对自己都有好处。
变量未初始化的问题 如果在功能函数中,提前声明变量设默认值即可。 如果在模板引擎以及一些处理大批量参数的场景,最好用OOP处理,活用__set(),__get(),__isset()即可 |
3
raincious OP LS们真的用E_ALL?
我一开始学PHP的时候也是用E_ALL,一个页面打开,上百个isset调用,主要在数组处理上。 我实在没办法理解为什么程序员要将安全处理什么的交给解析器。 另外,isset跟安全处理没什么直接关系。他不能帮你判断用户输入是不是你想要的。一般人也主要用来防止Global Variable污染。 但是防止Global Variable污染你可以在函数或者什么地方声明啊,没事调用isset做什么呢? 另外,根据你们的说法,如果类似我这样保证变量使用之前都提前声明的话,就不需要开E_NOTICE了吧? 此外,我确实不相信有人的程序是error_reporting(E_ALL),你们的开发组真的是这样开发程序的么?那么你们其他意外怎么处理,比如file_get_content一个不存在的文件,这可是E_WARNING啊,如果不屏蔽,报错给用户不说,你们的HTTP Header不是会很糟。 如果为了file_get_content不报错,得file_existe吧?还得is_file吧?那么就3个IO操作了,值得么? 感觉E_ALL只是对新学PHP的人的一种手段而已。 |
4
chenz 2013-04-29 13:21:05 +08:00
1. 不应该关掉notice警告。如果你关掉notice,那么当一个需要set的变量没有set的时候,你可能无法察觉。但是所有的警告都应该写入log,而不是打印出来(至少生产环境)
2. 你应该用isset检查。不一定是在Yes那一行,可能是在更之前做这个isset检查。但是无论什么情况都应该做这个检查 你虽然习惯初始化,但是你不能保证你每次都记得初始化,你也不能保证团队里每个人都记得初始化 话说,我怎么感觉我回到了10年前的那些PHP论坛和邮件组?当年我们就是在频繁讨论这些话题。虽然这10年来PHP技术有长足的发展(匿名函数、composer、psr等),但是isset该如何使用,notice是否应该关掉,我想不会有太多变化吧 |
5
chenz 2013-04-29 13:28:15 +08:00 1
>> 此外,我确实不相信有人的程序是error_reporting(E_ALL),你们的开发组真的是这样开发程序的么?那么你们其他意外怎么处理,比如file_get_content一个不存在的文件,这可是E_WARNING啊,如果不屏蔽,报错给用户不说,你们的HTTP Header不是会很糟。
我的所有代码都是在E_ALL下写的,有notice我会马上修正。 file_get_content的问题,当然是if (file_exists($f) && file_readable..)才file_get_contents。 另外,就算没有做上面的判断,也不会把错误报告给用户。因为生产环境下当然会把所有warning写入服务器的log file,而不是打印出来。用户永远看不到这些错误报告。如果你们团队没有这样做,我可以说你们的团队真的还需要很多磨练 |
6
skey 2013-04-29 13:42:26 +08:00
error_reporting(E_ALL) +1
|
7
Js 2013-04-29 13:45:39 +08:00
|
8
raincious OP 我觉得各位还是没有考虑好这个问题,或者最好能举个例子说明楼主那个==YES的if如果再没初始化的时候会有什么危害。
当变量未初始化 return $_REQUEST['visitor'] == 'Yes' ? true : false; // False 当变量初始化并等于其他值 return $_REQUEST['visitor'] == 'Yes' ? true : false; // False 当变量初始化并等于Yes return $_REQUEST['visitor'] == 'Yes' ? true : false; // True 当变量未初始化并等于Yes // 未初始化如何等于? /* */ 可见情况是一致的。 另外,就算是为了防止全局变量污染: http://www.php.net/manual/en/ini.core.php#ini.register-globals PHP 5.4.0之后就没有自动全局变量注册了。于是乎,抱歉,使用这条利用来进行isset已经不靠谱了。 好吧,我整理下我的观点,基本不变:就变量是否初始化来打开E_NOTICE会增加不当开销,建议调试时打开,开发时写入次要日志,生产时关闭且不输出。 当然E_NOTICE还有其他错误,但在我看来,这跟程序员水平有关。如果为了安全,不应该让程序员来承担不必要isset的义务,而应该在核心上避免isset的需要(当然,不是完全禁止isset)。如果你们不明白,可以参看我3年前写的代码: https://code.google.com/p/faculaframework/source/browse/trunk/include/inc.initializer.php#66 @Js 此外根据性能问题,我特别进行了测试,观点仍然是我不做变更,这是结果: 操作次数都是5000次 T1: 判断下文件 T2: file_get_content这个文件 T3: file_exist && is_readable && file_get_content 这个文件 Array ( [Test1] => Array ( [LastStartTime] => 1367215477.7918 [LastEndTime] => 1367215477.7918 [LastUsedTime] => 3.6001205444336E-5 [AvaTime] => 3.5916407863653E-5 [Total] => 0.33174586296082 ) [Test2] => Array ( [LastStartTime] => 1367215478.5506 [LastEndTime] => 1367215478.5507 [LastUsedTime] => 0.00010204315185547 [AvaTime] => 0.00010305986018425 [Total] => 0.64278268814087 ) [Test3] => Array ( [LastStartTime] => 1367215479.5682 [LastEndTime] => 1367215479.5684 [LastUsedTime] => 0.00016403198242188 [AvaTime] => 0.00016249667572205 [Total] => 0.90015578269958 ) ) 请不要参考AvaTime,这是线性平均时间,不准确 这是测试代码: http://pastebin.com/i0ajTvMf Bites Me! |
9
AlloVince 2013-04-29 14:23:05 +08:00
@raincious 我还真的就是E_ALL
https://github.com/AlloVince/eva-engine/blob/master/init_autoloader.php isset用的特别多,代表你项目的OOP程度不深或者代码组织不够好,还主要依赖函数式编程用参数传递,而没有把使用频率高或复杂参数抽象为一个对象,很好的OOP代码组织结构可以取代局部变量的传递。 至于文件读取的问题,使用file_get_content属于比较偷懒的做法,简单但是执行效率低,个人写脚本OK,项目中并不推荐。好的文件读取方式应该是 if ($fh = fopen($filename, "r")) { # Processing fclose($fh); } 一次IO操作同时包含了文件的正确性检查。参看《用 PHP 读取文件的正确方法》 http://www.ibm.com/developerworks/cn/opensource/os-php-readfiles/index.html |
10
Js 2013-04-29 14:27:42 +08:00
@raincious 这测试没什么意思, 同一个文件第一次就进OS缓存了, 等于单向的测file_exists+is_readable的效率, 尤其是is_readable本身就带了file_exists的功能...
http://pastebin.com/U9ye5kQz |
11
GTim 2013-04-29 14:30:01 +08:00
人家是看到你还没达到大牛水平,哈哈...
错误和警告不能因为关闭了错误提示就忽略不是.. |
12
cute 2013-04-29 14:36:04 +08:00
我所有的代码都是error_reporting(E_ALL | E_STRICT).
|
13
chenz 2013-04-29 14:48:07 +08:00 1
1. 这里所有的讨论,从来就没有人说要用isset来防止global污染。实际上,就我个人而言,自动全局变量,在至少五年前已经不需要讨论了。现在还有人在讨论自动全局变量,在我看来很不可思议
2. 你提到"这可是E_WARNING啊,如果不屏蔽,报错给用户不说",证明你根本不知道error log应该如何设置。因为有经验的开发团队,在任何情况下,都不会让用户看到错误报告 3. 你不能根据一个例子没有问题,就假定所有情况下都没有问题。所以单单根据你那个request来讨论是否应该开启notice或者是否该使用isset是没有任何意义的。为什么要开启notice,我之前已经说得很清楚了,你不能保证所有人,以及所有场景下,都能严格初始化变量 4. 看了你写的inc.initializer.php,把最后的?>去掉吧。请看这里: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md The closing ?> tag MUST be omitted from files containing only PHP. 5. 不知道你为何多次提及"新手"或者"新学"。犯了上面第四条的人,很明显不能算是个非常有经验的PHP开发人员。而我要告诉你,这个帖子里的回复者里,有发布过多个PECL项目的程序员,有超过10年经验的开发者,有对zval了如指掌的同学。所以,低调吧,在你还在犯4这样的错误,还在连zval是什么都不知道的情况下,不要妄谈什么"新手"的习惯 |
14
chenz 2013-04-29 15:02:40 +08:00
看了你的http://pastebin.com/i0ajTvMf
1. 请了解clearstatcache这个函数,修改你的测试吧。你的测试代码没有任何意义 2. 你又犯了?>的错误:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md |
15
breeswish 2013-04-29 15:07:02 +08:00 via Android
我一般开发环境使用E_ALL
生产环境关闭错误显示 检查变量是否为空什么的我觉得就跟C里面检查一个指针是否为NULL一样重要 |
16
raincious OP 事实证明,@AlloVince的结果是最快的,在各种情况下:
T1: file_existe T2: file_get_content T3: @chenz & @Js 的方式 T4: @AlloVince 的方式 Array ( [Looped] => 7500 [Test1] => Array ( [LastStartTime] => 1367219062.6647 [LastEndTime] => 1367219062.6648 [LastUsedTime] => 0.0001220703125 [AvaTime] => 0.00010805782386953 [Total] => 0.7269139289856 ) [Test2] => Array ( [LastStartTime] => 1367219062.6648 [LastEndTime] => 1367219062.665 [LastUsedTime] => 0.00015997886657715 [AvaTime] => 0.00016230891026936 [Total] => 3.4872250556946 ) [Test3] => Array ( [LastStartTime] => 1367219062.665 [LastEndTime] => 1367219062.6654 [LastUsedTime] => 0.0004270076751709 [AvaTime] => 0.00042835394322712 [Total] => 2.5338525772095 ) [Test4] => Array ( [LastStartTime] => 1367219062.6654 [LastEndTime] => 1367219062.666 [LastUsedTime] => 0.00052094459533691 [AvaTime] => 0.00033806347033363 [Total] => 1.6245625019073 ) ) 这是代码:http://pastebin.com/gu7MSFRz 但是除了Test3,和用来参考的Test1其他方式都至少可能会有E_WARNING抛出的风险。 另外@chenz,我没有质疑各位的历史。当然也不在乎各位是否写过zval之类,一个工具而已。就事论事,你看清我的观点,我认为你应当error_reporting(0),以上所有各位我的观点都是如此,但是同时必须使用set_error_handler()。这是我的核心观点。也是我在开发时一直的观点。 https://code.google.com/p/faculaframework/source/browse/trunk/include/class.oops.php#86 我同时也没有说“就应该让错误看不见”。你也要注意这一点,不要没事挑刺。另外,我搬出新学,是因为我一开始也用的E_ALL,我代码的r2版本里你能看到一堆file_exist和isset,但是后来,这些错误扰乱了我正常的HTTP HEADER,于是我必须做出调整,保持程序在任何情况下都是稳定的。于是我固执的认为error_reporting这种事情就应该 = 0,然后你自己负责的好好处理,不要直接抛出。 我想我的处理方式不在各位之下吧? 当然,为了证明上述,于是我搬了一些论据,比如isset的开销。当然,@AlloVince的方法确实是最快的,条件允许我会将一些地方的file_exist改成fopen来追求速度。 但是到此为止,我只看到了我的观点,没看到各位什么观点,我想知道你们开了E_ALL,然后怎么处理?就让错误飘在页面上? |
18
Js 2013-04-29 15:51:23 +08:00
@raincious 你那个例子不确定因素太多了, 比如./test/1.txt的大小, 毕竟你file_get_contents测的全部文件, 而后者是读取的是filesize('./test/1.txt')大小.(PS: 我不认为读取大段或者全部数据fopen再fread比file_get_contents高, 两者逻辑基本一样, 后者比前者少了几次函数调用+内存再分配+字符窜拼接,只会快不会慢的).
言归正题, 文件不存在fopen一样会报warnning, 所以,按照你之前的思路, 你必须继续@fopen或者关掉警告, 至于性能,你可以把我那个例子的file_get_contents改成fopen, 差异还是那么大, 不会变的, 所以, 对待无法确定是否存在的文件, 还是在操作前判断是否存在 |
19
qq286735628 2013-04-29 15:51:41 +08:00
|
20
shiny 2013-04-29 15:52:42 +08:00
个人的习惯是开 E_ALL,像 file_get_contents 这类错误就用 @ 来屏蔽,error_handler 里可以识别是否是用 @ 屏蔽的。如果是 @ 屏蔽的则跳过,非 @ 屏蔽的则记录日志。错误级别足够高则显示自定义的 500 页面。
所以平时都不可能出现「错误飘在页面上」。 |
21
chenz 2013-04-29 15:54:32 +08:00
你不是没看到大家的观点,而是你根本选择性地失明
我再说一次我的观点,以及你选择性忽略的一些点 1. 我开E_ALL,是为了能彻底去掉所有notice以及其他错误。也就是说,我的代码的最终版本,正常情况下,是不会抛出notice或者warning或者更高级别的错误的。 2. 错误是不会飘在页面上的。开发环境下,我最多看到一次notice或者warning,一看到我就解决掉。而在生产环境,就算我不解决掉这些notice和warning,也是永远不会有任何错误显示给用户的 3. 你不能根据一个例子没有问题,就假定所有情况下都没有问题。所以单单根据你那个request来讨论是否应该开启notice或者是否该使用isset是没有任何意义的。为什么要开启notice,我之前已经说得很清楚了,你不能保证所有人,以及所有场景下,都能严格初始化变量 4. clearstatcache的问题请你回应,你不理解这个,你的测试代码就没有任何意义。当然,就算你了解了这个,你的代码依然没什么意义。但是至少往有意义的方向迈进了一步 5. ?>的问题跟本帖话题无关,但是我也希望你能阅读一下psr。而且既然你这么关注你的response http header,你就必须知道这个?>问题也是和它息息相关的 6. 你当然可以设置自己的error handler,但是处理notice或者warning这样的error没有任何意义。所有的notice和warning都应该写代码解决掉,而不是让程序处理这些错误。或许唯一的意义就是你可以写一个让自己能更快地发现这些错误的handler,然后解决掉这些notice/warning 上面几点,除了最后一点,我在之前的回复里已经提到过了。你为什么会没看到"各位的观点"呢? |
22
raincious OP 亲爱的@Js,我没有关掉警告,只是让他不显示。因为在我看来貌似多次@不如关掉,因为貌似@每一次都有消耗,屏蔽只消耗一次。然后自己做个处理,速度就快了。这些错误你之后都可以手动读出来的。
./test/1.txt - ./test/10000.txt大小都是3K左右的文件,内容相同,文件名超出部分NOT FOUND。 我来问这个问题,主要是具体的想知道大家怎么处理error_reporting。我早先写框架的时候遇到了很多很多问题,才导致我使用了这种处理方式。 所以我想知道,各位就算开了error_reporting让他直接显示,然后怎么办?遇到一条就检查初始化或者屏蔽么?我之前得到另一个做开源的开发者的一些建议(只是人家现在在做硬件之类的),说“PHP不是静态语言,(非关键情况下)不需要特意屏蔽某些错误”。当然,他是在看到我ftp那些操作的时候给我的建议。 @chenz,我还是没看到你的观点。你帖子的内容我当然都看过了。我想知道的是你遇到这种错误,具体怎么做的?我觉得你没有发挥程序员的长处:分析目的;解决问题。 那我就猜猜,你看对不对:你一般情况下都是开E_ALL,然后当出现error你就去debug掉是吧? 此外呢,其实我们的代码都不会抛出E_N、E_W,不同的是,你用PHP自己的方式处理了,配合Xdebug之类可能更好用。我用自己handler处理了,这样甚至可以直接显示给用户,但是调试麻烦。这就是我们处理方式的区别。 不知道我猜的对不对。 此外,其实就clearstatcache的问题。。。其实。。我的realpath_cache_size,是关闭的。甚至与MySQL的Connection timeout都只有1秒。我比较习惯于严苛的运行环境,这样部署的时候会比较爽。 那么焦点就是这个了:关闭E_NOTICE显示,好还是不好。(注意,不是忽略所有NOTICE错误) 另外我同意的一点是,不应该就楼主的问题来判断E_NOTICE是不是应该屏蔽显示,楼主只是变量未初始化。但是诸如unserialize失败也会有E_NOTICE。 就unserialize的例子来说吧,我一般会用 if ($a = unserialize($str)) 自行判断上面的操作有没有问题,这样的情况下,一个E_NOTICE是不是就多余了呢?而且很多情况下,你不能保证给unserialize的字符串就是他想要的啊。 |
23
python 2013-04-29 17:15:21 +08:00 1
@chenz 赞同+1
@raincious 对于变量在使用前是否先isset,还是先初始化, ============== 我的做法: $option = array( //如果是用户的输入,先isset 'file_name' => isset($_POST['file_name']) ? $_POST['file_name'] : '', //5.2.0以上可以用$fileName = filter_input(INPUT_GET, 'file_name'); ); dododo($options); function dododo(array $options) { !isset($options['file_name']) and die('need a file..'); //如果不是用户的输入,就在使用新变量前先初始化好,如$file_content; $file_content = ''; is_file($options['file_name']) and is_readable($options['file_name']) and $file_content = file_get_contents($options['file_name']); return $file_content; } 一般都是习惯于先初始化好,不可能存在不初始化的变量,也就不需要isset了 ================================ 对于这个,我觉得,在处理用户的输入时,默认值应该是为了照顾大众的习惯而设置的,不应该程序就帮用户输入了.用户的输入总是不可靠的,当然要isset了..直接$_REQUEST['visitor'] === 'yes' ,关闭了E_NOTICE, 会导致你看不到unserialize的出错时产生的E_NOTICE... 对于 error_reporting, 生产环境用0,然后写日志, 用户访问出错时显示空白或者错误提示"您访问的页面有点问题"之类的内容, 不会让错误乱飘的..开发环境用E_ALL(5.4以下用E_ALL | E_STRICT)..关于性能,@屏蔽影响往往不是重点... |
24
maomaosang 2013-04-29 18:19:59 +08:00
1.楼主你知道ini_set里面有个东西叫做display_errors么,生产环境把这个关掉,所有的报错在error.log里面全都能看到,不会飘在页面上……
2.咱们真的是E_ALL开发的,因为原则是:开发环境解决所有报错,即使是notice;生产环境关掉display_errors,用户啥报错都不会看到,如果有报错,全在log里。这是原则,雷打不动,notice都不准有。 3.我没太明白你set error handler的用意,你set一个handler,然后这个handler对所有的error处理?怎么处理?写日志?日志本身自带就有啊。难道你还写一个函数专门handle这些error?有这个时间你干嘛不写代码把error解决了。。 |
25
raincious OP @maomaosang
display_errors我当然也有做。 https://code.google.com/p/faculaframework/source/browse/trunk/include/class.oops.php#60 那么,为什么我要关掉error_reporting,其中一个原因就是,你的脚本在服务器中运行。可能你自己调试本地日志没问题,但服务器上谁也不知道。 首先,如果一个服务器上跑上百个网站,那么日志会变得很难整理,每天产生1GB的日志,我觉得没人愿意去处理。而且我这人对I/O是有洁癖的,越少越好,何况如果服务器是SSD的盘。 所以,我给一个set error handler,就能够自己筛选错误级别,程序遇到之后就会提交到调试服务器上,调试服务器自动给你整理好,方便你知道,甚至给你发个手机短信邮件什么的告诉你得回公司加个小班(还能跟绩效什么的关联起来,多好阿)。同时,这样可以避免更多人能接触到生产服务器。 可能又有人说了,写个小程序周期整理下error.log不就行了么?我觉得各有做法,我用这手比较顺而已。 当然,我觉得大家避免E_NOTICE,最主要的是避免Bad style($a[name]这样的),这一点我也有洁癖,根本不会犯这错(是的,对我来说这就是错),所以我不需要解析器帮我解决。但是至于消灭E_NOTICE,我觉得有点过了,有一刀切的意味。 关键还是在于你要知道自己在做什么,PHP会怎么反应,这反应会有什么后果。 至于isset要不要,我也有看法,我的意见是: 如果这变量经常未被设定,那么isset可以节省一点时间; 如果这个变量经常被设定,那么不使用isset会使用更多时间; 但是由于在任何情况下,节省或浪费的时间我测试50000次只相差0.05秒,还没一次页面数据库使用的时间多,所以用isset和不用,在类似对 用户是否输入 和 输入是否是真 的判断没区别的情况下,也就是习惯问题了。 我不知道我这样说@chenz是否同意。 |
26
chenz 2013-04-29 19:54:57 +08:00
1. clearstatcache跟realpath_cache_size没有任何关系。前者是清空文件系统信息的缓存(例如filemtime),后者是文件路径的realpath的缓存
2. 你说 "我之前得到另一个做开源的开发者的一些建议(只是人家现在在做硬件之类的)”。我的意见是,你叫这个"开源的开发者"好好地做硬件吧。PHP水很深,不是专业的PHP开发人员不要乱评论。 3. > 那我就猜猜,你看对不对:你一般情况下都是开E_ALL,然后当出现error你就去debug掉是吧? 你真的不用猜,我上面已经说过很多次了。我,也可能包括很多这里回复者,对notice错误是零容忍 4. 我猜你依然不知道为什么?>是个问题吧?因为你直到现在对这个都没有回应 |
27
raincious OP @chenz,建议你语气和蔼点,像我,呵呵。
1,是的因为我需要这些缓存,所以我从来不清除他们。当然也就没有自己尝试过clearstatcache。我觉得他们应该像用C++时那样,大多数情况下按提供使用。由于我对IO能省则省,所以从来没有需要手动clearstatcache的情况。这确实是一个知识缺失。 2,30年+的开发经验,C + C++ + PHP等,现在在做龙芯,元老级人物。我把他搬出来,确实是因为他说过。当然他也给了我很多不太好的建议。我正在逐步发现这些问题,包括这个帖子。当然他的很多建议我也是很受用的。 3,不设条件0容忍?我不是做不到,只是觉得一刀切方式不好,可能是管理成本问题。当然我的固然观点是,要是某人觉得你说话他不喜欢,是不是让大家都不许说?当然,让程序运行的更完美是所有程序员的目标的确。 4,?>,我觉得我的解决方案更好,于是我还是坚持自己的,这倒不是不理解,有人说?>不要更安全(为什么呢?),有人说?>不要可以避免白空间问题。但是,我没有白空间问题啊。 |
28
chenz 2013-04-29 21:17:05 +08:00
1. 你之前当然可以不知道clearstatcache,每个人都有不知道的点。但是在我给你clearstatcache的链接的情况下,你居然能扯到realpath这个东西。所以我质疑你的态度或者能力
2. 30年+经验,见识了,1983开始写程序?敢问是哪位?陈老? 3. 对notice零容忍有什么成本的?我接触的绝大多数(如果不是全部)PHP程序员和团队都是对notice零容忍。而且从来没人觉得有什么问题。你举例"你说话他不喜欢"的例子真可笑 4. 什么叫你的方案更好?你所谓的更好,是完全错误的做法。除非你每次都用hexdump检查你的PHP文件并确保最后两个字符是3f 3e,否则肯定无法确保?>是最终的两个字符。这个不但是psr规定这样,php手册也写明了这一点:http://php.net/manual/en/language.basic-syntax.phptags.php If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. 在非view文件里写?>的PHP程序员,不是个合格的程序员 |
29
chenz 2013-04-29 21:23:07 +08:00
另外,对于4. "这倒不是不理解"。你完全没理解,如果你理解,就不会说"有人说"。
"有人说","某某前辈说",在我看来,就是bullshit,完全不靠谱的来源。如果你注意到,我上面所贴的几个链接,都是权威的来源,而不是"有人说"。引用权威来源,这才是学术讨论所采用的正确的来源引用方式 |
30
ShiningRay 2013-04-29 22:20:36 +08:00
既然你这么认为就这么认为好了,自己写套nb的开源软件出来证明自己就行了,这个世界就是这样的
|
31
ljbha007 2013-04-29 22:33:51 +08:00
凡事先使用isset判断是个好习惯
有警告说明代码有问题 应该改代码 而不是把警告关掉 这是个非常坏的习惯 所以楼主叫人家改掉好习惯并且叫人家养成坏习惯当然必须down vote啊 我也down了一个 |
32
maomaosang 2013-04-29 22:34:43 +08:00
“可能你自己调试本地日志没问题,但服务器上谁也不知道。”我为什么不知道?error.log全都知道啊,这句逻辑挺混乱的我没太看懂。
"如果一个服务器上跑上百个网站,那么日志会变得很难整理,每天产生1GB的日志,我觉得没人愿意去处理。而且我这人对I/O是有洁癖的,越少越好,何况如果服务器是SSD的盘。" 如果你在本地开发时对notice零容忍,我相信线上的error.log是不可能达到1G的。 "就能够自己筛选错误级别,程序遇到之后就会提交到调试服务器上,调试服务器自动给你整理好" 你这个整理程序真的足够智能?如果你有空维护这个整理程序,为什么不愿意消灭掉notice呢。我不知道你这个整理程序是怎么个逻辑,如果对于isset的notice直接扔掉,那么导致的问题可能会很严重。因为你要知道有时候一个notice背后反映的很可能是一个feeeeetal error,只是在那个页面上没表现出来罢了。 至于小程序整理error.log,您真的有必要这么矫情么。。我们都是肉眼整理error.log的,因为里面的内容实在是少之又少。。这就是notice一刀切的好处。 其实我们这里纠结的不是用不用isset,isset执行效率是否高效,而是处理notice的态度。我不怀疑你在某些方面的技术能力,你在SO里面也的确解决了楼主的问题(其实就是个disabled嘛),但是error reporting这些细枝末节的东西,业界都总结了best practice,这些practice在我写PHP的过程中,一路使用下来,是能的的确确感受到其"best"之处。包括@chenz 说的?>问题,可能你代码习惯好,写一年代码都不会在?>后面加异常字符,但是你如果一年零一天的时候加了,你遇到这个问题,可能就调试一下午,到时候你就哭了。。平常你是没有白空间,但是万一光标在那儿,键盘无意碰了一下呢? 另外我很奇怪你用SSD的方式,完全可以挂两个盘,一个SSD一个机械HD,你log放在机械HD里面就行了嘛。。。 |
33
rqrq 2013-04-29 23:07:43 +08:00
我认为程序员必须遵守墨菲定律,lz觉得如何?
多少年的开发经验不能证明任何问题。译言网有篇讲逻辑的文章,推荐lz阅读。 |
34
dorentus 2013-04-29 23:49:43 +08:00 1
SO 上给答案减分的话是扣分人和被扣分人各减一分的
你这个 0+ 5- 的结果本身已经可以说明问题了 |
35
allenhsu 2013-04-30 00:05:59 +08:00
|
36
raincious OP @chenz 我的方案更好是比你的方案好。因为你的方案根本无法解决header的问题,仍然不可避免ERR_CONTENT_DECODING_FAILED,而我目前的方案是header队列,虽然无法保证别人不在?>后面写东西,但是我可以保证,于是我就这么写,这叫代码洁癖。别人调用自然可以用他们的方式。
我没有质疑各位的Optimalled performance。既然是为了让程序运行更好,于是我只是禁止了error_reporting,不做本地记录,但是所有的错误都更友好的被获取了。 还有,关于你那个bullshit。。。你那个10年的怎么回事?另外,我来这里询问,是想得到准确答复。为何以及如何对待E_NOTICE。这就是为什么在python给我回复之后我答谢了他。我相信这里的人应该比我更有经验处理这些问题,这跟我经常请教我那位朋友是一个心理——因为你们处理的情况多,所以我能得到更有效的答复,否则我为什么不去CSDN? 请注意,你们答复的结果对我未来说也是“听某人说”,希望这不是bullshit。 @maomaosang 如果这世界上的程序都是我写的,那我真的会保证不会有那么多INFO、WARNING、ERROR。但是这就是世界。你有程序报的错要记录,除了程序,用户输入有问题要记录、用户页面刷新太多要记录、登录操作要记录、管理操作要记录、给用户什么广告了要记录等等等等。记录个错误只是小意思,顺便而已。否则会用专门的服务器来做这个? 此外我认为,程序服务器不应该用来存储除了程序之外的东西。用户上传FTP走,缓存memcache,数据mysql,日志远程。当然,事实上我也不能保证这一点。 @rqrq 当然,但我不认为即使你抑制了E_NOTICE,就能解决全部问题不是么?我的扩展观点是,大家除了E_NOTICE,更应该关心自己的代码质量,而不是完全Test Driven。 |
37
raincious OP @allenhsu
如果array_merge中有一个参数不是数组,则会返回E_WARNING,这是没有任何办法的,所以必须 if (is_array($defaultOptions) && is_array($_GET)) { $newArray = $defaultOptions + $_GET // "有人说"更快 } |
38
lfeng 2013-04-30 01:26:43 +08:00
@dorentus 嗯,我也觉得这个0+ 5- 的结果本身已经可以说明问题了。
另外看到这个帖子的是我想到的第一个词是掩耳盗铃,当然我誓死捍卫LZ坚持自己观点的权利,其实这个问题根本就没有什么好挣的,自己觉得怎么爽就怎么用呗,反正到最后被坑的是自己,只要你不做后面接手的那个倒霉蛋就成了。 |
39
yakczh 2013-04-30 08:25:17 +08:00
stackoverflow的质量高,这是这样一步步炼成的
|
40
Leask 2013-04-30 09:29:12 +08:00 via iPad
现在才看到这个帖子,亏了。
如果早看到,我会用 @chenz 完全一样的观点回复一下楼主。 说实话,这都是十分十分基础的常识。 不谈技术,我希望楼主能消化一下大家的观点,找相关文档看看,留意一下优秀的实现是如何处理的。在充分调研后再给自己一个定论也不迟。 尊重事实,客观、虚心、耐心,我觉得是一名程序员的基本素养。 |
41
laoyuan 2013-04-30 10:13:06 +08:00
可能LZ同事啥的也上v2ex,面子上过不去。。。
|
42
raincious OP @laoyuan 还真不在。我对我自己的代码要求很严,但是对notice我是有选择处理,不是每一个notice都做屏蔽,比如如果if ($a == 'yes') 这样后面不会导致问题,那就这样好了。
说真的,我写过的代码中,从来没有因为undefined index或变量出过任何问题。所以我当然认为,关键在于你知道这个notice怎么来的,会导致什么,要如何控制,之后你怎么处理才不会导致问题是你自己的事。 当然,大家建议去掉所有导致的问题我已经了解了,事实上@AlloVince对notice已经解释的很明白,配合@python的例子,对我来说已经形成了处理的Pattern。 当然,我觉得这个帖子从一开始已经变味,我并不是在讨论是不是要彻底不管errors,而是处理方式的问题罢了。 @Leask 我真的很耐心,只是回复的信息对我来说还没形成体系才一再追问罢了。Pattren(How)有了,但是Why不完整,所以我才对回答不满意。比如我说8楼,几个表达式效果是一样的,这个问题就无人涉及,是不是因为在反正不能让notice出现这一前提下,大家都无视了那个问题呢。 我真心希望是你回答了我的问题。谢谢。 |
43
ShiningRay 2013-04-30 12:33:04 +08:00
楼主如果你发这贴是为了寻找认可和共鸣我觉得就错了。
可能楼主剑走偏锋,有自己的一套打法,但你的经验可能适合你的工作环境,对别人来说则可能不合适,最后站在不一样的立场上进行讨论,最后讨论只能变味。 所以,你应该把自己的方法论给完整的梳理一遍,可以考虑自己写一个系列的文章,把自己的经验总结一下,让大家明白和清楚。 简单的说,等你出名了自然有人捧你。 |
44
Leask 2013-04-30 12:33:11 +08:00 via iPad 1
有时候我们不但要考虑代码在小范围内是否流畅运行。当然,这和你参与项目的规模和复杂程度有关。我留意到你提到你是写框架的。我在连续两家公司是做后端框架的。你应该知道很多时候你不能完全预料一切的input都是可以预料的。如果在框架层不能做到 notice free 的话,我觉得代码是没有达到要求的。至于你说你也对代码要求也很高,我只能说不同的人对「高」的理解不一样。
其次,作为越靠近后方的开发者,你必须明白自己提供的基础设施必须是尽可能可靠的。那么,你处理异常的方式应该尽可能地符合「最佳实践」这样有助于你的同事和你提供的api的「开发者用户」更能理解。 鉴于这几点,真的不要问 why 了。 |
45
Cadina 2013-04-30 12:37:46 +08:00
大家不要再喷LZ了,LZ是来卖萌的。。
(把NOTICE关掉,我看不见啊,看不见~~) |
46
davepkxxx 2013-04-30 12:39:57 +08:00
这就和Java里不论什么情况,直接把异常给捕获,也不给交代,或者直接网上抛差不多。
|
47
raincious OP @Leask 刚才尝试下将我框架内的Notice修补,由于我用数组很多,很多数组在类里面 public $array = array(); 就好了,之后就动态使用,需要时判断,所以很多Undefined Index。
但是改掉这些之后,目前看来没什么收益,当然也没什么损失,可能是因为框架比较老的缘故,还有待观察。我写这个框架的时候Discuz还是7,也有一堆堆的Undefined,Wordpress里面当时也是一堆Undefined,phpBB里面也是一堆Undefined、IPB和VBB里也是一堆Undefined。于是这么多Undefined,我对Undefined也就没感觉了,觉得就应该这样。 反正目前正在准备新框架了,因为目前的框架是为规模不大的网站设计的,很多东西没有灵活的考虑到,比如插件、PDO和ORM之类。新框架写的时候会注意Undefined这样的问题。目前的架构处于稳定性考虑就先如此好了。 现在Wordpress用新架构之后倒是没有多少Notice了,可能去掉Notice这是趋势吧。用新的OO风格去写,可能本身Notice也不会很多。 |
48
evlos 2013-04-30 22:48:08 +08:00
恩,没人能 100% 保证自己这辈子不会做什么事情,也没人能 100% 保证自己有一天不会手滑而且手滑的时候不会造成巨大的损失,所以大家的建议都是关于尽量地养成不留隐患的好习惯。
我的习惯主要是一般数组都要看看 index 是否存在,文件也得看看是否存在,变量如果初始化了一般不用管,但是用户输入的一定要看看 $_POST['xxx'] 之类的有没有输入进来,输入进来之后最好拿正则式检查一遍。 开发环境一定 E_ALL | E_STRICT。 生产环境 E_ALL & ~E_DEPRECATED,display_error 关掉。 日志非常重要,大型网站一般配备日志服务器,可以从此看出日志的重要性,就算不重要的日志,也可能成为某些隐患。 |