2012-08-07 92 views
2

大家好,我使用Zend Framework(但我认为这是无关紧要的)和PHP5,我只是想修改一个对象,传递一个对象的对象:引用或值?

public function saveSite($post) { 
    $form = new Diff_Form_Download(); 
    $subform = new Diff_Form_DownloadSubform(); 
    $form = $this->view->form; 
    $newSite = 0; 
    $sitesRecord = new Diff_Model_Sites(); 
    $debugString = null; 

    if (is_array($post)) { 
     $subform = $this->getSubformByPost($post); 
     $debugString = $subform->getContent(); 
     echo $debugString; 

     //new site instertion 
     if (is_null($subform)) { 
      $subform = $form->getSubForm('NewSite'); 
      $newSite = 1; 
     } 

     $values = reset($subform->getValues()); 

     $sitesRecord = Doctrine_Core::getTable('Diff_Model_Sites')->findOneBy('idSite', $values['idSite']); 
     if ($sitesRecord) { 
      $sitesRecord->idSite = $values['idSite']; //useless but necessary to make Doctrine understand to use update? 
     } else { //if the record is not present instantiate a new object (otherwise save() will not work 
      $sitesRecord = new Diff_Model_Sites(); 
     } 

     $sitesRecord->content = $subform->getContent(); //$values['content']; 
     $sitesRecord->newHtml = $subform->getContent(); 
     $sitesRecord->url = $values['url']; 
     $sitesRecord->shortName = $values['shortName']; 
     $sitesRecord->lastChanged = date("Y-m-d H:i:s"); 
     $sitesRecord->pollingHours = $values['pollingHours']; 
     $sitesRecord->minLengthChange = $values['minLenghtChange']; 

     if (Zend_Auth::getInstance()->hasIdentity()) { //save the owner 
      $sitesRecord->idOwner = Zend_Auth::getInstance()->getIdentity()->idOwner; //retrieve the owner 
      $sitesRecord->save(); 
     } else { 
      throw new Exception("your session have expired: \n please login again"); 
     } 
    } 
} 

/** 
* return the calling subform 
* @param type $post 
* @return type 
*/ 
public function getSubformByPost($post) { 
    $form = new Diff_Form_Download(); 
    $form = $this->view->form; 
    $subform = new Diff_Form_DownloadSubform(); 
    $subformName = "site" . $post['idSite']; 
    $subform = $form->getSubForm($subformName); 

    return $subform; 
} 

public function refreshOneDiff($post) { 
    $debugString; 
    if (is_array($post)) { 
     $form = new Diff_Form_Download(); 
     $form = $this->view->form; 

     $subform = new Diff_Form_DownloadSubform(); 
     $subform = $this->getSubformByPost($post); 

     if (!$subform) 
      $subform = $this->view->form->getSubformByPost('NewSite'); 
     $url = $subform->getUrl(); 
     $idSite = $subform->getIdSite(); 

     $crawler = new Crawler(); 
     $newpageContent = $crawler->get_web_page($url); 
     $siteRecord = new Diff_Model_Sites(); 
     $siteRecord = $subform->getSiteRecord(); 
     if ($siteRecord) //check if the record is not null 
      $oldpageContent = $siteRecord->get('content'); 
     else 
      $oldpageContent = null; 

     $differences = $this->getDiff($oldpageContent, $newpageContent); 

     if (!is_null($differences)) { 
      $siteRecord->content = $newpageContent; 
      $subform->setContent($newpageContent); 
      $subform->setContentDiff($differences); 
      $subform->setSiteRecord($siteRecord); 
      $subform = $this->getSubformByPost($post); 
      $debugString = $subform->getContent(); 
     } 

      //echo $debugString; 

     $sitePresence = Doctrine_Core::getTable('Diff_Model_Sites')->findOneBy('idSite', $idSite); 
     if ($sitePresence) { 
      //$this->saveSite($post); 
      $this->debugtry($post); 
     } 
    } else { 

    } 
} 

