处理 php 页面错误的最佳方法?

2024-03-25

现在我的页面看起来像这样:

if($_GET['something'] == 'somevalue')
{
    $output .= 'somecode';

    // make a DB query, fetch a row
    //...
    $row = $stmt->Fetch(PDO::ASSOC);

    if($row != null)
    {
        $output .= 'morecode';

        if(somethingIsOK())
        {
            $output .= 'yet more page output';
        }
        else
        {
            $error = 'something is most definitely not OK.';
        }
    }
    else
    {
        $error = 'the row does not exist.';
    }
}
else
{
    $error = 'something is not a valid value';
}

if($error == '') // no error
{
    //display $output on page
}
else // an error
{
    // display whatever error occurred on the page
}

我做事的方式是有效的,但是对于可能显而易见的事情来说,它非常麻烦和乏味:假设我在代码中间的某个地方调用一个函数,或者想要检查变量的值,或者验证数据库查询返回一个有效的结果,如果失败我想输出一个错误?我必须创建另一个 if/else 块并将所有代码移至新的 if 块内。这似乎不是一个聪明的做事方式。

我一直在阅读有关 try/catch 的内容,并一直在考虑将所有代码放入 try 语句中,然后让代码按顺序运行,而无需任何 if/else 块,如果出现问题,只需抛出异常。根据我的阅读,这将停止执行并使其直接跳转到 catch 块(就像失败的 if 语句将转到 else 块一样),然后我可以在其中输出错误消息。但这是可接受的或标准的做法吗?

在构建和输出 HTML 页面的 php 应用程序中,处理错误(致命或非致命)的最佳方法是什么?我不想死在空白屏幕上,因为这对用户非常不友好,而是想在页面正文中输出一条消息,同时仍然允许显示页眉和页脚。

谢谢你的建议!


有很多方法可以解决这个问题,但坦率地说,没有一种方法本质上是“正确的”。

您必须自己决定哪种方法对您来说更“舒适” - 这始终是一个偏好问题(尽管有些技术您应该避免并且有充分的理由)。

这在很大程度上取决于您如何分割逻辑,但是我倾向于将所有可以返回非致命错误的代码包含在函数内,并使用所述函数的返回值来指示存在错误。

For 致命错误 http://en.wikipedia.org/wiki/Fatal_error我倾向于使用异常(与try-catch块)。

现在要明确的是:

  • 非致命错误是指您可以recoverfrom - 意味着即使出现问题,仍然有一些代码可以执行并生成一些有价值的输出。例如,如果您想使用获取当前时间NTP协议,但服务器没有响应,您可以决定使用本地time功能并仍然向用户显示一些有价值的数据。
  • 致命错误是您无法纠正的错误recoverfrom - 意味着发生了非常糟糕的事情,您唯一能做的就是告诉您的用户该页面无法执行其要求的操作。例如,如果您从数据库中获取一些数据并得到SQL Exception- 没有可显示的有价值的数据,您只能告知用户这一点。

非致命错误(使用函数返回)

使用函数返回作为处理非致命问题的一个很好的例子是尝试在页面上显示某些文件的内容的函数当这不是页面的主要目标时(例如,您将有一个在每个页面上显示从文本文件中获取的徽章的功能 - 我知道这是牵强的,但请耐心等待)。

function getBadge($file){
    $f = fopen($file,'r');
    if(!$f){
        return null;
    }
    .. do some processing ..
    return $badges;
}

$badges = getBadges('badges.txt');
if(!$badges){
    echo "Cannot display badges.";
} else {
    echo $badges;
}
.. carry on doing whatever page should be doing ..

事实上,该函数fopen它本身就是一个例子 -它会返回 http://php.net/manual/en/function.fopen.php.

成功时返回文件指针资源,错误时返回 FALSE。


致命错误(使用异常 - try-catch)

当你有一段代码需要执行因为这正是用户想要的(例如从数据库读取所有新闻并将其显示给用户),所以您可以使用异常。让我们举一个简单的例子 - 用户访问了他的个人资料并希望查看他收到的所有消息(现在假设它们以纯文本形式存储)。你可能有这样的功能:

function getMessages($user){
    $messages = array();
    $f = fopen("messages_$user.txt","r");
    if(!$f){
        throw new Exception("Could not read messages!");
    }
    ... do some processing ...
    return $messages;
}

并像这样使用它:

