6

我正在使用的 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->value 在 __construct 函数中设置正确,但在 __toString 函数中为空白。

编辑 2

我还应该提到在 __construct 函数中设置的其他变量在 __toString 函数中起作用,例如 $this->keyword。只是 $this->value 将变为空白。

编辑 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.'
    ),
);
4

8 回答 8

11

这是因为如果非序列化对象不知道类的类型,则它们不会保留方法。

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

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

[编辑]您可以查看PHP 手册以获取有关反序列化过程的更多详细信息。

于 2012-11-08T04:54:58.147 回答
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;
}
于 2012-11-12T15:33:53.790 回答
1

编辑: 是否需要反序列化调用:

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

get_option 已经返回未序列化的对象(只要它由 update_option() 保存 - 如果需要,它会在将对象保存到数据库之前自动序列化对象)

原始答案

我怀疑问题出在您序列化对象的方式上。

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

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

这是演示工作流程的单个 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]);

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

于 2012-11-14T01:41:12.120 回答
1

您是否尝试强制运算符 -> 优先级?

我的意思是,从这里:

$this->value->get_alt_desc()

对此:

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

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

于 2012-11-14T15:13:35.450 回答
1

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

您是否尝试过打开错误报告?

error_reporting(E_ALL);
ini_set("display_errors", 1);
于 2012-11-06T05:00:48.737 回答
1

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

所以你已经像这样调用了类的函数

$this->set_name();
于 2012-11-08T04:34:25.760 回答
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)

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

希望这可以帮助。

于 2012-11-11T16:16:08.427 回答
-2

所以,我想出了一个解决这个问题的方法,使代码按预期工作。它不能解决根本原因,但它更像是一种解决方法。

在 __construct 函数中,我添加了:

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

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

$this->value->get_alt_desc()

$this->value2->get_alt_desc()

所以所有的代码都在工作,除了一个变量 $this->value 失去了它的价值,一旦我使用了一个不同的变量名,一切都按照它应该有的方式工作。

于 2012-11-08T05:31:14.293 回答