【问题标题】:Need some advice on error handling in PHP / mysql需要一些关于 PHP / mysql 错误处理的建议
【发布时间】:2009-06-10 13:08:30
【问题描述】:

我不确定在向最终用户提供 READABLE 反馈时最好使用哪种方法。我已经阅读了一些论坛,但并没有真正变得更明智(或者我没有理解它)

我想在插入/更新失败、成功以及提供自定义反馈(例如检查项目是否已经存在)时提供反馈。

在 INSERT、UPDATE、DELETE、DROP 等操作中,查询返回 TRUE 或 FALSE。 因此,我的结果属性 $this->query_result 应该始终为 true 或 false。

我的问题:

  • 向用户动态显示反馈 表单提交后(提交给相同的 页)
  • $this->query_result 为真,如果它 返回一个字符串

我添加了代码来看看我在做什么(做错了)

这些是我用来连接/查询数据库的函数:

  public function connect() 
  { 

      if (!($this->conn = mysql_connect($this->host, $this->username, $this->pwd)))  {
         die("Error connecting to DB by user = " . $this->username); 
      } 

      $this->db = mysql_select_db($this->dbname,$this->conn) 
        or die("Unable to connect to database " . $this->dbname); 
  }  

  private function query($sql) 
  {
      $this->query_result = mysql_query($sql, $this->conn)or die("Unable to query local database <b>". mysql_error()."</b><br>$sql"); 

      if (!$this->query_result){ 
          die("database query failed."); 
      } else { 
          return $this->query_result; 
      }
  } 

这是我的问题:我正在提供有关数据访问层 (DAL) 的反馈,请参阅例如这个:

  public function addNewPerson($formData)
  {
    $sql = "INSERT INTO my_table(`name`, `email`, `www`)";

    $sql .= " VALUES('".
      $formData['name']."','".
      $formData['email']."','".
      $formData['www']."','");

   $this->query($sql);
   return $this->query_result;
  }

通过返回文本字符串,返回结果将始终为真。 根据我的阅读,我可能应该有一个处理错误/反馈的函数。

这就是我目前对模板中的反馈所做的事情:

  if (isset($_POST['form_submit']))
  {

    if (isset($_POST['person_submit'])) {
      $formData = $sl->getFormData();
      $result = $myDB->addNewPerson($formData);

      if ($result == true)
      {
        echo '<script type="text/javascript" language="JavaScript">
              jQuery("#contentArea .messageWindow1").show(500);
              jQuery("#contentArea :input").click(function(){ jQuery("#contentArea .messageWindow1").hide(500); });
        </script>';
      } else {
        echo '<script type="text/javascript" language="JavaScript">
              jQuery("#contentArea .messageWindow2").show(500);
              jQuery("#contentArea :input").click(function(){ jQuery("#contentArea .messageWindow2").hide(500); });
        </script>';
      }
    }
  } 

<div id="contentArea">   
  <div class="messageWindow1"> <span class="msg"><?php echo $labelResult ?></span></div>
  <div class="messageWindow2"> <span class="msg"><?php echo $labelResult ?></span></div>
</div>

