Zend_Db_Select行级安全性

时间:2011-02-17 14:12:14

标签: php zend-framework zend-db-select row-level-security

如何使用Zend_Db_Select完成行级安全性?我可以想到一些选择,但它们似乎并不适合这种模式。

假设我有userscontent和许多不同的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');

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

有没有其他人有这种需要,你是如何解决的?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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类遍历包含的表,检查是否有可以调用的安全函数然后调用它。

另一个选项(更不用说db的效率)是查询所有项目,并在迭代结果集时对返回的行进行安全性检查。