代码之家  ›  专栏  ›  技术社区  ›  ItsPronounced Finn

Codeigniter数据库错误处理,尝试覆盖所有可能的场景

  •  0
  • ItsPronounced Finn  · 技术社区  · 6 年前

    如果我的MYSQL数据库返回任何错误(无行、无连接、无表等),我将尝试覆盖所有基础当我使用 CodeIgniter 3

    我有一个助手函数,它根据提供的邮政编码返回纬度和经度。它总是只返回一行(允许记录退出)。以下是我的助手函数:

    if (!function_exists('get_coordinates_from_zipcode')) {
    
        //gets latitude and longitude coordinates from supplied zipcode. Returns array
        function get_coordinates_from_zipcode($zipcode) {
            $ci =& get_instance();
            $ci->load->database();
    
            $query = $ci->db->get_where('Geo', array('zip =' => $zipcode))->row_array();
    
            if (!$query) {
                return FALSE;
            } else {
                return $query;
            }
        }
        //* Fields returned from geolocation database *//
        /*  -zip
            -lat
            -lng
        // Returns false on error or no records
        */
    
    }
    

    这是我的 View 我正在使用(通过 $data['array'] 从我的 Controller ):

    <?php if ($array == FALSE || !$array) : ?>
    <?php echo "No data returned"; ?>
    <?php else : ?>
    <?php echo $array['zip'] . ' is located at ' . $array['lat'] . ' and ' . $array['lng']; ?>
    <?php endif; ?>
    

    如果没有行,但我想处理任何其他问题,例如多行(不太可能发生),或者连接到数据库或表时出现问题,那么这种方法效果很好。

    我在我的 Helper

    if ($ci->db->error()) {
            return $ci->db->error(); //
        } else {
            return $query;
    }
    

    当我这样做时,故意使用无效的邮政编码将错误传递给视图, $ci->db->error() 始终返回 array(2) { ["code"]=> int(0) ["message"]=> string(0) "" } 并且是空的。当然我也会遇到一些错误 Undefined index: lat Undefined index: lng

    我应该通过 $ci-db->error() 阵列到视图并在视图上执行操作?

    我只是想确保我所有的基地都被覆盖。在我看来,我应该在 帮手 功能,但 error() 即使出现错误(例如没有行、没有db连接或没有该名称的表),也始终似乎为空。

    我觉得

    if (!$query) {
        return FALSE;
    } else {
        return $query;
    }
    

    在我的helper函数中,无法涵盖连接到数据库时可能遇到的所有问题。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Alex    6 年前

    你为什么不做以下事情:

    if (!function_exists('get_coordinates_from_zipcode')) {
    
        //gets latitude and longitude coordinates from supplied zipcode. Returns array
        function get_coordinates_from_zipcode($zipcode) {
            $ci =& get_instance();
            $ci->load->database();
    
            if ($ci->db->conn_id === false) {
                return false; // connection couldn't be established
            }
    
            $query = $ci->db->get_where('Geo', array('zip =' => $zipcode));
    
            if ($query && $query->num_rows() == 1) {
                return $query->row_array();
            }
            return false;
        }
        //* Fields returned from geolocation database *//
        /*  -zip
            -lat
            -lng
        // Returns false on error or no records
        */
    
    }
    

    这样做:

    1. 您测试该查询没有返回错误结果
    2. 您测试只得到1行
    3. 确保已与db建立连接(似乎有点过头了)

    请注意:您应该 总是 检查的值 num_rows() 在尝试访问结果数组/对象之前。如果没有行,则在尝试访问数组时将获得未定义的索引。

        2
  •  1
  •   Atural    6 年前

    我不理解你的助手在这里的目的-如果你不使用模型,如果你绕过这里的控制器,为什么你一开始还要使用Codeigniter?

    现在你的问题

    如果可能的话,我会创建一个模型,您可以在其中处理所有错误,并尝试 throw 他们通过例外情况

    可能的方法

    模型

    class Geo_model extends CI_Model
    {
        public function __construct()
        {
            $this->load->database();
        }
    
        public function get_coordinates_from_zipcode($zipcode = false)
        {
            if (!$zipcode)  throw new InvalidArgumentException('Zipcode should be set');
    
            $query = $this->db
                ->select('*')
                ->from('Geo')
                ->where('zip', $zipcode)
                ->get();
    
            $arrError = $this->db->error();
    
            if (isset($arrError['message']) && !empty($arrError['message']))    throw new RuntimeException($arrError['message']);
    
            if ($query->num_rows() != 1)    throw new RuntimeException('Query - Number of rows should be 1');
    
            return $query->row_array();
    
        }
    }
    

    控制器

    class Geo extends CI_Controller
    {
    
        public function coordinatesfromzipcode($zipcode)
        {
            $this->load->model('Geo_model');
            try
            {
                $row = $this->Geo_model->get_coordinates_from_zipcode($zipcode);
                //load your coordinates view
            }
            catch (Excepetion $e)
            {
                //load an error view or something like that...
                echo $e->getMessage();
            }
    
        }
    }