如何使用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');
但是,这似乎让我有点过于接近扩展或修改库以获得可能已存在的东西,但我还没有看到它。
有没有其他人有这种需要,你是如何解决的?
答案 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的效率)是查询所有项目,并在迭代结果集时对返回的行进行安全性检查。