我正在使用的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.'
),
);
答案 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正在失去它的值,而且一旦我使用了不同的变量名,一切都按原样运行。