$ this->价值损失,以及它的价值

时间:2012-11-06 04:20:17

标签: php variables

我正在使用的PHP文件存在问题,我似乎无法找到解决方案。

在代码的一部分中设置了$this->value的值,并根据我的测试正确设置了值。

但是,稍后在同一代码中$this->value为空。

以下是代码:

<?php

class Padd_Input_Advertisement {

    protected $keyword;
    protected $value;
    protected $name;
    protected $description;

    function __construct($keyword,$name,$description='') {
        $this->keyword = $keyword;
        $this->value = unserialize(get_option($keyword));
        $this->name = $name;
        $this->description = $description;
    }

    public function get_keyword() {
        return $this->keyword;
    }

    public function set_keyword($keyword) {
        $this->keyword = $keyword;
    }

    public function get_value() {
        return $this->value;
    }

    public function set_value($value) {
        $this->value = $value;
    }

    public function get_name() {
        return $this->name;
    }

    public function set_name($name) {
        $this->name = $name;
    }

    public function get_description() {
        return $this->description;
    }

    public function set_description($description) {
        $this->description = $description;
    }

    public function  __toString() {

        $strHTML  = '';
        $strHTML .= '<tr valign="top">';
        $strHTML .= '   <th scope="row"><label for="' . $this->keyword . '">' . $this->name . '</label></th>';
        $strHTML .= '   <td>';
        $strHTML .= '       <label for="' . $this->keyword. '_alt_desc">Short Description</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_alt_desc" type="text" id="' . $this->keyword . '_alt_desc" value="' . $this->value->get_alt_desc() . '" size="80" /><br />';
        $strHTML .= '       <label for="' . $this->keyword. '_img_url">Image URL</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_img_url" type="text" id="' . $this->keyword . '_img_url" value="' . $this->value->get_img_url() . '" size="80" /><br />';
        $strHTML .= '       <label for="' . $this->keyword. '_web_url">Website</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_web_url" type="text" id="' . $this->keyword . '_web_url" value="' . $this->value->get_web_url() . '" size="80" />';
        $strHTML .= '       <br /><small>' . $this->description . '</small>';
        $strHTML .= '   </td>';
        $strHTML .= '</tr>';
        return $strHTML;
    }

}

?>

function __construct的顶部,设置了值,我确认会发生这种情况。

但是,在底部函数function __toString中,$this->value为空。

知道可能导致这种情况的原因吗?

修改

因此,回顾一下,$ this-&gt;值在__construct函数中正确设置,但在__toString函数中是空白的。

编辑2

我还应该提到__construct函数中设置的其他变量在__toString函数中工作,就像$ this-&gt;关键字一样。这是jut $ this-&gt;值为空白。

编辑3 该类被称为

$padd_options['advertisements'] = array(
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_1',
        'Square Ad 1 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_2',
        'Square Ad 2 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_3',
        'Square Ad 3 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_4',
        'Square Ad 4 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
);

8 个答案:

答案 0 :(得分:11)

这是因为如果不知道类的类型,反序列化的对象保留方法。

当您反序列化get_keyword()函数调用的结果时,如果序列化对象的类未知,PHP将回退到特殊类__PHP_Incomplete_Class_Name。这个类基本上是一个虚拟类:它没有任何方法。但是,它允许您访问反序列化对象的属性。

因此,如果您希望能够调用$this->value的方法(这是您在__toString中执行的操作),则必须包含声明$this->value类型的文件。 1}}在调用unserialize之前。

[edit] 您可以查看the PHP manual以获取有关反序列化过程的更多详细信息。

答案 1 :(得分:4)

这就是导致你出现问题的原因:

$this->value = unserialize(get_option($keyword));

正如其他一些人之前所指出的那样,您可以使用get_option()函数的实际声明和包含get_alt_desc(), get_img_url(), get_web_url()方法的类来更新原始帖子。

可以假设get_option()函数返回一个序列化对象,该对象实现以下公共方法:

public function get_alt_desc() { /* custom code */ }
public function get_img_url() { /* custom code */ }
public function get_web_url() { /* custom code */ }

通过序列化和反序列化您的对象,您将无法访问上述所有方法。 为避免这种情况,您需要修改get_option()函数以返回实际对象而不是序列化表示。

假设有一个Value类代表你的对象:

class Value {
    protected $alt_desc;
    protected $img_url;
    protected $web_url;

    public function __construct($keyword) {
        $this->alt_desc = $keyword[0]; // some string build around $keyword
        $this->img_url = $keyword[1]; // some string build around $keyword 
        $this->web_url = $keyword[2]; // some string build around $keyword
    }

    public function get_alt_desc() {
        return $this->alt_desc;
    }

    public function get_img_url() {
        return $this->img_url;
    } 

    public function get_web_url() {
        return $this->web_url;
    }
}

然后你可以修改你的get_option()函数来简单地返回一个对象:

