2

我如何使用 实现行级安全性Zend_Db_Select?我能想到几个选项,但它们似乎不太适合这种模式。

假设我有users, content, 和许多不同的 ACL 级别。这是我想到的一个解决方案:

$select = $db->select()
             ->from('content')
             ->where('content_type NOT IN (?)',
                     Model_Content::userAllowedContentTypes()
             )
             ->order('date DESC')
);

但问题是,如果您决定为不同类型的安全性添加另一个字段怎么办?所以,我想可能是这样的:

/**
 * @var Zend_Db_Select
 */
$where = Model_Content::getWhere();
$db->select()
    ->from('content')
    ->$where()
    ->order('date DESC');

更好..但这也不太对劲。我想要的是更像这样的东西:

$db->select()
    ->from(array('c' => 'content'))
    ->getPlugin(new Model_Content_Security('c'))
    ->order('date DESC');

但这似乎有点太接近扩展或修改库以获得可能已经存在的东西,但我还没有完全看到它。

有没有其他人有这种需求,你是怎么解决的?

4

2 回答 2

1

扩展 Zend_Db_Select。制作 App_Db_Select_Security 并在构造函数中适当地初始化它。

于 2011-02-17T15:31:31.960 回答
1

如果您的安全性在数据库中受到控制,您可以加入它:

    $select = $db->select()
             ->from('content')
             ->joinLeft( array( 'pt'=>'permissionTable' ),'content.id = pt.contentId AND pt.userId = ' . $escapedUserId, array() )
             ->where( pt.contentId IS NOT NULL )        
             ->order('date DESC');

也许扩展 Zend_Db_Select 以检查正在访问的表,并让它调用安全对象,将 select 语句作为参数传递。例如,您的内容类可能负责添加 joinLeft() 和 where() 语句。

public function addSecurityToSelect( Zend_Db_Select $select ){
    return $select->joinLeft( array( 'pt'=>'permissionTable' ),'content.id = pt.contentId AND pt.userId = ' . $escapedUserId, array() )
                  ->where( pt.contentId IS NOT NULL )  

}

让扩展的 Zend_Db_Select 类遍历包含的表,检查是否有可以调用的安全函数,然后调用它。

另一种选择(数据库效率低得多)是查询所有项目并在遍历结果集时对返回的行进行安全检查。

于 2011-02-17T16:00:32.497 回答