1 | <?php |
||
56 | class Instance |
||
57 | { |
||
58 | /** |
||
59 | * @var string the component ID, class name, interface name or alias name |
||
60 | */ |
||
61 | public $id; |
||
62 | |||
63 | |||
64 | /** |
||
65 | * Constructor. |
||
66 | * @param string $id the component ID |
||
67 | */ |
||
68 | 75 | protected function __construct($id) |
|
72 | |||
73 | /** |
||
74 | * Creates a new Instance object. |
||
75 | * @param string $id the component ID |
||
76 | * @return Instance the new Instance object. |
||
77 | */ |
||
78 | 21 | public static function of($id) |
|
82 | |||
83 | /** |
||
84 | * Resolves the specified reference into the actual object and makes sure it is of the specified type. |
||
85 | * |
||
86 | * The reference may be specified as a string or an Instance object. If the former, |
||
87 | * it will be treated as a component ID, a class/interface name or an alias, depending on the container type. |
||
88 | * |
||
89 | * If you do not specify a container, the method will first try `Yii::$app` followed by `Yii::$container`. |
||
90 | * |
||
91 | * For example, |
||
92 | * |
||
93 | * ```php |
||
94 | * use yii\db\Connection; |
||
95 | * |
||
96 | * // returns Yii::$app->db |
||
97 | * $db = Instance::ensure('db', Connection::class); |
||
98 | * // returns an instance of Connection using the given configuration |
||
99 | * $db = Instance::ensure(['dsn' => 'sqlite:path/to/my.db'], Connection::class); |
||
100 | * ``` |
||
101 | * |
||
102 | * @param object|string|array|static $reference an object or a reference to the desired object. |
||
103 | * You may specify a reference in terms of a component ID or an Instance object. |
||
104 | * Starting from version 2.0.2, you may also pass in a configuration array for creating the object. |
||
105 | * If the "class" value is not specified in the configuration array, it will use the value of `$type`. |
||
106 | * @param string $type the class/interface name to be checked. If null, type check will not be performed. |
||
107 | * @param ServiceLocator|Container $container the container. This will be passed to [[get()]]. |
||
108 | * @return object the object referenced by the Instance, or `$reference` itself if it is an object. |
||
109 | * @throws InvalidConfigException if the reference is invalid |
||
110 | */ |
||
111 | 242 | public static function ensure($reference, $type = null, $container = null) |
|
112 | { |
||
113 | 242 | if (is_array($reference)) { |
|
114 | 4 | $class = isset($reference['class']) ? $reference['class'] : $type; |
|
115 | 4 | if (!$container instanceof Container) { |
|
116 | 2 | $container = Yii::$container; |
|
117 | } |
||
118 | 4 | unset($reference['class']); |
|
119 | 4 | $component = $container->get($class, [], $reference); |
|
120 | 4 | if ($type === null || $component instanceof $type) { |
|
121 | 3 | return $component; |
|
122 | } |
||
123 | |||
124 | 1 | throw new InvalidConfigException('Invalid data type: ' . $class . '. ' . $type . ' is expected.'); |
|
125 | } elseif (empty($reference)) { |
||
126 | 1 | throw new InvalidConfigException('The required component is not specified.'); |
|
127 | } |
||
128 | |||
129 | 240 | if (is_string($reference)) { |
|
130 | 54 | $reference = new static($reference); |
|
131 | 213 | } elseif ($type === null || $reference instanceof $type) { |
|
132 | 210 | return $reference; |
|
133 | } |
||
134 | |||
135 | 57 | if ($reference instanceof self) { |
|
136 | try { |
||
137 | 56 | $component = $reference->get($container); |
|
138 | 3 | } catch (\ReflectionException $e) { |
|
139 | 3 | throw new InvalidConfigException('Failed to instantiate component or class "' . $reference->id . '".', 0, $e); |
|
140 | } |
||
141 | 53 | if ($type === null || $component instanceof $type) { |
|
142 | 52 | return $component; |
|
143 | } |
||
144 | |||
145 | 1 | throw new InvalidConfigException('"' . $reference->id . '" refers to a ' . get_class($component) . " component. $type is expected."); |
|
146 | } |
||
147 | |||
148 | 1 | $valueType = is_object($reference) ? get_class($reference) : gettype($reference); |
|
149 | 1 | throw new InvalidConfigException("Invalid data type: $valueType. $type is expected."); |
|
150 | } |
||
151 | |||
152 | /** |
||
153 | * Returns the actual object referenced by this Instance object. |
||
154 | * @param ServiceLocator|Container $container the container used to locate the referenced object. |
||
155 | * If null, the method will first try `Yii::$app` then `Yii::$container`. |
||
156 | * @return object the actual object referenced by this Instance object. |
||
157 | */ |
||
158 | 57 | public function get($container = null) |
|
159 | { |
||
160 | 57 | if ($container) { |
|
161 | 6 | return $container->get($this->id); |
|
162 | } |
||
163 | 51 | if (Yii::$app && Yii::$app->has($this->id)) { |
|
164 | 47 | return Yii::$app->get($this->id); |
|
165 | } |
||
166 | |||
167 | 4 | return Yii::$container->get($this->id); |
|
168 | } |
||
169 | |||
170 | /** |
||
171 | * Restores class state after using `var_export()` |
||
172 | * |
||
173 | * @param array $state |
||
174 | * @return Instance |
||
175 | * @throws InvalidConfigException when $state property does not contain `id` parameter |
||
176 | * @see var_export() |
||
177 | * @since 2.0.12 |
||
178 | */ |
||
179 | 2 | public static function __set_state($state) |
|
187 | } |
||
188 |