function get_option($keyword) {
    /*
     * The code below is just an example
     * This function must return an object
     */
    return new Value($keyword);
}

您的Padd_Input_Advertisement构造函数应更新如下:

function __construct($keyword,$name,$description='') {
    $this->keyword = $keyword;
    // removed the unserialize call as it's not necessary anymore
    $this->value = get_option($keyword);
    $this->name = $name;
    $this->description = $description;
}

答案 2 :(得分:1)

我会将此作为评论添加,但我想我还没有声誉可以做到这一点。

您是否尝试启用错误报告?

error_reporting(E_ALL);
ini_set("display_errors", 1);

答案 3 :(得分:1)

在面向对象编程中,您必须使用$this来调用函数。 在您的函数__toString()中,您可以直接调用函数。

所以你已经像这样调用了类的功能

$this->set_name();

答案 4 :(得分:1)

使用来自Padd Solutions的Magaling主题,其中包含问题的脚本,我在主题目录的index.php中添加了以下代码:

/*********************************TEST***********************************/
  $padd_options[ 'advertisements' ] = array( new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_468060_1', 'Banner Ad 1 (468x60)', 'The advertisement is placed beside the site name in the header.' ),
                                             new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_468060_2', 'Banner Ad 2 (468x60)', 'The advertisement is placed just below the title in Search Result page, Categories page, Tags page, Author page, and Archives page.' ),
                                             new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_125125_1', 'Square Ad 1 (125x125)', 'The advertisement will be posted at the side bar.' ),
                                             new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_125125_2', 'Square Ad 2 (125x125)', 'The advertisement will be posted at the side bar.' ),
                                             new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_125125_3', 'Square Ad 3 (125x125)', 'The advertisement will be posted at the side bar.' ),
                                             new Padd_Input_Advertisement( PADD_THEME_SLUG . '_ads_125125_4', 'Square Ad 4 (125x125)', 'The advertisement will be posted at the side bar.' ), );

  echo var_dump( $padd_options[ 'advertisements' ] );

/*********************************TEST***********************************/

得到以下结果,显示该值是一个包含其他几个值的数组:

array (size=6)
  0 => 
    object(Padd_Input_Advertisement)[286]
      protected 'keyword' => string 'magaling_ads_468060_1' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[282]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-468x060.gif' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Banner Ad 1 (468x60)' (length=20)
      protected 'description' => string 'The advertisement is placed beside the site name in the header.' (length=63)
  1 => 
    object(Padd_Input_Advertisement)[284]
      protected 'keyword' => string 'magaling_ads_468060_2' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[283]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-468x060.gif' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Banner Ad 2 (468x60)' (length=20)
      protected 'description' => string 'The advertisement is placed just below the title in Search Result page, Categories page, Tags page, Author page, and Archives page.' (length=131)
  2 => 
    object(Padd_Input_Advertisement)[279]
      protected 'keyword' => string 'magaling_ads_125125_1' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[278]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-125x125.jpg' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Square Ad 1 (125x125)' (length=21)
      protected 'description' => string 'The advertisement will be posted at the side bar.' (length=49)
  3 => 
    object(Padd_Input_Advertisement)[277]
      protected 'keyword' => string 'magaling_ads_125125_2' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[276]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-125x125.jpg' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Square Ad 2 (125x125)' (length=21)
      protected 'description' => string 'The advertisement will be posted at the side bar.' (length=49)
  4 => 
    object(Padd_Input_Advertisement)[275]
      protected 'keyword' => string 'magaling_ads_125125_3' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[273]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-125x125.jpg' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Square Ad 3 (125x125)' (length=21)
      protected 'description' => string 'The advertisement will be posted at the side bar.' (length=49)
  5 => 
    object(Padd_Input_Advertisement)[217]
      protected 'keyword' => string 'magaling_ads_125125_4' (length=21)
      protected 'value' => 
        object(Padd_Advertisement)[216]
          private 'img_url' => string 'http://localhost/TestSite/wp-content/themes/magaling/images/advertisement-125x125.jpg' (length=86)
          private 'alt_desc' => string 'Padd Solutions' (length=14)
          private 'web_url' => string 'http://www.paddsolutions.com' (length=28)
          private 'target' => string '_new' (length=4)
          private 'css_class' => string '' (length=0)
      protected 'name' => string 'Square Ad 4 (125x125)' (length=21)
      protected 'description' => string 'The advertisement will be posted at the side bar.' (length=49)

我不知道为什么你的脚本中的值会丢失,但是你正在使用的主题或你调用函数的方式有些缺失或错误。顺便提一下,提供的信息是不够的

希望这有帮助。

答案 5 :(得分:1)

修改 是否需要非序列化调用:

$this->value = unserialize(get_option($keyword));

get_option已经返回了未序列化的对象(只要它是由update_option()保存的 - 如果需要,会自动将对象序列化,然后再保存到数据库中)

原始回答

我怀疑问题在于序列化对象的方式。

