2011-07-17 2 views
1

Zend_Db_Table_Row을 저장할 때 ZF가 하나의 열에 SQL 함수를 적용 할 수 있습니까? 방법에 대한 힌트에 대한Zend_Db_Table_Row :: save()에 SQL 함수 적용

UPDATE table SET field = GeomFromText(?) WHERE id = ?; 

감사 :

UPDATE table SET field = ? WHERE id = ?; 

내가 자동으로이 분야에 GeomFromText() 함수를 적용하는 데 싶습니다 $row->save() 기본적으로이 SQL 쿼리를 생성하는 경우 예를 들어

, Zend_Db와 함께!

답변

1

Zend_Db_Table에서 상속 클래스에서 사용자 지정 update 방법 (안 Zend_Db_Table_Row)에서 정의하고 함수의 반환 값으로 열을 설정하는 Zend_Db_Expr를 사용합니다.

여기의 문서를 참조하십시오. http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.extending.insert-update.

+0

당신이, 내가 실제로 단지 사용 감사합니다'$ 로우 -> 열을 = 새로운 Zend_Db_Expr ('GeomFromText ("...")') '와 괜찮 았어. 단점은 내가 수동으로 데이터를 탈출해야한다는 것입니다. – Benjamin

1

난 그냥 추측하고 있지만,이 시도 할 수 :

<?php 
class MyTable extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'my_table'; 

    public function update(array $data, $where) { 
     /** 
     * Build "col = ?" pairs for the statement, 
     * except for Zend_Db_Expr which is treated literally. 
     */ 
     $set = array(); 
     $i = 0; 
     foreach ($data as $col => $val) { 
      if ($val instanceof Zend_Db_Expr) { 
       $val = $val->__toString(); 
       unset($data[$col]); 
      } else { 
       if ($this->_db->supportsParameters('positional')) { 
        $val = ($col == 'field') ? 'GeomFromText(?)' : '?'; 
       } else { 
        if ($this->_db->supportsParameters('named')) { 
         unset($data[$col]); 
         $data[':col'.$i] = $val; 
         $val = ($col == 'field') ? 'GeomFromText(:col'.$i.')' : ':col'.$i; 
         $i++; 
        } else { 
         /** @see Zend_Db_Adapter_Exception */ 
         require_once 'Zend/Db/Adapter/Exception.php'; 
         throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding"); 
        } 
       } 
      } 
      $set[] = $this->_db->quoteIdentifier($col, true) . ' = ' . $val; 
     } 

     $where = $this->_whereExpr($where); 

     /** 
     * Build the UPDATE statement 
     */ 
     $sql = "UPDATE " 
      . $this->_db->quoteIdentifier($this->_name , true) 
      . ' SET ' . implode(', ', $set) 
      . (($where) ? " WHERE $where" : ''); 

     /** 
     * Execute the statement and return the number of affected rows 
     */ 
     if ($this->_db->supportsParameters('positional')) { 
      $stmt = $this->_db->query($sql, array_values($data)); 
     } else { 
      $stmt = $this->_db->query($sql, $data); 
     } 
     $result = $stmt->rowCount(); 
     return $result; 
    } 

    protected function _whereExpr($where) 
    { 
     if (empty($where)) { 
      return $where; 
     } 
     if (!is_array($where)) { 
      $where = array($where); 
     } 
     foreach ($where as $cond => &$term) { 
      // is $cond an int? (i.e. Not a condition) 
      if (is_int($cond)) { 
       // $term is the full condition 
       if ($term instanceof Zend_Db_Expr) { 
        $term = $term->__toString(); 
       } 
      } else { 
       // $cond is the condition with placeholder, 
       // and $term is quoted into the condition 
       $term = $this->quoteInto($cond, $term); 
      } 
      $term = '(' . $term . ')'; 
     } 

     $where = implode(' AND ', $where); 
     return $where; 
    } 
} 
?> 
+1

Zend_Db_Adapter_Abstract (실제로이 코드를 가져 왔음)의 업데이트 메소드에서 볼 수 있듯이 Zend_Db_Expr은 SQL 인젝션을위한 공간을 그대로 유지하면서 Zend_Db_Expr을 그대로 취급하므로 사용하지 않는 것이 좋습니다. –