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

$this->keyword のように、__construct 関数で設定された他の変数が __toString 関数で機能していることにも言及する必要があります。空白になるのは $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ます。このクラスは基本的にダミークラスです。メソッドはありません。ただし、逆シリアル化されたオブジェクトの属性にアクセスできます。

$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

質問のスクリプトを含むPaddSolutionsの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 に答える
1

演算子 -> 優先順位を強制しようとしましたか?

つまり、これから:

$this->value->get_alt_desc()

これに:

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

おそらくあなたのPHPインタープリターは評価しようとしていますvalue->get_alt_desc()

于 2012-11-14T15:13:35.450 に答える
1

オブジェクト指向プログラミングでは、を使用して関数を呼び出す必要があります$this。関数では、関数__toString()を直接呼び出します。

したがって、このようなクラスの関数を呼び出しました

$this->set_name();
于 2012-11-08T04:34:25.760 に答える
1

これをコメントとして追加したかったのですが、まだそれを行うための評判ポイントがないと思います.

エラー報告を有効にしてみましたか?

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

編集: unserialise 呼び出しが必要です:

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

get_option は既にシリアル化されていないオブジェクトを返します (それが update_option() によって保存されている限り - データベースに保存する前に必要に応じてオブジェクトを自動的にシリアル化します)

元の答え

問題は、オブジェクトをシリアル化する方法にあると思われます。

シリアル化プロセス(文字列表現への変換)中に、シリアル化されたオブジェクトの型が KNOWN であることを確認する必要があります。そうして初めて、正常に逆シリアル化(文字列表現からオブジェクトに変換) することができます。

に関する別の質問にお答えします_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's ) に保存される前に、Wordpress オプションが (オブジェクト タイプで) 適切にシリアル化されていることを確認することですupdate_option()。したがって、 get_option はシリアル化された文字列を返し、メソッドで適切にシリアル化を解除します__construct

于 2012-11-14T01:41:12.120 に答える
-2

そのため、コードを期待どおりに機能させるこの問題の解決策を見つけました。根本的な原因を解決するわけではありませんが、回避策です。

__construct 関数に次を追加しました。

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

そして、私が変更したエラーの原因となったコードで:

$this->value->get_alt_desc()

$this->value2->get_alt_desc()

そのため、1 つの変数 $this->value がその値を失っていたことを除いて、すべてのコードが機能していました。別の変数名を使用すると、すべてが正常に機能しました。

于 2012-11-08T05:31:14.293 に答える