try{
    ..do some stuff..
    $messages = getMessages($_SESSION['user'])); //assuming you store username in $_SESSION
    foreach($messages as $msg){
        echo $msg."<br/>";
    }
} catch(Exception $e){
    echo "Sorry, there was an error: ".$e->getMessage();
}

现在,如果您有一个可以执行所有其他代码的“顶级”脚本,这可能会派上用场。这意味着,例如,在您的index.php你只会有:

try{
    .. execute some code, perform some functions ..
} catch(Exception $e){
    echo "Sorry, there was an error: ".$e->getMessage();
}

不要过度使用异常!

无论您做什么,都不要使用异常来检查可以恢复的内容。读一读关于另一个问题 https://stackoverflow.com/questions/729379/why-not-use-exceptions-as-regular-flow-of-control(全部归功于安东·戈戈列夫对于这一点以及其他回答者有很好的解释)为什么会出现这种情况。

进一步阅读

现在,学习如何处理错误的最好方法莫过于尝试几种方法,看看什么对你有好处。您可能会发现以下有用:

  • W3School 关于 PHP 异常处理 http://www.w3schools.com/php/php_exception.asp
  • 关于错误处理的简短教程 http://www.htmlgoodies.com/beyond/php/article.php/3472561/PHP-Tutorial-Error-Handling.htm(类似于我的函数返回方法)
  • 有关 PHP 错误处理的详细教程 http://www.devshed.com/c/a/PHP/Error-Handling-in-PHP-Coding-Defensively/- 包括使用trigger_error()函数,我没有提到它,因为我不使用它,对它了解不多,但显然它确实很有用。这是一本特别好的读物。

希望这可以帮助 :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

