Php 函数在第一次调用时返回字符串,在后续调用时返回对象

Php 函数在第一次调用时返回字符串,在后续调用时返回对象,php,mysql,orm,propel,Php,Mysql,Orm,Propel,我对此有点困惑,所以我希望有人能为我解释一下 我有一个函数,用于从我的一个表中返回列状态,访问 function someFunction($visitId = null) { $visit = VisitQuery::create() ->select(array('Status')) ->findPk($visitId); } 如果我var\u dump($visit),在第一次调用函数时,它会输出: string '1' (length=1) 但是,对函

我对此有点困惑,所以我希望有人能为我解释一下

我有一个函数,用于从我的一个表中返回列
状态
访问

function someFunction($visitId = null) {
  $visit = VisitQuery::create()
    ->select(array('Status'))
    ->findPk($visitId);
}
如果我
var\u 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)
  ...
我第一次调用该函数时,通过一个已发布表单传递了一个
(int)$visitId

var_dump($visitId); // int 362
后续调用使用另一个函数返回的
(int)$visitId
saveVisit()

我试着做了一些调试,出于某种原因,第一次函数调用和后续调用向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
有人能告诉我这是为什么或如何发生的吗

我用的是推进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;
}
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);
}
推进的
findPk()
方法:

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;
}
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;
}
保存就诊记录的功能:

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; 
  }
}

第一次调用时,似乎会获取数据,然后将完整对象的副本放入实例池。我不确定这是一个bug还是一个有效的行为(您的代码可能会建议使用前者,但我很想听听更了解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语句,则每次都会返回相同的结果,即从原始调用中正确返回的结果


希望有帮助!

我想说问题在于
VisitQuery::create()
。你能展示一下
创建
功能的代码吗?看起来它第一次会创建一个新的访问并返回
1
,对于每个后续的请求,它都会返回它之前创建的对象,你能发布该功能的完整代码吗@ØHankyPankyØ我已经在问题中添加了完整的功能好的,现在请您粘贴这些方法的代码:
findPk
VisitQuery::create
@HankyPankyØ我已经发布了所有相关的代码