Php Zend_Db_为更新/删除查询选择
在处理应用程序的映射结构时,我们遇到了一些代码一致性方面的问题。虽然使用Zend_Db_select类和诸如:$select->from'table'->where'id=?,1这样的函数进行select查询很容易,但它不适用于更新/删除查询。没有像Zend_Db_Update或Zend_Db_Delete这样的类来构建更新和删除查询,就像构建选择查询一样。为了解决这个问题,我们扩展了Zend_Db_Select类,如下面的代码所示。代码显示了扩展Zend_Db_Select类的自定义类,在底部显示了一些最小的示例代码,以显示如何使用它Php Zend_Db_为更新/删除查询选择,php,mapping,zend-framework,Php,Mapping,Zend Framework,在处理应用程序的映射结构时,我们遇到了一些代码一致性方面的问题。虽然使用Zend_Db_select类和诸如:$select->from'table'->where'id=?,1这样的函数进行select查询很容易,但它不适用于更新/删除查询。没有像Zend_Db_Update或Zend_Db_Delete这样的类来构建更新和删除查询,就像构建选择查询一样。为了解决这个问题,我们扩展了Zend_Db_Select类,如下面的代码所示。代码显示了扩展Zend_Db_Select类的自定义类,在底部
<?php
class Unica_Model_Statement extends Zend_Db_Select
{
public function __construct($oMapper)
{
parent::__construct($oMapper->getAdapter());
$this->from($oMapper->getTableName());
}
/**
* @desc Make a string that can be used for updates and delete
* From the string "SELECT `column` FROM `tabelnaam` WHERE `id` = 1" only the part "`id = `" is returned.
* @return string
*/
public function toAltString()
{
$sQuery = $this->assemble(); // Get the full query string
$sFrom = $this->_renderFrom(''); // Get the FROM part of the string
// Get the text after the FROM (and therefore not using the "SELECT `colname`" part)
$sString = strstr($sQuery,$sFrom);
// Delete the FROM itself from the query (therefore deleting the "FROM `tabelnaam`" part)
$sString = str_replace($sFrom, '', $sString);
// Delete the word "WHERE" from the string.
$sString = str_replace('WHERE', '', $sString);
return $sString;
}
}
################################################
# Below code is just to demonstrate the usage. #
################################################
class Default_IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$person = new Unica_Model_Person_Entity();
$statement = new Unica_Model_Statement($person->getMapper());
$statement->where('id = ?' , 1);
$person->getMapper()->delete($statement);
}
}
class Unica_Model_Person_Mapper
{
public function delete($statement)
{
$where = $statement->toAltString();
$this->getAdapter()->delete($this->_tableName,$where);
}
}
使用这个类一切都很好,但它让我们怀疑我们是否遗漏了什么。有没有一个原因没有像select那样的默认更新/删除类,并且在其他地方使用这个类会给我们带来麻烦
如蒙指教,不胜感激。
提前感谢,
伊利亚人我不知道Zend_Db_Select不提供CUD方法的确切原因。显而易见的解释是,Select意味着您应该将其用于动态查询构建。要插入、更新和删除,您可以使用Zend_Db_适配器或Zend_Db_表和Zend_Db_表行中的代理方法或通用Zend_Db_语句
然而,尽管如此,我认为扩展Zend_Db_Select并根据您的需要对其进行调整并没有什么错,就像任何其他组件一样,这些组件一开始并不能满足您的需要如果您确信您不会让它在将来发展得太多,那么这个类就可以了。我假设您的方法是受益于Zend_Db_Select类中的自动引用。然而,依我拙见,如果您需要修改或扩展它,它存在一些设计缺陷,可能会导致扩展性问题: 它接收一些数据,这些数据在实体对象之后被丢弃,以使用from子句。 它直接操作select查询的SQL输出,这可能是一种危险的依赖。如果格式发生变化,并且如果您需要在where子句中包含更多元素,那么您的代码可能会变得非常混乱,无法适应这些变化。 我的方法是直接在代码中使用where子句,并在必要时引用它们。在我看来,它并不是特别不干净。如下所示:
$db->delete('tablename', 'id = ' . $db->quote('1'));
private function myDelete($tableName, array $fields)
{
$whereClauses = array();
foreach ($fields as $fieldName => $fieldValue) {
$whereClauses[] = $fieldName . ' = ' . $db->quote($fieldValue);
}
$this->db->delete($tableName, implode(' AND ', $whereClauses));
}
$this->myDelete('tablename', array('id' => '1', 'name' => 'john'));
最终,您甚至可以将其抽象为一个方法或类,以避免将$db->quote调用分散到各个地方,类似这样:
private function myDelete($tableName, $fieldName, $fieldValue)
{
$this->db->delete($tableName, $fieldName . ' = ' . $db->quote($fieldValue));
}
编辑:在where部分中包含多个子句将使其更加复杂,并且您希望的灵活性将取决于您的特定应用程序。例如,几个ANDed条款的可能解决方案如下:
$db->delete('tablename', 'id = ' . $db->quote('1'));
private function myDelete($tableName, array $fields)
{
$whereClauses = array();
foreach ($fields as $fieldName => $fieldValue) {
$whereClauses[] = $fieldName . ' = ' . $db->quote($fieldValue);
}
$this->db->delete($tableName, implode(' AND ', $whereClauses));
}
$this->myDelete('tablename', array('id' => '1', 'name' => 'john'));
希望这能有所帮助,谢谢你的回复,你的报价是对的。我正在尝试自动引用所有内容,这样程序员就不必费心引用所有内容,即使他忘记了,也很安全。但是,myDelete函数如何处理where中的多个值?比如:删除id=3或address='test'和language!='根据WHERE子句的复杂程度,您需要或多或少地修改代码。我将答案编辑为仅使用AND和字段相等,只是为了展示一个简单的示例。我以前尝试过类似的方法,但发现自己陷入了类似数组键的问题。像这样的情况:数组'id'=>3,'id'=>4这样使用它来启用大于可能性的数组'id=?'=>3,'id=?'=>4正如我所说的,我认为您需要缩小问题的范围,只包括在where上可能得到的值,否则可能会使解决方案过于复杂。如果需要处理标识符采用多个可能值的情况,可以这样做:array'id'=>array'3',4'。但同样,复杂性将取决于应用程序中可能出现的where情况的范围。