【问题讨论】:

    标签: php mysql feedback


    【解决方案1】:

    我会使用 PHP5 的内置异常处理来捕获错误和可能的验证错误。例如:

        class DatabaseException extends Exception {}
        class ValidatorException extends Exception {}
    
             public function connect() 
              { 
    
                  if (!($this->conn = mysql_connect($this->host, $this->username, $this->pwd)))  {
                     throw new DatabaseException("Error connecting to DB by user = " . $this->username); 
                  } 
    
                  if(!($this->db = mysql_select_db($this->dbname,$this->conn))) { 
                    throw new DatabaseException("Unable to connect to database " . $this->dbname);
     }
              }  
    
        //....
    
    
        public function addNewPerson($formData)
          {
            $sql = "INSERT INTO my_table(`name`, `email`, `www`)";
    
            $sql .= " VALUES('".
              $formData['name']."','".
              $formData['email']."','".
              $formData['www']."','");
    
           //If less than 2 characters, do not insert data.
           if (strlen($formData['name']) < 2)
            throw new ValidatorException( "Person not saved. Name field was to short or empty.");
    
           //If person already exists
           if($this->isPersonInList($formData['name']))
            throw new ValidatorException( "Person already exists!");
    
           //Process query
           $this->query($sql);
           return $this->query_result;
          }
    

    在调用脚本中

    try {
    $formData = $sl->getFormData();
    $result = $myDB->addNewPerson($formData);
    } catch (DatabaseException $e) {
    // display $e->getMessage()
    } catch (ValidatorException $e) {
    //display $e->getMessage()
    }
    

    您的脚本需要指出的其他几件事。

    1. 最好使用PDO并准备好 声明。
    2. 你也可以使用下面的方法来判断字符串长度是否为 见过。
    $arr = '肖恩'; var_dump(isset($arr[10])); //错误的 var_dump(isset($arr[2])); //真的
    1. 过滤 sql 的输入 之前的注入/XSS 漏洞利用 将其推入您的数据库或 在您的应用程序中使用它。

    【讨论】:

    • 这是一个很好的例子。谢谢!是的,我知道。当我提出基础知识时,我将重构我的代码。我首先必须学习 PDO 以及如何在 MySQL 中使用准备好的语句。在将输入发送到数据库之前,我还将对其进行过滤。我正在尝试找出他最好的方法来做到这一点。
    • 哦,一个问题。如果插入/删除由于约束问题或重复条目(唯一键)而失败怎么办。我将如何捕捉它?
    • 这不起作用 :( 我得到“解析错误:语法错误,意外的 T_THROW”。这是 connect() 函数中的“抛出”。
    • 我想我已经修好了,但还没有验证。
    • 谢谢。我会测试它。我遇到了另一个问题。我正在尝试扩展我的 DAL 类以使用 PDO ->“class DAL extends PDO {}”。但是当重新加载页面时,它完全是空白的 - 没有任何数据。我正在使用 PHP v.5.2.6,并且启用了以下扩展:php_pdo、php_pdo_mysql 和 php_pdo_sqlite。
    【解决方案2】:

    只有一个提示:在编程 OO 时应该使用异常。例如,您可以针对不同的错误反馈引入不同的异常。

    class ValidationException extends Exception
    {}
    
    class DatabaseExceptionextends Exception
    {}
    
    throw ValidationException("Person not saved. Name field was to short or empty.");
    throw DatabaseException("database query failed.");
    

    然后你捕获所有这些异常并根据异常的类型做出不同的反应。

    try {
        // ...
    }
    catch (ValidationException $e) {
        // ...
    }
    catch (DatabaseExceptionextends $e) {
        // ...
    }
    

    【讨论】:

    • 谢谢菲尔。我只在 .Net 中使用过 try/catch - 基本上只是你示例的最后一部分。你为什么要上课?你不能从catch里面抛出错误信息吗?嗯......我有点不确定如何使用它 - 即使你有一个干净而漂亮的例子(对不起)
    • Steven,他主要继承了标准 Exception 类,因此它们可以作为不同类型错误的标记。它使您的代码更具可读性和分隔性。但是过度使用是没有用的,因为那只会造成没人能理解的混乱。有关相关问题,请参阅 stackoverflow.com/questions/699372/…
    【解决方案3】:

    您可以在 addNewPerson() 中的错误消息的开头添加一个特殊字符。调用脚本将使用字符串函数来检测特殊字符(以便它知道存在错误)并删除该字符,以便在没有它的情况下显示消息。你认为这对你想要的有用吗?

    【讨论】:

      【解决方案4】:

      必须回答我自己的示例才能显示代码 sn-p。 接受 Shoan 的建议,我正在尝试扩展 DAL 以使用 PDO(class DAL extends PDO)。但这给了我空白屏幕。这是我的 DAL 课程。

      class DAL { 
        protected $username; 
        protected $pwd; 
        protected $host;
        protected $dbname;
        private $conn; 
        private $db; 
        private $query_result; 
      
        public function __construct($cfg_file = 'nf.config') 
        { 
          $config = parse_ini_file($cfg_file);
      
          $this->username     = $config['db_user']; 
          $this->pwd          = $config['db_password'];
          $this->host         = $config['db_host']; 
          $this->dbname       = $config['db_name'];
        } 
      
        public function connect() 
        { 
            ($this->conn = mysql_connect($this->host, $this->username, $this->pwd))  
              or die("Error connecting to DB by user = " . $this->username); 
      
            $this->db = mysql_select_db($this->dbname,$this->conn) 
              or die("Unable to connect to database " . $this->dbname); 
        }  
      
      
        private function query($sql) 
        {
            $this->query_result = mysql_query($sql, $this->conn)
              or die("Unable to query local database <b>". mysql_error()."</b><br>$sql"); 
      
            if ($this->query_result){ 
                return $this->query_result; 
            }
        } 
      
        public function getSomeData()
        {
          $sql ="SELECT * FROM myTable";
          //Process query
          $this->query($sql);
            return $this->query_result; 
        }
      }
      

      所以在我的代码中,我只是这样做:
      $myDB = 新 DAL();
      $myDB->connect();
      $result = $myDB->getSomeData();

      但是一旦我添加了“扩展 PDO”,我的页面就会变成空白。我也无法使用任何 try / catch / throw - 这一切都会给我错误消息。

      【讨论】:

      • 如果我尝试扩展到 mysqli(DAL 类扩展 mysqli),我会得到相同的结果
      • 当人们建议使用 PDO 进行查询时,他们并不意味着您是 PDO 的子类。如果您的 DAL 类与 PDO 类做同样的事情,但略有不同,则子类化将是有意义的。在您的情况下,您只是想使用 PDO 作为工具,所以实例化它!有关介绍,请参阅 php.net/manual/en/pdo.connections.phpphp.net/manual/en/pdo.prepared-statements.php
      猜你喜欢
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多