サポート » プラグイン » register_activation_hook関数で使われている引数の解釈

  • 解決済 echizenya

    (@echizenya)


    (質問の主旨)
    WordPressのプラグインを作る時に使う、
    register_activation_hook( __FILE__ , array( $this, ‘add_application_user_roles’ ) );という
    記述について教えてください

    (質問の補足)

    1.
    現在、「WordPressによるWebアプリケーション開発」という参考書のP34を写経中です。
    https://goo.gl/mtdFxJ

    2.
    WordPress Codexでregister_activation_hook関数の使用例を確認すると、
    register_activation_hook( __FILE__, ‘myplugin_activate’ );
    となっています。ですが参考書の第二引数は、配列になっています。これはなぜでしょうか?
    https://goo.gl/9EknWx

    3.
    配列の一番目の要素は$thisとなっています。一般的なPHPのコードを見ているとクラス内で使われている
    プロパティの初期化メソッドとして、

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

    という表現が用いられます。ここで使われている$thisとは、WPWA_User_Managerというクラスのことを指していると解釈してもよろしいのでしょうか?

    4.
    pluginsディレクトリの下にwpwa-user-managerというディレクトリを設け、さらにclass-wpwa-user-manager.phpというファイルでプラグインを作成しております。当該ファイルのコードは以下のとおりです。

    <?php
    class WPWA_User_Manager {
      public function __construct() {
        // 初期化コード
        register_activation_hook( __FILE__ , array( $this, 'add_application_user_roles' ) );
      }
      // フォロワー、開発者、メンバー 3種類のユーザーロール
      public function add_application_user_roles() {
          add_role( 'follower', 'Follower', array( 'read' => true ) );
          add_role( 'developer', 'Developer', array( 'read' => true ) );
          add_role( 'member', 'Member', array( 'read' => true ) );
      }
    
    }
    
    $user_manage = new WPWA_User_Manager;

    ご存知の方がいらっしゃいましたら、ご教示のほどよろしくお願い申し上げます。

    • このトピックはechizenyaが4 ヶ月、 1 週前に変更しました。
