V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX  ›  PHP

PHP 有没有什么办法能兜住异常别抛 404?

  •  
  •   abcbuzhiming · 2017-03-01 15:08:29 +08:00 · 4957 次点击
    这是一个创建于 2585 天前的主题,其中的信息可能已经有所发展或是发生改变。
    php 的 try catch 很多异常和错误根本兜不住,网上很少有说 php 如何优雅的处理各种异常 error 的方法,请有经验的前辈指点一下
    42 条回复    2017-03-04 09:12:38 +08:00
    narcotics
        1
    narcotics  
       2017-03-01 15:10:38 +08:00
    404 为啥要兜住。。。?不存在就是不存在啊。。。
    Livid
        2
    Livid  
    MOD
       2017-03-01 15:11:39 +08:00
    tmkook
        3
    tmkook  
       2017-03-01 15:21:28 +08:00
    PHP7 有个新特性,只要 catch Exception 就能捕获所有异常
    a136572301
        4
    a136572301  
       2017-03-01 15:32:44 +08:00
    活捉,站长-。-
    abcbuzhiming
        5
    abcbuzhiming  
    OP
       2017-03-01 15:34:44 +08:00
    @narcotics 你要是用用过 java , C#这类语言就明白有异常处理在 IO 的时候能省多少事了
    abcbuzhiming
        6
    abcbuzhiming  
    OP
       2017-03-01 15:36:32 +08:00
    @tmkook 我靠,你这样一说,我突然发觉,我这可能不是异常,而是比异常更高级的东西,因为我用的就是 php7.0.14 ,我用了你说的 catch Exception 。反正就是读个 excel ,那个 excel 文件是有问题的。然后代码就完蛋了,根据日志的结果,到那行代码直接不往后执行了,就像那行代码变成了 die()一样
    abcbuzhiming
        7
    abcbuzhiming  
    OP
       2017-03-01 15:47:13 +08:00
    @Livid 我仔细看了一下这个 sentry ,它好像不能抓住错误现场并立即处理啊?
    panlilu
        8
    panlilu  
       2017-03-01 15:58:15 +08:00
    404 什么的不是可以在 nginx 那层解决么。。
    jswh
        9
    jswh  
       2017-03-01 15:59:09 +08:00
    set_exception_handler
    set_error_handler
    register_shutdown_function
    PigKnife
        10
    PigKnife  
       2017-03-01 16:00:28 +08:00
    大兄弟, catch Error 试试
    surfire91
        11
    surfire91  
       2017-03-01 16:15:35 +08:00
    "很多异常和错误根本兜不住"
    比如那个异常或错误?
    兜不住怎么理解?

    “ PHP 有没有什么办法能兜住异常别抛 404 ”
    404 是指 http code 404 吗? 这个一般都是 web server 抛的,还没到 php 处理。
    abcbuzhiming
        12
    abcbuzhiming  
    OP
       2017-03-01 16:16:55 +08:00
    @panlilu 我需要在出现错误后进行逻辑处理,在 nginx 那块处理 404 仅仅是对客户端友好,不能解决逻辑问题
    Felldeadbird
        13
    Felldeadbird  
       2017-03-01 16:17:08 +08:00
    我个人见解是因为 PHP 的错误提示机制 和后面引入的异常 存在定位重复,所以 PHP 的异常机制一直比较不实用。参考#9 的做法,自定义一个全局的异常机制,可以比较优雅解决。
    但是呢,有些错误必须手动 throw 。不像其他语言自动去抓取。
    abcbuzhiming
        14
    abcbuzhiming  
    OP
       2017-03-01 16:17:13 +08:00
    @PigKnife 请教如何 catch error
    abcbuzhiming
        15
    abcbuzhiming  
    OP
       2017-03-01 17:00:28 +08:00
    @surfire91 我描述不准确吧,应该是 php error 了, http server 就抛出 404 了,我是希望能把 php 的 error 都兜住,并且进行善后处理(避免下次到这继续 error ,因为有些 error 是用户故意上传某些文件造成的,要把这些垃圾删掉),别的语言很简单, try catch 就行了, php 就不行
    ParallelMao
        16
    ParallelMao  
       2017-03-01 17:02:54 +08:00
    LukeXuan
        17
    LukeXuan  
       2017-03-01 17:08:00 +08:00
    404 不应该是找不到的时候抛出的么 就算你 error handling 不对也是 500 吧
    surfire91
        18
    surfire91  
       2017-03-01 17:14:18 +08:00
    php5 没法 catch error 只能通过 set_error_handler , php7 可以,见 http://php.net/manual/zh/language.errors.php7.php
    learnshare
        19
    learnshare  
       2017-03-01 17:20:21 +08:00
    404 有两种吧,一个是请求静态资源,那应该在 Nginx 处理;另一个是动态资源,那就 catch 到错误(或许应该算 500 )
    lxm
        20
    lxm  
       2017-03-01 17:33:48 +08:00
    自己写 router ,匹配不到转向 404 处理页面
    jarlyyn
        21
    jarlyyn  
       2017-03-01 17:42:38 +08:00
    404 是异常或则错误么?

    难道不是个 header ?
    wdlth
        22
    wdlth  
       2017-03-01 21:18:13 +08:00
    你说的是框架找不到路由时抛出的 404 ?
    HarveyDent
        23
    HarveyDent  
       2017-03-01 22:11:09 +08:00
    搭车问一个问题,使用某个库,这个库出错了以后返回错误码,并且 echo 了一串错误信息。这个能捕获到吗,我不想把这个东西 echo 出去啊。
    Jakesoft
        24
    Jakesoft  
       2017-03-01 22:43:12 +08:00
    @HarveyDent php.ini 中有个 display_errors 指令,设置为 off 就可以不显示错误了,线上环境一般都会这样设置吧。
    mingyun
        25
    mingyun  
       2017-03-01 23:21:11 +08:00
    404 再跳转首页
    macroideal
        26
    macroideal  
       2017-03-01 23:29:43 +08:00
    if 单入口, 在 Php 里设置异常处理的勾子
    else 修改 php.ini
    R18
        27
    R18  
       2017-03-01 23:37:11 +08:00 via Android
    404 不是 php 扔出去的吧,是 web 服务器
    SummerWQM
        28
    SummerWQM  
       2017-03-01 23:54:10 +08:00
    自己设置 http 协议响应头就可以了呀, 想根据 业务 跑出具体的响应头 一般会在 php 层做的。
    shiny
        29
    shiny  
       2017-03-02 00:03:35 +08:00
    有时候 php-fpm 进程会崩掉,出现过两次这种情况了。
    leeg810312
        30
    leeg810312  
       2017-03-02 01:03:57 +08:00 via Android
    程序出错不是 5 开头吗? 4 也算?是我学错了么
    daryl
        31
    daryl  
       2017-03-02 07:23:33 +08:00 via iPhone
    等一下……一直懵逼 404 不是 webserver 抛出的么…
    dawniii
        32
    dawniii  
       2017-03-02 07:47:21 +08:00
    就算 php 是抛出的也是 500 啊,老实说你是不是用的 thinkphp3.* 他家的框架全局抛出异常直接给 404 状态码。。。之前坑我一次。
    wwolf
        33
    wwolf  
       2017-03-02 08:31:25 +08:00
    可以自定义异常类, response 之前直接捕获进行处理
    wizardoz
        34
    wizardoz  
       2017-03-02 09:31:23 +08:00
    何不考虑把 404 页面做得漂亮一点?
    narcotics
        35
    narcotics  
       2017-03-02 10:03:21 +08:00
    @abcbuzhiming 我没写过 php ,但不管 C# Java Golang Nodejs 不管任何写 Web 的语言, 404 就是 404 not found ,你可以做个漂亮的 404 页面,你可以 404 之后再做跳转,但是绝不是把它“兜住”隐藏起来

    况且什么样的“异常”会导致 404 我也是很好奇
    zencoding
        36
    zencoding  
       2017-03-02 11:12:42 +08:00
    catch Error
    abcbuzhiming
        37
    abcbuzhiming  
    OP
       2017-03-02 11:39:02 +08:00
    @dawniii 你说对了,就是 TP3.x
    abcbuzhiming
        38
    abcbuzhiming  
    OP
       2017-03-02 11:40:38 +08:00
    @surfire91 我跪了,太奇怪了,我本来就是 PHP7.0.10 ,无论是 catch error 还是 set_error_handler 我都试过了,这个 php_reader 读取错误 xls 格式引发的错误,还是抓不住,这难道既不是 expection ,也不是 error 吗,这到底是什么东西啊
    surfire91
        39
    surfire91  
       2017-03-02 12:00:57 +08:00
    @abcbuzhiming 有示例吗
    abcbuzhiming
        40
    abcbuzhiming  
    OP
       2017-03-02 14:19:32 +08:00
    @surfire91 谢谢各位为了回答了这么多,今天研究了半天,终于发现自己其实是被框架坑了,并不是抓不住异常,而是在这个框架里,所有的类都必须基于命名空间所对应的路径来调用, PHP 的 Exception 是基类,所以必须写成
    catch (\Exception $e);写成 catch (Exception $e),这个框架就认为不存在这个类,但是它不报错,直接把异常甩到上层去了。。。我在这卡了两天。直到刚才左想右想不对于是用原生代码来试才发现这个坑
    TIGERB
        41
    TIGERB  
       2017-03-02 14:36:33 +08:00
    ```
    register_shutdown_function();
    error_get_last();


    set_error_handler();
    ```
    dawniii
        42
    dawniii  
       2017-03-04 09:12:38 +08:00
    @abcbuzhiming 不是不报错,是 tp3.x 直接把全局捕获的异常写了 404header 。然后你的 nginx 设置接管 404 页面。所以你没看到错误信息。这个真的是坑爹,上次我以为我们线上网站被人删除了。。。 真的坑
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2434 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 15:56 · PVG 23:56 · LAX 08:56 · JFK 11:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.