2012-08-07 102 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編碼。