Object.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\base;
  8. use Yii;
  9. /**
  10. * Object is the base class that implements the *property* feature.
  11. *
  12. * @include @yii/base/Object.md
  13. *
  14. * @author Qiang Xue <[email protected]>
  15. * @since 2.0
  16. */
  17. class Object implements Arrayable
  18. {
  19. /**
  20. * @return string the fully qualified name of this class.
  21. */
  22. public static function className()
  23. {
  24. return get_called_class();
  25. }
  26. /**
  27. * Constructor.
  28. * The default implementation does two things:
  29. *
  30. * - Initializes the object with the given configuration `$config`.
  31. * - Call [[init()]].
  32. *
  33. * If this method is overridden in a child class, it is recommended that
  34. *
  35. * - the last parameter of the constructor is a configuration array, like `$config` here.
  36. * - call the parent implementation at the end of the constructor.
  37. *
  38. * @param array $config name-value pairs that will be used to initialize the object properties
  39. */
  40. public function __construct($config = [])
  41. {
  42. if (!empty($config)) {
  43. Yii::configure($this, $config);
  44. }
  45. $this->init();
  46. }
  47. /**
  48. * Initializes the object.
  49. * This method is invoked at the end of the constructor after the object is initialized with the
  50. * given configuration.
  51. */
  52. public function init()
  53. {
  54. }
  55. /**
  56. * Returns the value of an object property.
  57. *
  58. * Do not call this method directly as it is a PHP magic method that
  59. * will be implicitly called when executing `$value = $object->property;`.
  60. * @param string $name the property name
  61. * @return mixed the property value
  62. * @throws UnknownPropertyException if the property is not defined
  63. * @throws InvalidCallException if the property is write-only
  64. * @see __set()
  65. */
  66. public function __get($name)
  67. {
  68. $getter = 'get' . $name;
  69. if (method_exists($this, $getter)) {
  70. return $this->$getter();
  71. } elseif (method_exists($this, 'set' . $name)) {
  72. throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
  73. } else {
  74. throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
  75. }
  76. }
  77. /**
  78. * Sets value of an object property.
  79. *
  80. * Do not call this method directly as it is a PHP magic method that
  81. * will be implicitly called when executing `$object->property = $value;`.
  82. * @param string $name the property name or the event name
  83. * @param mixed $value the property value
  84. * @throws UnknownPropertyException if the property is not defined
  85. * @throws InvalidCallException if the property is read-only
  86. * @see __get()
  87. */
  88. public function __set($name, $value)
  89. {
  90. $setter = 'set' . $name;
  91. if (method_exists($this, $setter)) {
  92. $this->$setter($value);
  93. } elseif (method_exists($this, 'get' . $name)) {
  94. throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
  95. } else {
  96. throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
  97. }
  98. }
  99. /**
  100. * Checks if the named property is set (not null).
  101. *
  102. * Do not call this method directly as it is a PHP magic method that
  103. * will be implicitly called when executing `isset($object->property)`.
  104. *
  105. * Note that if the property is not defined, false will be returned.
  106. * @param string $name the property name or the event name
  107. * @return boolean whether the named property is set (not null).
  108. */
  109. public function __isset($name)
  110. {
  111. $getter = 'get' . $name;
  112. if (method_exists($this, $getter)) {
  113. return $this->$getter() !== null;
  114. } else {
  115. return false;
  116. }
  117. }
  118. /**
  119. * Sets an object property to null.
  120. *
  121. * Do not call this method directly as it is a PHP magic method that
  122. * will be implicitly called when executing `unset($object->property)`.
  123. *
  124. * Note that if the property is not defined, this method will do nothing.
  125. * If the property is read-only, it will throw an exception.
  126. * @param string $name the property name
  127. * @throws InvalidCallException if the property is read only.
  128. */
  129. public function __unset($name)
  130. {
  131. $setter = 'set' . $name;
  132. if (method_exists($this, $setter)) {
  133. $this->$setter(null);
  134. } elseif (method_exists($this, 'get' . $name)) {
  135. throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
  136. }
  137. }
  138. /**
  139. * Calls the named method which is not a class method.
  140. *
  141. * Do not call this method directly as it is a PHP magic method that
  142. * will be implicitly called when an unknown method is being invoked.
  143. * @param string $name the method name
  144. * @param array $params method parameters
  145. * @throws UnknownMethodException when calling unknown method
  146. * @return mixed the method return value
  147. */
  148. public function __call($name, $params)
  149. {
  150. throw new UnknownMethodException('Unknown method: ' . get_class($this) . "::$name()");
  151. }
  152. /**
  153. * Returns a value indicating whether a property is defined.
  154. * A property is defined if:
  155. *
  156. * - the class has a getter or setter method associated with the specified name
  157. * (in this case, property name is case-insensitive);
  158. * - the class has a member variable with the specified name (when `$checkVars` is true);
  159. *
  160. * @param string $name the property name
  161. * @param boolean $checkVars whether to treat member variables as properties
  162. * @return boolean whether the property is defined
  163. * @see canGetProperty()
  164. * @see canSetProperty()
  165. */
  166. public function hasProperty($name, $checkVars = true)
  167. {
  168. return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
  169. }
  170. /**
  171. * Returns a value indicating whether a property can be read.
  172. * A property is readable if:
  173. *
  174. * - the class has a getter method associated with the specified name
  175. * (in this case, property name is case-insensitive);
  176. * - the class has a member variable with the specified name (when `$checkVars` is true);
  177. *
  178. * @param string $name the property name
  179. * @param boolean $checkVars whether to treat member variables as properties
  180. * @return boolean whether the property can be read
  181. * @see canSetProperty()
  182. */
  183. public function canGetProperty($name, $checkVars = true)
  184. {
  185. return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
  186. }
  187. /**
  188. * Returns a value indicating whether a property can be set.
  189. * A property is writable if:
  190. *
  191. * - the class has a setter method associated with the specified name
  192. * (in this case, property name is case-insensitive);
  193. * - the class has a member variable with the specified name (when `$checkVars` is true);
  194. *
  195. * @param string $name the property name
  196. * @param boolean $checkVars whether to treat member variables as properties
  197. * @return boolean whether the property can be written
  198. * @see canGetProperty()
  199. */
  200. public function canSetProperty($name, $checkVars = true)
  201. {
  202. return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
  203. }
  204. /**
  205. * Returns a value indicating whether a method is defined.
  206. *
  207. * The default implementation is a call to php function `method_exists()`.
  208. * You may override this method when you implemented the php magic method `__call()`.
  209. * @param string $name the property name
  210. * @return boolean whether the property is defined
  211. */
  212. public function hasMethod($name)
  213. {
  214. return method_exists($this, $name);
  215. }
  216. /**
  217. * Converts the object into an array.
  218. * The default implementation will return all public property values as an array.
  219. * @return array the array representation of the object
  220. */
  221. public function toArray()
  222. {
  223. return Yii::getObjectVars($this);
  224. }
  225. }