du5910 2019-02-21 15:54
浏览 157
已采纳

PHP链式类方法与其他类合并

I start with an example.

Mold class

<?php
class Mold {
  public $current;

  function merge($first, $second) {
    $this->current = $first . $second;
    return $this;
  }

  function phone() {
    $this->current = '<a href="tel:' . $this->current . '">' . $this->current . '</a>';
    return $this;
  }

  function __toString() {
    return $this->current;
  }
}

function mold() {
  return new Mold();
}

In action

This works as expected.

echo mold()->merge('sada', 'asdsa')->phone();

Problem

I have one or more classes with methods that wants to be available as well.

Plugin class

class MyPlugin {
  function link() {
    // Code
  }

  function currency($number) {
    // Code
  }
}
class MyPlugin2 {
  // Other methods
}

Dream code

The exact change of events below may not make any sense. Anyway, what I intend to do is the following.

echo mold()->merge('sada', 'asdsa')->currency(45)-link();
  • Call mold() which creates a new instance of the Mold class.
  • Chain merge() which is used from the Mold class.
  • currency() or link() method does not exist in the Mold class. Instead they should be loaded from one of the plugins.

In conclusion

  • I know I can extend a class but it does not really solve the problem because there can be more than one plugin classes.
  • I know I can create instances of the plugin classes, but they somehow need to be aware by the Mold class.
  • Append methods to a class comes to mind as well as merge classes.
  • 写回答

3条回答 默认 最新

  • dongliang1893 2019-02-22 15:25
    关注

    Interesting ideas.

    The one that solves the problem like I had in my mind was to use traits like @vivek_23 suggested in a comment.

    Here is a complete example of how it works

    <?php
    // Core methods
    class MoldCore {
      public $current;
    
      function merge($first, $second) {
        $this->current = $first . $second;
        return $this;
      }
    
      function phone() {
        $this->current = '<a href="tel:' . $this->current . '">' . $this->current . '</a>';
        return $this;
      }
    
      function __toString() {
        return $this->current;
      }
    }
    
    // Plugin 1
    trait Plugin1 {
      public function yaay() {
        $this->current .= ' Plugin1 yaay';
        return $this;
      }
    }
    
    // Plugin 2
    trait Plugin2 {
      public function hello() {
        $this->current = str_replace('Plugin1', 'Modified', $this->current);
        return $this;
      }
    
      public function world() {
        $this->current .= ' Plugin2 world';
        return $this;
      }
    }
    
    // Glue plugins with MoldCore
    class Mold extends MoldCore {
      use Plugin1, Plugin2;
    }
    
    $mold = new Mold();
    echo $mold->merge('sada', 'asdsa')->phone()->yaay()->hello();
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题