您需要确保在序列化过程中(转换为字符串表示)序列化对象的类型是已知的。只有这样你才能成功地反序列化(从字符串表示转换回对象)它。

回答关于_toString()的另一个问题。当您尝试在字符串上下文中使用对象时(例如,当您尝试回显对象时),PHP会神奇地调用此函数。你不要直接调用这个函数。

这是演示WORKING流程的单个php文件;对你应该寻找陷阱的部分的评论(问题的原因)。将其保存为index.php并运行以查看结果。

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

class Padd_Input_Advertisement {
    protected $keyword;
    protected $value;
    protected $name;
    protected $description;

    function __construct($keyword,$name,$description='') {
        $this->keyword = $keyword;
        $this->value = unserialize(get_option($keyword));
        $this->name = $name;
        $this->description = $description;        
    }

    public function get_keyword()         { return $this->keyword; }
    public function set_keyword($keyword) { $this->keyword = $keyword; }
    public function get_value()           {  return $this->value; }
    public function set_value($value)     { $this->value = $value; }
    public function get_name()            { return $this->name; }
    public function set_name($name)       { $this->name = $name; }
    public function get_description()     { return $this->description;}
    public function set_description($description) { $this->description = $description; }
    public function  __toString() {

        $strHTML  = '';
        $strHTML .= '<tr valign="top">';
        $strHTML .= '   <th scope="row"><label for="' . $this->keyword . '">' . $this->name . '</label></th>';
        $strHTML .= '   <td>';
        $strHTML .= '       <label for="' . $this->keyword. '_alt_desc">Short Description</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_alt_desc" type="text" id="' . $this->keyword . '_alt_desc" value="' . $this->value->get_alt_desc() . '" size="80" /><br />';
        $strHTML .= '       <label for="' . $this->keyword. '_img_url">Image URL</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_img_url" type="text" id="' . $this->keyword . '_img_url" value="' . $this->value->get_img_url() . '" size="80" /><br />';
        $strHTML .= '       <label for="' . $this->keyword. '_web_url">Website</label><br />';
        $strHTML .= '       <input name="' . $this->keyword . '_web_url" type="text" id="' . $this->keyword . '_web_url" value="' . $this->value->get_web_url() . '" size="80" />';
        $strHTML .= '       <br /><small>' . $this->description . '</small>';
        $strHTML .= '   </td>';
        $strHTML .= '</tr>';
        return $strHTML;
    }

}

//Just a sample of the class representing your option object
class Class_Of_Value {
    protected $alt_desc;
    protected $img_url;
    protected $web_url;

    public function __construct($keyword) {
        $this->alt_desc = 'description'; 
        $this->img_url = 'image'; 
        $this->web_url = 'web'; 
    }

    public function get_alt_desc() { return $this->alt_desc; }
    public function get_img_url()  { return $this->img_url; } 
    public function get_web_url()  { return $this->web_url; }
}

//Sample of a CORRECT get_option function.
function get_option($keyword) {
    //THIS IS IMPORTANT
    $valueObject = new Class_Of_Value($keyword);
    //MAKE SURE THAT TYPE of serialised value is KNOWN
    return serialize($valueObject); 
}
//Here is the root cause of your problem.
//Wordpress' get_option() DOES NOT serialise returned objects. It returns just value of an option pulled from database!
//Hence you can't call methods  $this->value->get_alt_desc() etc.


define ('PADD_NAME_SPACE', ''); //dummy definition of the constant for the sake of PHP Notices

$padd_options['advertisements'] = array(
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_1',
        'Square Ad 1 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_2',
        'Square Ad 2 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_3',
        'Square Ad 3 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
    new Padd_Input_Advertisement(
        PADD_NAME_SPACE . '_ads_125125_4',
        'Square Ad 4 (125x125)',
        'The advertisement will be posted at the side bar.'
    ),
);

//Here __toString will be called by PHP outputing your HTML form filled with object values.
echo($padd_options['advertisements'][0]);

建议您的问题的解决方案是确保在保存到数据库(WP的update_option())之前正确地序列化Wordpress选项(使用对象类型)。 因此,get_option将返回序列化字符串,然后在__construct方法中正确地反序列化。

答案 6 :(得分:1)

你试图强迫运营商 - &gt;优先?

我的意思是,从这个:

$this->value->get_alt_desc()

到此:

($this->value)->get_alt_desc()

也许您的PHP解释器正在尝试评估value->get_alt_desc()

答案 7 :(得分:-2)

所以,我已经找到了解决这个问题的方法,使代码按预期工作。它没有解决根本原因,但它更像是一种解决方法。

在__construct函数中我添加了:

$this->value2 = $this->value;

然后在导致错误的代码中我改变了:

$this->value->get_alt_desc()

$this->value2->get_alt_desc()

所以所有的代码都在工作,除了那个变量$ this-&gt; value正在失去它的值,而且一旦我使用了不同的变量名,一切都按原样运行。