2013-08-23 114 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语句,那么你每次都会得到相同的结果 - 你从原始调用中正确得到的结果。

希望有帮助!