2013-08-23 118 views
2

我對此有點困惑,所以我希望有人能爲我闡明一些事情。功能在第一次通話時返回字符串,並在隨後的通話中返回一個對象

我有一個函數,其目的是從我的表visit之一返回列Status

function someFunction($visitId = null) { 
    $visit = VisitQuery::create() 
    ->select(array('Status')) 
    ->findPk($visitId); 
} 

如果我var_dump($visit),調用函數爲首次時,它輸出:

string '1' (length=1) 

隨後,相同調用函數然而似乎回到整個對象:

object(Visit)[30] 
    protected 'startCopy' => boolean false 
    protected 'id' => int 362 
    protected 'job_id' => int 351 
    protected 'company_id' => int 2 
    protected 'type_id' => int 1 
    protected 'visit_date' => string '2013-08-23 00:00:00' (length=19) 
    protected 'status' => string '1' (length=1) 
    ... 

我第一次用調用函數通過發佈形式傳遞:

var_dump($visitId); // int 362 

後續調用與從另一函數返回一個(int) $visitId發,saveVisit()(使用波輪保存記錄 - 我相信這可能有什麼用它做)。

$visitId = saveVisit($visitId); 
var_dump($visitId); // int 362 

我試着做一些調試,出於某種原因,發行到MySQL查詢是第一個函數調用和後面的值之間的不同:

var_dump($con->getLastExecutedQuery()); 

SELECT visit.STATUS AS "Status" FROM `visit` WHERE visit.ID=362 // 1st call 
SELECT `ID`, `JOB_ID`, `COMPANY_ID`, `TYPE_ID`, `VISIT_DATE`, `STATUS`, `REMIND`, `PRINTED` FROM `visit` WHERE `ID` = 362 // 2nd call 
SELECT `ID`, `JOB_ID`, `COMPANY_ID`, `TYPE_ID`, `VISIT_DATE`, `STATUS`, `REMIND`, `PRINTED` FROM `visit` WHERE `ID` = 362 // 3rd call 

誰能告訴我爲什麼或如何,這是發生了什麼?

我正在使用Propel 1.6。


行走的create()方法:

public static function create($modelAlias = null, $criteria = null) 
{ 
    if ($criteria instanceof VisitQuery) { 
     return $criteria; 
    } 
    $query = new VisitQuery(); 
    if (null !== $modelAlias) { 
     $query->setModelAlias($modelAlias); 
    } 
    if ($criteria instanceof Criteria) { 
     $query->mergeWith($criteria); 
    } 

    return $query; 
} 

行走的findPk()方法:

public function findPk($key, $con = null) 
{ 
    if ($con === null) { 
     $con = Propel::getConnection($this->getDbName(), Propel::CONNECTION_READ); 
    } 
    // As the query uses a PK condition, no limit(1) is necessary. 
    $this->basePreSelect($con); 
    $criteria = $this->isKeepQuery() ? clone $this : $this; 
    $pkCols = $this->getTableMap()->getPrimaryKeyColumns(); 
    if (count($pkCols) == 1) { 
     // simple primary key 
     $pkCol = $pkCols[0]; 
     $criteria->add($pkCol->getFullyQualifiedName(), $key); 
    } else { 
     // composite primary key 
     foreach ($pkCols as $pkCol) { 
      $keyPart = array_shift($key); 
      $criteria->add($pkCol->getFullyQualifiedName(), $keyPart); 
     } 
    } 
    $stmt = $criteria->doSelect($con); 

    return $criteria->getFormatter()->init($criteria)->formatOne($stmt); 
} 

我的函數來獲取訪問狀態:

function getVisitStatus($visitId = null) { 
    if (empty($visitId)) { 
    return false; 
    } 
    try { 
    $visit = VisitQuery::create() 
     ->select(array('Status')) 
     ->findPk($visitId); 
    } catch (Exception $e) { 
    echo $e->getMessage(); exit; 
    } 
    if (is_null($visit)) { 
    return false; 
    } 
    return $visit; 
} 

福nction這就節省了訪問記錄:

function saveVisit($data = null) { 
    if (empty($data)) { 
    return false; 
    }  
    try {  
    $visit = (!empty($data['visit_id'])) ? VisitQuery::create()->findPk($data['visit_id']) : new Visit(); 
    if (!is_object($visit)) { 
     return false; 
    } 

    $visitDataMap = array(
     'JobId' => 'job_id', 
     'TypeId' => 'type_id', 
     'VisitDate' => 'visit_date', 
     'Status' => 'status', 
     'CompanyId' => 'engineer_id', 
     'Remind' => 'remind' 
    ); 

    $visitData = array(); 
    foreach ($visitDataMap as $column => $value) { 
     if (!empty($data[$value])) { 
     $visitData[$column] = $data[$value]; 
     } 
    } 
    $visit->fromArray($visitData); 
    $visit->save(); 
    return $visit->getId(); 
    } catch (PropelException $e) { 
    echo $e->getMessage(); exit; 
    } 
} 
+0

我想說問題出在'VisitQuery :: create()'。你可以顯示「創建」功能的代碼嗎? –

+0

看起來像第一次它會創建一個新的訪問並返回'1',並且對於每個後續請求它將返回它之前創建的那個對象,可以發佈該函數的完整代碼 –

+0

@ØHankyPankyØ我已經添加了完成功能 – billyonecan

回答

1

看來,在第一次通話將抓住你的數據,但然後把完整的對象的副本到實例池。我不確定這是一個錯誤還是有效的行爲(您的代碼會提示前者,但我很樂意聽到更多關於Propel的人的意見,例如開發人員),但您可以通過以下方式阻止它:

VisitPeer::clearInstancePool(); 

請記住,您正在使用visit關係在此處完成的其他查詢中緩存了一點緩存。

您將能夠通過在BaseVisitPeer.php文件中添加回顯來確認此情況。你會看到這樣的事情:

public static function getInstanceFromPool($key) 
{ 
    if (Propel::isInstancePoolingEnabled()) { 
     if (isset(VisitPeer::$instances[$key])) { 
      return VisitPeer::$instances[$key]; 
     } 
    } 

    return null; // just to be explicit 
} 

如果你的某個位置添加回聲if (isset(VisitPeer::$instances[$key])) {語句中,你應該看到的只是第二次及以後的調用後出現。如果你要評論這整個if語句,那麼你每次都會得到相同的結果 - 你從原始調用中正確得到的結果。

希望有幫助!