基本上我在这里做什么的目的是: 1)从视图 2)抓住从形式的子窗体抢形式(让我们称之为SubformX) 3)抓住从SubformX 4的对象“siteRecordX”)改变“siteRecordX”的值 5)调用一个函数saveRecord () 6)在此功能regrab相同SubformX和呼应对象的值siteRecordX

令人惊讶的是,如果我更改SubformX的变量,它将保持这种方式,如果我更改SubformX的对象的变量,它将保持不变(如果我检索SubformX)。 看起来,即使SubformX通过引用传递,它的子对象也不一样,它们通过值传递,所以它们消失,改变函数的上下文。 你能帮我吗? 感谢

编辑 我还是解决不了这个问题,也不明白: 这是子窗体的构造函数:

public function __construct($site = null, $options = null) { 
    if ($site instanceof Diff_Model_Sites) { 
     $this->_shortName = $site->get('shortName'); 
     $this->_url = $site->get('url'); 
     $this->_content = $site->get('content'); 
     $this->_idSite = $site->get('idSite'); 
     $this->_siteRecord = $site; 
     $this->_lastChanged = $site->get('lastChanged'); 
    }parent::__construct($options);} 

,而这是我使用设定值SubformX的功能。

public function setContent($contentText) { 
    $this->_siteRecord->content = $contentText; 
    $this->_content = $contentText; 
} 

,这是我打电话来获取值

public function getContent() { 
    if (isset($this->_siteRecord)) { 
     //return $this->_content; 
     return $this->_siteRecord->content; 
    } 
} 

与注释行,我能够检索更新的价值,而不是与第二子窗体的功能。 这对我来说是一个真正的谜,因为我在完全相同的点上以完全相同的方式设置并获取它们,我无法理解它们之间的差异。

+1

http://php.net/manual/en/language.oop5.references.php - 尽管我承认那里的信息可能会进一步影响问题。缺点是* all *对象总是被引用传递,而不管上下文,因为你实际上并没有传递对象,而是一个指向它的指针。这意味着即使你创建了一个指针的副本,它仍然指向相同的东西。创建对象副本(在PHP5中)的唯一方法是使用'clone'。如果对象稍后在代码中未被修改,那是因为您没有修改它。 – DaveRandom 2012-08-07 10:38:11

+0

感谢您的评论。我发现每个indexAction都会再次调用每个子窗体的构造函数,重载子窗体在保存之前从数据库中检索元素。我仍然必须弄清楚如何改变这种行为。任何帮助,可以赞赏。在哪里shoud我实例化对象,从数据库加载他们的价值?谢谢 – user1439509 2012-08-07 13:55:02

回答

0

_siteRecord属性是一个ORM对象(学说,它出现)。所以它的数据可能有一些对于引用类型对象不是标准的行为。它肯定有一些覆盖__get__set。它也采用缓存。这些事情对于保持数据库模型交互正常工作是必要的,但它们可能会混淆应该是引用和值类型。 (参见:http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html

P.S:在构造函数中使用:

$this->_content = $site->get('content'); 
$this->_siteRecord = $site; 

但在你的getContent()使用:

$this->_siteRecord->content; 

这种差异可能是问题的一部分。

0

谢谢大家。这是教条缓存。 我还没有调查进一步的问题,但摆脱教条后一切工作正常。 此问题发生后,我已经失去了一整天的时间。 此外,今天我又因另一个与教义有关的好奇问题而失去了另一天。 似乎每次你从你的db Doctrine收集数据为你解码(就像php函数utf8_decode($ data)。 当然,如果你得到的数据,然后再放回到数据库,它会导致一个编码和解码的混乱。 这就够了。我仍然认为ORM是伟大的编程工具,但简单的说就不是。 我不会安息,因为我会让它从我的程序中消失。 我将使用Zend_Db库代替。我大部分已经没有遗憾地没有面对上述主义的问题。 再次感谢Seth Battin和Dave Random的帮助和耐心了解我的noob编码。