8件の返信を表示中 - 1 - 8件目 (全8件中)
  • kimipooh

    (@kimipooh)

    2.

    register_activation_hook()


    をみると、array( $this, ‘add_application_user_roles’ ) の部分は、add_action の $function のへ引き渡されます。
    で、add_actionの説明をみると

    add_action()


    クラスをつかうときには、add_action の第2引数は arrayにして、疑似変数 $this をいれてておけってことですね。
    これは関数(メソッド)がどのクラスにあるのかを示さないといけないってことだと思います。

    つまりクラス内で register_activation_hook や add_action を使うなら第二引数は array($this, ‘関数’);
    をクラスを使わないなら、 ‘関数’を使えばいいってことですね。

    3. はその通りだと思います。

    class WPWA_User_Manager {
      $name = 'hogege';
      public function __construct() {
         $name = 'hohoho';
         $this->name = $name; 
      }
    }

    の場合、 WPWA_User_Manager直下の $name の値を、 _construct 関数内の $name の値に上書きするということになります。

    echizenya

    (@echizenya)

    kimipoohさん。
    ご丁寧な説明ありがとうございます!

    array( $this, ‘add_application_user_roles’ ) の部分は、add_action の $function のへ引き渡されます。

    つまりクラス内で register_activation_hook や add_action を使うなら第二引数は array($this, ‘関数’);をクラスを使わないなら、 ‘関数’を使えばいいってことですね。

    了解しました!
    ただ

    add_action()

    add_action関数の第二引数を確認すると、

    $function_to_add
    (callable) (Required) The name of the function you wish to be called.

    となっています。この英文から、第2引数でarrayを使い、疑似変数 $thisを入れるという解釈が自分の頭の中では繋げることができません。お手数をおかけして誠に恐れ入りますが、add_action関数の第二引数に関する解釈も、合わせてご教示いただければ幸いです。

    以上、よろしくお願い申し上げます。

    モデレーター Okamoto Hidetaka

    (@hideokamoto)

    add_action()

    Using with a Class
    To use add_action() when your plugin or theme is built using classes, you need to use the array callable syntax. You would pass the function to add_action() as an array, with $this as the first element, then the name of the class method, like so:

    Google翻訳の結果

    クラスで使用する
    プラグインまたはテーマがクラスを使用して構築されているときにadd_action()を使用するには、配列呼び出し可能構文を使用する必要があります。 この関数を配列としてadd_action()に渡します。$ thisを最初の要素として使用し、次にクラスメソッドの名前を次のようにします。

    kimipooh

    (@kimipooh)

    $function_to_add は型として callable となっています。
    で、callable の文法は
    http://php.net/manual/ja/language.types.callable.php
    にある通り、クラス内関数(メソッド)かどうかで記述方法が違うわけです。

    でお示しのヘルプではそのあたりが、説明不足だとは思いますが
    https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_action
    で説明されているかなと思います。

    あと問題はこの理解ですね。
    これはクラスの概念と関係があります。超ざっくり説明しますと(アクセス修飾子とか細かいことを全無視するなら)

    クラスを使わない関数群 = グローバル関数群 = どこからでもその関数を参照・利用可
    クラス内関数群 = プライベート関数群 = クラス名を指定して参照・利用可

    とまぁこの違いがあります。つまり add_action で関数を書くだけの場合、クラス内関数は利用できないことになります。クラス名が分からないので。そこで $this の登場です。いやまぁ ‘WPWA_User_Manager’ でもいいのですが、毎回クラスごとにベタ打ちするとクラス名変更をするとかプログラムを使いまわすときとか不便ですよね。そこで現在いるクラスっていう意味で $this が使われます。つまり $this は 今いるクラスのクラス名が入るってことですね。

    $this->hogege(); は現在いるクラス内にある hogege関数(メソッド)だよ〜っていうわけです。
    hogehogeclassというクラス内の関数を使いたいなら、
    $hoge = new hogehogeclass(); とクラスを参照した上で、
    $hoge->hogege(); ってなります。

    kimipooh

    (@kimipooh)

    おっと、

    add_action()


    もちゃんとクラスの場合の記述がありますね… いずれにしても何故必要かは説明した通りです。

    msio

    (@msio)

    やり取りと詳細について精査していないのでざっくり適当な見解なので申し訳ないのですが質問者さんの
    「配列になるのはなぜか」について
    フックの位置がストリーム内なのでレセプタが必要ないため単次元の変数でよくて
    プラグインなどクラス化したものからのアクセスの場合、どこにレスポンスを返すのか指定が必要なため配列変数になっているのではないでしょうか。

    簡単にいうとピザ屋に徒歩でピザを買いに行くと住所を伝える必要がなく受け取りまでを待ちにしたり出来たら連絡してもらうことができますが、宅配だと住所を指定しないとピザを作成する作業を依頼してもピザは到着しないということではないでしょうか。

    フックというのは主作業に対してわりこみをかけることで、日々淡々とピザを焼いているピザ屋に「私のために1枚つくってくれ」とオーダーすることのようなものです。
    そのピザができあがったらどこにとどけますか、または届けなくてもいいですかという指示がレセプタの用意で、作業がおわったらここに返事をくれと配列の形式で流す、その対象が指示者のクラスなのでthisになっていたということではないでしょうか。

    クラス化してある、というのは指示と答えが別のプロセスで動くというメリットのかわりに派生する変数がそのクラス内で完結するため、結果を返す先を指定しないとクラスというプロセス内で消滅してしまうので、指示渡し時に返答の位置を指示しておくという必要があると思います。
    なんでもかんでもグローバル変数で同じ変数名がかぶって上書きみたいなミスを多人数作業で発生させない、かつルーチン内の定義は各員自由にできるというアジャイルの流れかと思うですがいかがでしょうか。

    msio

    (@msio)

    あと細かいことなんですが結果を渡す先を指示するまではわかるにしてもなぜ配列なのか、については巻数にパラメータをはじめから三つ、ひとつはもしかしたら外部変数へのリフレクションかもしくは使わない盲腸のようなパラメータを用意するよりは二つで運用して二つ目が「is_array」判定されたらレスポンスを指定のオブジェクトへ返す仕様のほうがスマートだからではないかと思います。
    もうひとつ、クラスとグローバルの範囲についてなのですがイメージとしては「声が届く範囲がそのプロセスのグローバル」であり「声がとどかない距離、または近距離でも厚いへだたりを超えて作業をしている状態」がクラス、みたいに言うとよけいにわかりにくいでしょうか。どうでしょうか。
    距離が近くて声がとどかないなんてありえない、と想像されるようなきがするのですがたとえば「冷蔵庫」というへだたりは温度の維持を内と外、それぞれに有益な状態をたもっていますが厚い隔たりで「同じプロセス上に置けない」ものだと思います。
    仮に、スパゲッティプログラムという全部グローバルで同じプロセスで組むというのは「冷蔵庫にガスコンロがある状態、レスポンスも早く最小で最速の結果を得られる」ものですが、それをとりまく環境をひたすら汚染することが想像できるのではないでしょうか。
    いかがでしょうか。

    echizenya

    (@echizenya)

    みなさま、コメントやアドバイスありがとうございます!

    @hideokamotoさん。
    add_actionのページについて、最後まで読んでいませんでした。
    “Using with a Class”の例文のご紹介ありがとうございます。十分参考にさせていただきました。

    @kimipoohさん。
    PHPのドキュメンテーションのご紹介ありがとうございます。

    受け渡し
    オブジェクトのインスタンスを渡すには配列を使います。 配列の 0 番目の要素にオブジェクトを、
    そして 1 番目の要素にメソッド名を指定します。 protected メソッドや private メソッドは、クラスの内部からはアクセスできます。

    ↑の説明を読むと、register_activation_hook()の第二引数で、なぜarray()や$thisを使うのか、分かってきました。

    @msioさん。
    わたしの「配列になるのはなぜか」という疑問について、詳細な説明ありがとうございます。
    WordPressのプラグインやアプリケーション開発についてはまだ始めたばかりなので、とても参考になりました。

    “フック”という用語は今ひとつ何をさしているのか、今まで分かっていませんでしたが、「ピザ屋さんの例え」が大変分かりやすく、理解が進みました。

    二つで運用して二つ目が「is_array」判定されたらレスポンスを指定のオブジェクトへ返す仕様のほうがスマートだからではないかと思います。

    そこまではとても考えは及びませんでした。今後自分でプラグインやアプリケーションを作れるようになったときの
    参考にさせていただきたいと思います。

    みなさまので、register_activation_hook( __FILE__ , array( $this, ‘add_application_user_roles’ ) );
    について解釈できるようになりました。参考書の「WordPressによるWebアプリケーション開発」の写経を続けるようにします。
    ありがとうございました。

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • このトピックに返信するにはログインが必要です。