php传递对象的对象:引用还是值?

时间:2012-08-07 10:17:01

标签: php zend-framework object reference

大家好我正在使用zend框架(但我认为这是无关紧要的)和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获取一个对象“siteRecordX” 4)更改“siteRecordX”的值 5)调用函数saveRecord() 6)在此函数中重新调整相同的SubformX并回显对象siteRecordX

的值

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

EDIT 我仍然无法解决这个问题,也无法理解它: 这是子表单的构造函数:

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

使用注释行我能够检索更新的值,而不是第二个。 这对我来说真是个谜,因为我在完全相同的点上设置并完全相同,我无法理解其中的差异。

2 个答案:

答案 0 :(得分:0)

您的_siteRecord属性是一个ORM对象(Doctrine,它出现)。因此,其数据可能具有一些不是参考类型对象标准的行为。它肯定会覆盖__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;

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

答案 1 :(得分:0)

谢谢大家。这是Doctrine缓存。 我没有进一步调查这个问题,但在摆脱了Doctrine之后一切正常。 在这个问题之后,我已经失去了一整天。 此外,今天我又因为与学说有关的另一个好奇问题而失去了另一天。 看来你每次从db Doctrine收集数据都会为你解码它们(就像php函数utf8_decode($ data)一样)。 当然,如果您获取数据然后再将其放回数据库中,则会导致编码和解码的总体混乱。 这就够了。我仍然认为ORM是很棒的编程工具,但只是Doctrine不是。 我不会安息,因为我会把它从我的程序中删除。 我将使用Zend_Db库代替。我大部分时间都没有后悔,没有面对上述学说的问题。 再次感谢Seth Battin和Dave Random帮助和耐心了解我的noob编码。