Monthly Archives: January 2014

php对象中最基础的东东 — Object

在开发php框架的时候,我们总需要一个最最基础的类,而这个类负责着最最基础的东西,在OO中,Object就是最原始,最底层的结构。为何需要Object?Object是一个对象,这个对象中它含有属性、方法。通过所需要的对象捏合在一起,就成了一个东西。 就比方说家里的照明,它就包含有2个Object:开关和灯泡。 开关拥有链接电源和断开电源的功能,而灯泡具有亮和灭的属性,两者结合在一起就成了家里的最简单的照明系统。 同样,在PHP中需要各种各样的类,组合起来产生一个为人服务的功能。

PHP的Class默认是有__get, __set, __isset, __unset, __call这些基础的magic, 但是如果你不在class中实现这些方法的时候,是不会自动启用的。

1. __get
当$object->property 就会自动触发,这样就把$object的属性(类变量)完全暴露出来了,为了安全期间,只有拥有get{name}方法的可以读取到

2. __set
当$object->property = $value 就会自动触发,会将值直接赋予到该属性上。 同上, 只有拥有set{name}方法的才能进行属性设置。 这样避免了一个object的完全暴露

在object中,只要让property能读取,那么就一定有设定的方法。因此,只要property拥有get属性,那么他同时也要拥有set属性

3. __isset
当使用islet时会触发,用于判断$object是否有property

4. __unset
当使用unset是会触发,将值赋值为null

5. __call
当调用$obejct->xx(), 如果调用失败的时候,会触发__call

6. hasMethod
判断该$object是否拥有此方法

7. hasPerporty
判断该$object是否拥有此属性,一般通过判断 公有property是否可以读取、是否可以赋值 或者 私有属性是否存在(property_exists)

好了,上面已经把大致的Object基础讲了一边,下面是基本实现

class Object {
   //获得当前Object的类名
   public static function className() {
      return get_called_class();
   }

   public function __get() {
       $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
           return $this->$getter();
        } elseif (method_exists($this, 'set' . $name)) {
           throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
        } else {
           throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
        }
   }

   public function __set() {
       $setter = 'set' . $name;
        if (method_exists($this, $setter)) {
           return $this->$setter();
        } elseif (method_exists($this, 'get' . $name)) {
           throw new InvalidCallException('Getting read-only property: ' . get_class($this) . '::' . $name);
        } else {
           throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
        }
   }
   
   public function __isset($name) {
        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
           return $this->$getter() !== null;
        } else {
           return false;
        }
    }

   public function __unset($name) {
        $setter = 'set' . $name;
        if (method_exists($this, $setter)) {
           return $this->$setter(null);
        } else {
           throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
        }
    }

    public function hasProperty($name, $checkVars = true) {
        return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
    }

    public function canGetProperty($name, $checkVars) {
       return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
    }

    public function canSetProperty($name, $checkVars) {
       return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
    }

    public function hasMethod($name) {
       return method_exists($this, $name);
    }
}

这上面只有最最基础的Object,在现实中,Object可能会有各种各样的变化,因此我们需要在实际情况下,对Object进行改进。