読めるけど書けない

Twitter ツイート Hatena Bookmark ブックマーク

読めるけど書けない修飾子としてPHPには「niigata新潟アクセス修飾子」という@supper_rtiさんが作ってくれたパッチが存在します。
ネタと言えばネタだけど、とても素敵だし、本家にも実装してほしい機能の一つだったりもしますw
でもパッチ当てるのは実際面倒だし・・・そもそもそういう事が出来ない環境だけど、niigataアクセス修飾子が欲しくなるときは多々あるかと思います。

__get()使えば普通に実装できるって話も聞いてたので、実際に実装してみました。
速度的にはあれだけど、まあ遊びとして使う分にはありかと思いますw

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
<?php
abstract class Lemon {
  protected $__isNigata2Properties;
  protected $__isFinalProperties;


  public function __construct() {

    $this->__isNigata2Properties = array();
    $this->__isFinalProperties = array();
    $refectionClass = new ReflectionClass($this);
    foreach ($refectionClass->getProperties() as $property) {
      if ($property->getDocComment() === false) {
        continue;
      }
      if ($property->isPublic()) {
        continue;
      }

      foreach (explode("\n",$property->getDocComment()) as $value) {
        $value = str_replace(array("\t", "*", "\n", " "), "", $value);
        if ($this->__isNiigataAccess($value)) {
          $this->__isNigata2Properties[$property->getName()] = true;
          $this->__isFinalProperties[$property->getName()] = $this->__isFinalAccess($value);
          break;
        }
      }

    }
  }

  /**
   * GETマジックメソッド
   * @param string $name
   * @return string
   */
  public function __get($name) {
    if (isset($this->__isNigata2Properties[$name])) {
      $reflection = new ReflectionProperty($this,$name);
      $reflection->setAccessible(true);
      if ($this->__isFinalProperties[$name]) {
        $refectionClass = new ReflectionClass($this);
        $defaultProperties = $refectionClass->getDefaultProperties();
        return $defaultProperties[$name];
      } else {
        return $reflection->getValue($this);
      }
    } else {
      return parent::__get($name);
    }
  }

  /**
   * 檸檬かどうかのチェックを行う
   * @param string $value
   * @return boolean
   */
  protected function __isNiigataAccess($value) {
    return (strpos($value,"@access") !== false && strpos($value,"lemon"));
  }

  protected function __isFinalAccess($value) {
    return (strpos($value,"@access") !== false && strpos($value,"final"));
  }

}


// 以下テスト
// 変数のプロパティに対して「@access」のあとに「lemon」、「檸檬」、「れもん」とか
// つければプライベートな変数にアクセスできる
class Hoge extends Lemon {

  /**
   * @access lemon
   */
  private $hoge = "れもん";

  /**
   * @access final lemon
   */
  private $hoge2 = "イエロー";

  public function change() {
    $this->hoge = "レモン汁";
  }

  public function change2() {
    $this->hoge2 = "ぶるー";
  }

  public function check() {
    var_dump($this->hoge2);
  }

}

$hoge = new Hoge();
var_dump($hoge->hoge);
$hoge->change();
var_dump($hoge->hoge);
var_dump("----");
var_dump($hoge->hoge2);
$hoge->change2();
var_dump($hoge->hoge2);
comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。