Paradigm Shift Design

ISHITOYA Kentaro's blog.

staticなプロパティの存在確認

メモ.

 <?php
 class A{
     public static $sa;
     protected static $sb;
     private static $sc;
     public $a;
     protected $b;
     private $c;
     const ca = "ca";
 
     function check($name){
         var_dump(property_exists($this, $name));
     }
     function checkc($name){
         var_dump(defined("self::$name"));
     }
     function checkcv($name){
         $vars = get_class_vars(get_class($this));
         var_dump(array_key_exists($name, $vars));
     }
     function checkrc($name){
         $class = new ReflectionClass($this);
         var_dump($class->hasProperty($name));
     }
 }
 
 $a = new A();
 
 echo "ckeck with property_exists \n";
 echo "static public a :";
 $a->check("sa");
 echo "static protected b :";
 $a->check("sb");
 echo "static private c :";
 $a->check("sc");
 echo "public a :";
 $a->check("a");
 echo "protected b :";
 $a->check("b");
 echo "private c :";
 $a->check("c");
 
 echo "\n";
 echo "check with defined function \n";
 echo "static public a :";
 $a->checkc("sa");
 echo "static protected b :";
 $a->checkc("sb");
 echo "static private c :";
 $a->checkc("sc");
 echo "public a :";
 $a->checkc("a");
 echo "protected b :";
 $a->checkc("b");
 echo "private c :";
 $a->checkc("c");
 echo "const ca :";
 $a->checkc("ca");
 
 echo "\n";
 echo "and check with get_class_vars function \n";
 echo "static public a :";
 $a->checkcv("sa");
 echo "static protected b :";
 $a->checkcv("sb");
 echo "static private c :";
 $a->checkcv("sc");
 echo "public a :";
 $a->checkcv("a");
 echo "protected b :";
 $a->checkcv("b");
 echo "private c :";
 $a->checkcv("c");
 echo "const ca :";
 $a->checkcv("ca");
 
 echo "\n";
 echo "finally check with ReflectionClass \n";
 echo "static public a :";
 $a->checkrc("sa");
 echo "static protected b :";
 $a->checkrc("sb");
 echo "static private c :";
 $a->checkrc("sc");
 echo "public a :";
 $a->checkrc("a");
 echo "protected b :";
 $a->checkrc("b");
 echo "private c :";
 $a->checkrc("c");
 echo "const ca :";
 $a->checkrc("ca");
 
 echo "\n";
 echo "speed check\n";
 $times = 100000;
 check(array($a, "check"), "sa", "check with property_exists:", $times);
 check(array($a, "checkc"), "sa", "check with defined:", $times);
 check(array($a, "checkcv"), "sa", "check with get_class_vars:", $times);
 check(array($a, "checkrc"), "sa", "check with ReflectionClass:", $times);
 function check($callback, $arg, $string, $times){
     echo $string;
     ob_start();
     $start = microtime(true);
     for($i = 0; $i < $times; $i++){
         call_user_func($callback, $arg);
     }
     $end = microtime(true);
     ob_end_clean();
     $elapsed = ($end - $start);
     echo "elapsed : $elapsed\n";
 }
 ?>


を実行すると、

 [kentaro@satsuki test]$ php -f propertyExistsTest.php
 check with property_exists
  static public a :bool(false)
  static protected b :bool(false)
  static private c :bool(false)
  public a :bool(true)
  protected b :bool(true)
  private c :bool(true)
 
 check with defined function
  static public a :bool(false)
  static protected b :bool(false)
  static private c :bool(false)
  public a :bool(false)
  protected b :bool(false)
  private c :bool(false)
  const ca :bool(true)
 
 and check with get_class_vars function
  static public a :bool(true)
  static protected b :bool(true)
  static private c :bool(true)
  public a :bool(true)
  protected b :bool(true)
  private c :bool(true)
  const ca :bool(false)
 
 finally check with ReflectionClass
  static public a :bool(true)
  static protected b :bool(true)
  static private c :bool(true)
  public a :bool(true)
  protected b :bool(true)
  private c :bool(true)
  const ca :bool(false)
 
 speed check
  check with property_exists:elapsed : 0.6119921207428
  check with defined:elapsed : 0.60511517524719
  check with get_class_vars:elapsed : 1.0757899284363
  check with ReflectionClass:elapsed : 1.1798391342163

上記のとおり、スタティックプロパティは、組み込み関数ではチェックできない。

かならず、リフレクションを使ってチェックすること。