結論: PHP中提供了反射類來解析類的結構; 通過反射類可以獲取到類的構造函數及其參數和依賴; 給構造函數的參數遞歸設置預設值後,即可使用這些帶預設值的參數通過 newInstanceArgs 實例化出類對象; 在實例化的過程中,依賴的類也會被實例化,從而實現了依賴註入。 PHP中反射類的常用方法: ...
結論:
- PHP中提供了反射類來解析類的結構;
- 通過反射類可以獲取到類的構造函數及其參數和依賴;
- 給構造函數的參數遞歸設置預設值後,即可使用這些帶預設值的參數通過
newInstanceArgs
實例化出類對象; - 在實例化的過程中,依賴的類也會被實例化,從而實現了依賴註入。
PHP中反射類的常用方法:
// 通過類名 Circle 實例化反射類
$reflectionClass = new reflectionClass(Circle::class);
// 獲取類常量
$reflectionClass->getConstants();
// 獲取類屬性
$reflectionClass->getProperties();
// 獲取類方法
$reflectionClass->getMethods();
// 獲取類的構造函數
$constructor = $reflectionClass->getConstructor();
// 獲取方法的參數
$parameters = $constructor->getParameters();
// 通過參數預設值數組實例化類創建對象
$class = $reflectionClass->newInstanceArgs($dependencies);
創建兩個具有依賴關係的類:
class Point
{
public $x;
public $y;
public function __construct($x = 0, $y = 0)
{
$this->x = $x;
$this->y = $y;
}
}
class Circle
{
// 圓的半徑
public $radius;
// 圓心位置
public $center;
const PI = 3.14;
public function __construct(Point $point, $radius = 1)
{
$this->center = $point;
$this->radius = $radius;
}
// 列印圓心位置的坐標
public function printCenter()
{
printf('圓心的位置是:(%d, %d)', $this->center->x, $this->center->y);
}
//計算圓形的面積
public function area()
{
return 3.14 * pow($this->radius, 2);
}
}
創建兩個方法:
make
方法負責解析類和構建類的對象;
getDependencies
負責依賴解析並初始化參數預設值;
//構建類的對象
function make($className)
{
try {
$reflectionClass = new ReflectionClass($className);
$constructor = $reflectionClass->getConstructor();
$parameters = $constructor->getParameters();
$dependencies = getDependencies($parameters);
// 用指定的參數創建一個新的類實例
return $reflectionClass->newInstanceArgs($dependencies);
} catch (ReflectionException $e) {
throw new Exception("{$className} not found.");
}
}
//依賴解析並初始化參數預設值
function getDependencies($parameters)
{
$dependencies = [];
// Circle 類的參數為 point 和 radius
// Point 類的參數為 x 和 y
foreach($parameters as $parameter) {
$dependency = $parameter->getClass();
// 如果參數不是類
if (is_null($dependency)) {
// 可選參數,有預設值
if($parameter->isDefaultValueAvailable()) {
$dependencies[] = $parameter->getDefaultValue();
}
// 必傳參數暫時先給一個預設值
else {
$dependencies[] = '0';
}
}
// 如果參數是類
else {
// 遞歸進行依賴解析
$dependencies[] = make($parameter->getClass()->name);
}
}
return $dependencies;
}
測試:
// 實例化對象
$circle = make('Circle');
// 調用對象的方法
$area = $circle->area();
var_dump($circle, $area);
過程說明:
make('Circle')
getDependencies(Point, int)
make('Point')
getDependencies(int, int)
new Point(int, int);
return Point;
new Circle(Point, int);
return Circle;