处理 php 页面错误的最佳方法? 的相关文章

  • 压缩 zend Framework 2 的 html 输出

    我目前正在 PHP 5 4 4 上使用 Zend Framework 2 beta 开发个人 web 应用程序以用于自学目的 我想知道是否可以在 html 输出发送到浏览器之前拦截它 以便通过删除所有不必要的空格来缩小它 我怎样才能在ZF2
  • Magento - 将特定父类别的子类别列为链接

    我是 php 的初学者 并且一直试图将一个父类别的子类别作为链接调用 我得到了这个 它调出了 getName 但 getUrl 根本没有返回任何 URL 输出代码只是 li a href name of sub a li
  • 私人聊天系统MYSQL查询显示发送者/接收者的最后一条消息

    在这里我延伸一下我之前的问题 私人聊天系统MYSQL查询ORDERBY和GROUPBY https stackoverflow com questions 10929366 private chat system mysql query o
  • php表格:每行显示3个单元格[重复]

    这个问题在这里已经有答案了 我看这里 数组放入每行 5 个单元格的表格中 https stackoverflow com questions 9099568 array into a table with 5 cells in each r
  • 如何在 Zend Framework 中存储 cron 作业的脚本?

    因为 ZF 的所有 URL 都依赖于 mod 重写 所以我并不清楚应该在哪里存储用于 cron 作业的本地脚本 有人有什么建议 或者有 正式接受 的方式吗 我用模块化目录结构 http framework zend com manual e
  • 无法以编程方式反序列化 SOAP 消息

    当我尝试反序列化肥皂消息时 出现以下异常 我这样做是因为我有想要在测试中重用的响应文件 我无法使用真正的服务等 因为它不适合我们拥有的测试框架的架构 Test MyUnitTestMethod failed System InvalidOp
  • Zend IMAP 搜索和过滤器

    我如何使用 Gmail 中的过滤器进行搜索 就像获取带有特定标签的电子邮件列表或来自特定电子邮件地址的邮件列表一样 我无法在文档中找到它 注意 我使用 oAuth 进行身份验证 我希望这与搜索无关 Gmail 上的标签实际上是 从 IMAP
  • Spring Integration中的异常:如何记录但不拦截

    假设我有一个基本的 Spring 集成流程 例如
  • 使用 php 更改白天和黑夜的背景?

    我正在制作一个 tumblr 页面 我的 html 页面有两种不同的背景 我希望白天背景从早上 7 点到晚上 8 点显示 夜间背景从晚上 8 点到早上 7 点显示 我决定用 php 来做这件事 但对于 php 来说我是个新手 我的朋友给我发
  • php - 我应该加密电子邮件地址吗?

    当用户注册时 我应该将他们的电子邮件按原样存储在数据库中还是对其进行哈希处理 我希望稍后能够解密 那么我应该使用 md5 吗 谢谢你 No md5 is 单向哈希函数 http en wikipedia org wiki Cryptogra
  • php 中的简单授权/登录功能

    我希望第一次实现用户登录到我的网站 我很高兴构建自己的解决方案 或者实现一些开源的东西 但是到目前为止 在我的搜索中没有任何包是明显的选择 同样 我完全意识到 作为一名中级 php 程序员 如果我推出自己的解决方案 并真正敞开大门 我很可能
  • 将函数中的会话变量传递给 codeigniter 中的助手

    这就是我正在尝试做的事情 这是控制器中的功能 public function get started if test login this gt session gt all userdata this gt load gt view te
  • 如何以编程方式获取 WooCommerce 中的所有产品?

    我想获取 WooCommerce 中的所有产品数据 产品 sku 名称 价格 库存数量 可用性等 我可以使用 wp query 来做到这一点吗 这样你就可以通过 wp query 获取所有产品 global wpdb all product
  • 如何将异常序列化为Json

    C 异常是 ISerialisable 因此它们不能也是 DataContract 因此我无法使用 JsonDataContractSerializer 将异常序列化为 JSON 的替代方案是什么 由于这个问题还没有真正得到解答 只需创建一
  • 如何将 mysql 转换为 mysqli? [复制]

    这个问题在这里已经有答案了 我厌倦了将 mysql 转换为 mysqli 但似乎收到了很多错误和警告 连接到数据库没有问题 但其余代码似乎错误 我做错了什么 sql
  • Laravel 按动态 ID 数组对集合进行排序 [重复]

    这个问题在这里已经有答案了 我有以下 people array 5 2 9 6 11 people collection People find people 但当我倾倒并死去时 people collection集合按 ID ASC 排序
  • 如何在 HTML / Javascript 页面中插入 PHP 下拉列表

    好吧 这是我的第二篇文章 请接受我是一个完全的新手 愿意学习 花了很多时间在各个网站上寻找答案 而且我几乎已经到达了我需要到达的地方 至少在这一点上 我有一个网页 其中有许多 javascript 函数 这些函数一起使用 google 地图
  • Azure 上的“phpcomposer.phar install”出现“无法终止进程”错误

    我正在尝试将我的 Symfony 2 应用程序部署到 Microsoft Azure 网站云 为此 我按照本指南中的步骤操作http symfony com doc current cookbook deployment azure web
  • postgreSQL 在 WAMP 上的集成

    我刚刚在 Windows 7 上安装了 postgreSQL 我正在尝试将 postgreSQL 与 WAMP 服务器集成 为此 我在 httpd conf 和 php ini 文件中进行了以下更改 1个加载模块c path to libp
  • php 表单提交 - Q2

    我对这个虚拟问题感到抱歉 这是我的简单 PHP 表单 其中包含两个 SQL 表和 ADD 提交 按钮 我希望将人员从 Test1 转移到 Test2 很多事情都很好 只有提交按钮不起作用 因此 Test2 表没有反馈 Revised 现在提

