You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PSR-4与Composer的抽象继承类文件组织方案问询

符合PSR-4规范的Composer包目录与命名空间设计(结合组合模式)

我来帮你梳理下正确的结构,你的初步思路方向是对的,但有几个不符合PSR-4和最佳实践的地方需要调整——比如不要把多个类塞进同一个文件里,还有命名空间和目录的对应要更严谨。咱们一步步来:

核心原则先明确

首先,PSR-4的核心要求是命名空间与目录结构完全一一对应,且每个类必须单独放在一个与类名完全同名的文件中(大驼峰命名)。另外,抽象类和具体实现类要按职责和分类清晰划分,方便维护和依赖注入。

最终目录结构示例

/var/www/vendor/my-vendor-name/car-package/
├── src/
│   ├── Controllers/
│   │   ├── CarController.php       # 抽象类:所有汽车控制器的父类
│   │   └── MotorController.php     # 抽象类:所有发动机控制器的父类(如果需要)
│   ├── Models/
│   │   ├── CarModel.php            # 抽象类:所有汽车模型的父类
│   │   └── MotorModel.php          # 抽象类:所有发动机模型的父类(如果需要)
│   ├── Entities/
│   │   ├── CarEntity.php           # 抽象类:所有汽车实体的父类
│   │   └── MotorEntity.php         # 抽象类:所有发动机实体的父类(如果需要)
│   ├── Cars/
│   │   ├── SportsCar/
│   │   │   ├── Controllers/
│   │   │   │   └── SportsCarController.php  # 具体类:继承CarController
│   │   │   ├── Models/
│   │   │   │   └── SportsCarModel.php       # 具体类:继承CarModel
│   │   │   └── Entities/
│   │   │       └── SportsCarEntity.php      # 具体类:继承CarEntity
│   │   └── SedanCar/
│   │       ├── Controllers/
│   │       │   └── SedanCarController.php
│   │       ├── Models/
│   │       │   └── SedanCarModel.php
│   │       └── Entities/
│   │           └── SedanCarEntity.php
│   └── Motors/
│       ├── V6Motor/
│       │   ├── Controllers/
│       │   │   └── V6MotorController.php    # 具体类:继承MotorController
│       │   ├── Models/
│       │   │   └── V6MotorModel.php         # 具体类:继承MotorModel
│       │   └── Entities/
│       │       └── V6MotorEntity.php        # 具体类:继承MotorEntity
│       └── V8Motor/
│           ├── Controllers/
│           │   └── V8MotorController.php
│           ├── Models/
│           │   └── V8MotorModel.php
│           └── Entities/
│               └── V8MotorEntity.php
└── composer.json

命名空间对应规则

每个文件的命名空间严格匹配目录层级,举几个关键例子:

  • src/Controllers/CarController.php → 命名空间:MyVendorName\Car\Controllers
  • src/Cars/SportsCar/Controllers/SportsCarController.php → 命名空间:MyVendorName\Car\Cars\SportsCar\Controllers
  • src/Motors/V6Motor/Models/V6MotorModel.php → 命名空间:MyVendorName\Car\Motors\V6Motor\Models

继承关系示例

以SportsCarController继承抽象类CarController为例,代码如下:

<?php

namespace MyVendorName\Car\Cars\SportsCar\Controllers;

use MyVendorName\Car\Controllers\CarController;

class SportsCarController extends CarController
{
    // 实现抽象方法或添加自定义业务逻辑
    public function accelerate()
    {
        return "Sports car accelerating rapidly!";
    }
}

组合模式依赖注入实现

结合你的需求,比如SportsCarModel需要依赖V6MotorModel,可以通过构造函数注入实现组合:

<?php

namespace MyVendorName\Car\Cars\SportsCar\Models;

use MyVendorName\Car\Models\CarModel;
use MyVendorName\Car\Motors\V6Motor\Models\V6MotorModel;

class SportsCarModel extends CarModel
{
    protected $motorModel;

    // 构造函数注入发动机模型,符合依赖注入原则
    public function __construct(V6MotorModel $motorModel)
    {
        $this->motorModel = $motorModel;
    }

    // 组合调用发动机的能力
    public function getMaxSpeed()
    {
        $horsepower = $this->motorModel->getHorsepower();
        return $horsepower * 1.3; // 跑车的速度系数
    }
}

Composer配置(composer.json)

最后要在composer.json里配置PSR-4自动加载规则,确保类能被正确加载:

{
    "name": "my-vendor-name/car-package",
    "description": "Custom car package with composition pattern, following PSR-4 standards",
    "type": "library",
    "autoload": {
        "psr-4": {
            "MyVendorName\\Car\\": "src/"
        }
    },
    "require": {
        "php": "^7.4 || ^8.0"
    }
}

关键注意点

  1. 绝对不要把多个类放在同一个文件里(比如你之前的AllMyAbstractControllers.php),每个类单独一个文件是PSR-4的基本要求,也方便维护。
  2. 抽象类放在顶层的职责目录(Controllers/、Models/等),具体实现类按业务分类(Cars/SportsCar/、Motors/V6Motor/)嵌套,结构清晰。
  3. 组合模式通过构造函数注入依赖,避免硬编码实例化,符合SOLID原则。

内容的提问来源于stack exchange,提问作者user1032531

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:53:47