【问题标题】:Empty arrays infront of calls and timeouts using class variables?使用类变量的调用和超时前的空数组?
【发布时间】:2012-08-16 16:23:03
【问题描述】:

我遇到了最奇怪的问题。请帮忙。

我有一个用于扩展其他类对象的数据库对象。这样做时,我可以轻松地将结果集附加到类变量上,并从应用程序内的任何位置静态调用结果。这是我用来设置参数的“选择”函数:

    public static function select($where="", $bind="", $fields="*", $table="") {
        global $db;
        $object = get_called_class();
            if(empty($table))
                $table = static::$table;

        $sql = "SELECT " . $fields . " FROM " . $table;
        if(!empty($where))
            $sql .= " WHERE " . $where;
        $sql .= ";";
        return $db->run($object, $sql, $bind);
}

这里是数据库类函数运行,它实际执行上述函数 SQL 查询和参数,然后在一个对象中返回它,这样我就可以轻松地使用该对象:

    public function run($object, $sql, $bind='') {
        $this->sql = trim($sql);
        $this->bind = $this->cleanup($bind);

        try {
            $pdostmt = $this->prepare($this->sql);
            if($pdostmt->execute($this->bind) !== false) {
                switch(strtok($this->sql, ' ')) {
                    case 'DESCRIBE':
                    case 'PRAGMA':
                        return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
                    break;
                    case 'DELETE': 
                    case 'INSERT':
                    case 'UPDATE':
                    case 'REPLACE':
                    case 'TRUNCATE':
                        return $pdostmt->rowCount();
                        break;
                    default:
                        if($object == 'SessionHandler') {
                            if($pdostmt->rowCount() === 1) {
                                return $pdostmt->fetch(PDO::FETCH_ASSOC);
                            } else {
                                return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
                            }
                        } else {
                            if($pdostmt->rowCount() === 1) {
                                $pdostmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $object); 
                                return $pdostmt->fetch();
                            } else {
                                $pdostmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $object);
                                return $pdostmt->fetchAll();
                            }

                        }
                        break;
                }

            }
        } catch(PDOException $e) {
            $msg = 'Last SQL Query: ' . $this->sql . "\n";
            $msg .= 'SQL Error Message: ' . $e->getMessage();
            Logger::logToFile(__CLASS__, $msg);
            die($msg);
        }
    }

当我使用单个类并从另一个页面提取信息时,这些功能非常有用。但请考虑以下几点:

    class ACL extends DatabaseObject {
        private $_permissions = array();
        private $_userid = 0;
        private $_user_roles = array();

        public function __construct($userid = 0) {
            global $session;
            if($userid == 0) {
                $this->_userid = $session->userid;
            } else {
                $this->_userid = $userid;   
            }
            $this->get_user_roles($this->_userid);
            $this->get_all_roles();
        }

        public function get_user_roles($userid = 0) {
            $bind = array('userid' => $userid);
            $roles = self::select('userid = :userid', $bind, '*', 'user_roles');
            if(is_object($roles)) {
                $this->_user_roles[] = $roles->roleid;
            } else {
                foreach($roles as $role) {
                    $this->_user_roles[] = $role->roleid;
               }
            }
        }

        public function get_all_roles($format = 'id') {
            $format = strtolower($format);
            echo $this->_userid . '<br />';
        }
    }

在上面的ACL类中,在类的构造函数中,我将类的_userid变量设置为等于会话变量……但是当我使用$this-&gt;_userid调用get_user_roles函数时,应用程序崩溃了?另外,当我打印出 get_all_roles 函数的$this-&gt;_userid 时,我返回了三个值而不是一个?此外,我在此类中运行的所有查询都将空数组附加到结果的前面。空数组的数量等于结果的数量。那么最后一个数组会保存所有的对象吗?

请帮忙,我很困惑。任何帮助将不胜感激。

【问题讨论】:

    标签: php arrays class pdo


    【解决方案1】:

    确实很奇怪。您能否发布错误日志中的任何输出,以查看您的应用程序崩溃的位置?乍一看,我真的找不到任何明显错误的地方,但错误大多在细节上。

    【讨论】:

    • 我想我找到了问题所在。发生了什么事?我从查询中返回 ACL 对象...我认为这是导致挂起和空数组的原因,因为每个 ACL 对象都将 ACL 类变量设置为其自己的值。我做这个假设是对的吗?我现在所做的是将结果作为关联数组返回,并使用数组键为 ONE ACL 类设置值,到目前为止它似乎一直保持不变。
    • 当然。这行是罪魁祸首:PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $object.
    • 它基本上告诉 PDO 类用提供的数据填充该对象。顺便问一下,我可以问你为什么要传递这个对象吗?我注意到你在类名上有一个if 条件,这并不是最灵活的做法。为什么不去掉$object参数,改为$return_format呢?
    • 是的,在意识到发生了什么后不久,我改变了我的数据库运行功能如下:见下文
    【解决方案2】:

    根据我上面的评论,这是我现在使用的更新后的 DB Run Method。

        public function run($object, $sql, $bind='', $type='object') {
            $this->sql = trim($sql);
            $this->bind = $this->cleanup($bind);
    
            try {
                $pdostmt = $this->prepare($this->sql);
                if($pdostmt->execute($this->bind) !== false) {
                    switch(strtok($this->sql, ' ')) {
                        case 'DESCRIBE':
                        case 'PRAGMA':
                            return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
                            break;
                        case 'DELETE': 
                        case 'INSERT':
                        case 'UPDATE':
                        case 'REPLACE':
                        case 'TRUNCATE':
                            return $pdostmt->rowCount();
                            break;
                        default:
                            if($type == 'array') {
                                if($pdostmt->rowCount() === 1) {
                                    return $pdostmt->fetch(PDO::FETCH_ASSOC);
                                } else {
                                    return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
                                }
                            } elseif($type == 'object') {
                                if($pdostmt->rowCount() === 1) {
                                    $pdostmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $object); 
                                    return $pdostmt->fetch();
                                } else {
                                    $pdostmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, $object);
                                    return $pdostmt->fetchAll();
                                }
    
                            }
                            break;
                    }
    
                }
             } catch(PDOException $e) {
                $msg = 'Last SQL Query: ' . $this->sql . "\n";
                $msg .= 'SQL Error Message: ' . $e->getMessage();
                Logger::logToFile(__CLASS__, $msg);
                die($msg);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多