随机推荐

  • 正则表达式匹配数字和字符

    如何创建仅匹配字符和数字的正则表达式 这个正则表达式匹配宽度数字 D g 如何添加类似字符 等等 仅匹配字母和数字 A Za z0 9 将所需的字符添加到上述字符类中 以匹配该特定字符 A Za z0 9 您可以将上述正则表达式减少为 w
  • 渲染表格中的下标/上标(闪亮)

    我在一个闪亮的应用程序中有一个数据表 我想在其中添加上标到我的观察结果中 这些应该详细说明观察结果是否是估计值 以及观察年份距参考年份有多远 此数据已经在我的数据集中 例如 特定的观察结果可能显示 75 上标 3 e 这可能吗 我今天也有同
  • $sce:itype 尝试信任需要字符串的内容中的非字符串值:上下文:resourceUrl

    我想播放存储在我的 sails 服务器中的歌曲 路径是http localhost 4000 images 123 mp3 在前端 我使用 ng repeat 列出来自服务器的歌曲 div div i class fa fa play ci
  • helm 图表中的动态命名空间变量

    我与四个团队合作 他们使用在 kubernetes 命名空间中设置的完全相同的环境 我创建了 helm 图表来安装这些环境 一切正常 但由于主机名格式如下 我必须手动创建入口
  • ClickOnce 快捷方式无法启动应用程序

    我在 VS 2017 中创建了一个使用 ClickOnce 安装的 WPF 应用程序 将解决方案部署到网络位置后 我可以通过访问 application 链接在我的 64 位 Windows 10 计算机上安装 但是 该应用程序安装后无法在
  • 完成时更新整个

    编辑单元格后 我很难重新渲染 PrimeFaces 数据表 更改一个单元格中的值可能会更改其他单元格中的条目 因此需要刷新整个表格 这是 JSF 页面
  • 如何与 Kivy GUI 一起运行 Tornado 事件循环?

    我的客户端应用程序使用KivyGUI Kivy 有自己的事件循环 并使用 WebSocket 协议连接到服务器Tornado Tornado 也有一个事件循环 这就是连接部分是异步的原因 我希望用户在 Tornado 客户端运行监听服务器消
  • 如何删除 NSMutableArray 中具有相同属性值但只有一个的所有对象

    我有一个带有 url 字符串属性和标题的历史对象 我想搜索 URL 包含搜索字符串的对象的所有历史记录 然后删除所有重复项 例子 我有一系列历史对象 其中 20 个都是 https www google com https www goog
  • C# Winforms 复选框不指示焦点

    如果复选框是 Tab 键顺序 0 中的第一个控件 则在显示表单时并不表示它具有焦点 事实上 它确实具有焦点 您可以通过按空格键来选中 取消选中控件来演示这一点 如果您先按 Tab 键 然后按 Shift Tab 键返回到该复选框 则标签会出
  • 闪亮滑块输入从最大到最小

    是否可以制作一个以降序显示值的 sliderInput 从左到右 例如 5 4 3 2 1 runApp list ui fluidPage sliderInput test min 5 max 1 value 3 step 1 serve
  • 在Java中将BufferedImage转换为Mat(OpenCV)[重复]

    这个问题在这里已经有答案了 我试过这个link https stackoverflow com questions 14958643 converting bufferedimage to mat in opencv并有下面的代码 我的程序
  • WPF 窗口不会释放其资源,直到程序终止

    我一直在阅读有关 WPF 内存处理的内容 并跟踪了前 5 个和前 8 个内存泄漏陷阱 但在我目前的情况下没有任何帮助 我的软件有一个问题 WPF 在程序终止之前不会释放内存 如果我永远让它消失 无论我做什么都会导致 OutOfMemoryE
  • PHP - 从文件名字符串中删除扩展名

    我想从文件名中删除扩展名 并获取文件名 例如file xml gt 文件 image jpeg gt 图像 test march txt gt test march 等 所以我写了这个函数 function strip extension
  • 在 irb 中重新加载 ruby​​gems?

    我现在有这个脚本 def r this require this puts this is now loaded rescue LoadError puts The gem this is missing puts Should I ins
  • 为什么 List.ForEach 比标准 foreach 更快?

    考虑一下 必备条件 The alphabet from a z List
  • 如何使用 Erlang 发送推送通知?

    我正在尝试使用 Erlang 向 APNs 发送推送通知 这是我到目前为止想出的代码 module apnstest2 export connect 0 connect gt application start ssl ssl seed s
  • 在Python re中仅匹配unicode字母

    我有一个字符串 我想从中提取 3 个组 19 janvier 2012 gt 19 janvier 2012 月份名称可以包含非 ASCII 字符 因此 A Za z 对我不起作用 gt gt gt import re gt gt gt r
  • R-因子箱线图中的组抖动? [复制]

    这个问题在这里已经有答案了 是否可以将抖动分组到像我这样的箱线图中 以便数据点与每个市场的因素一致 现在它正在按市场名称排列 我给它们上了颜色以显示哪些应该被分组 My code p lt ggplot droplevels subset
  • setOffscreenPageLimit() 如何通过保留更多屏幕外 Fragment 来提高 ViewPager 性能?

    我有一个ViewPager控制五个Fragments 当我从Fragment在索引 1 到Fragment在索引 0 处 动画中有短暂的停顿我想消除的 目前 我没有打电话setOffscreenPageLimit 所以我知道Fragment
  • 处理 php 页面错误的最佳方法?

    现在我的页面看起来像这样 if GET something somevalue output somecode make a DB query fetch a row row stmt gt Fetch PDO ASSOC if row n