×
¥
查看详情
🔥 会员专享 文生文 代码生成

PHP对象实例化代码生成器

👁️ 68 次查看
📅 Dec 10, 2025
💡 核心价值: 本提示词专为PHP开发者设计,能够根据指定的类名自动生成完整的对象实例化代码。它支持多种实例化场景,包括带参数构造、命名空间处理、异常捕获等常见开发需求。通过结构化的工作流程,确保生成的代码符合PHP最佳实践,具备良好的可读性和可维护性。适用于快速原型开发、教学演示和代码审查等多种PHP开发场景。

🎯 可自定义参数(4个)

类名称
需要实例化的PHP类名称
实例化场景
对象实例化的具体应用场景
构造函数参数
构造函数需要的参数列表
命名空间配置
类的命名空间配置

🎨 效果示例

标题:App\Service\Mailer 的安全实例化(带参数构造,含参数验证与异常处理)

说明:本示例在保持 PSR-12 与可维护性的前提下,提供一个 Mailer 实例化工厂。参数来源于环境变量(避免硬编码凭证),并包含严格的参数校验与异常处理。

完整的PHP实例化代码

<?php

declare(strict_types=1);

namespace App\Service;

use InvalidArgumentException;
use RuntimeException;
use Throwable;

/**
 * Mailer 实例化工厂。
 *
 * 约定构造函数签名:
 *  new Mailer(
 *      string $host = 'smtp.local',
 *      int $port = 587,
 *      bool $secure = true,
 *      string $username = 'noreply',
 *      string $password = 's3cr3t',
 *      array $options = ['timeout' => 5]
 *  )
 *
 * 注意:不要在代码中硬编码 password,示例通过环境变量注入。
 */
final class MailerFactory
{
    /**
     * 通过环境变量创建 Mailer 实例。
     *
     * 支持的环境变量:
     *  - SMTP_HOST (默认: smtp.local)
     *  - SMTP_PORT (默认: 587)
     *  - SMTP_SECURE (默认: true,接受 "1","0","true","false","yes","no")
     *  - SMTP_USERNAME (默认: noreply)
     *  - SMTP_PASSWORD (必填,无默认)
     *  - SMTP_TIMEOUT (默认: 5,单位秒)
     *
     * @throws RuntimeException|InvalidArgumentException 当配置不合法或实例化失败时抛出
     */
    public function __invoke(): Mailer
    {
        $host = $this->normalizeHost($this->env('SMTP_HOST') ?? 'smtp.local');
        $port = $this->normalizePort($this->env('SMTP_PORT'), 587);
        $secure = $this->normalizeBool($this->env('SMTP_SECURE'), true);

        $username = $this->normalizeUsername($this->env('SMTP_USERNAME') ?? 'noreply');

        $password = $this->env('SMTP_PASSWORD');
        if ($password === null || $password === '') {
            throw new RuntimeException('Environment variable SMTP_PASSWORD is required and must not be empty.');
        }

        $timeout = $this->normalizeTimeout($this->env('SMTP_TIMEOUT'), 5);
        $options = ['timeout' => $timeout];

        try {
            // 假设 App\Service\Mailer 已在同命名空间定义并通过 Composer 自动加载可用
            return new Mailer($host, $port, $secure, $username, $password, $options);
        } catch (Throwable $e) {
            // 包装底层异常,避免泄漏敏感信息
            throw new RuntimeException('Failed to instantiate Mailer with provided configuration.', 0, $e);
        }
    }

    /**
     * 获取环境变量:优先 $_ENV / $_SERVER,回退到 getenv()。
     */
    private function env(string $key): ?string
    {
        if (array_key_exists($key, $_ENV)) {
            return $_ENV[$key];
        }
        if (array_key_exists($key, $_SERVER)) {
            return $_SERVER[$key];
        }
        $value = getenv($key);
        return $value === false ? null : $value;
    }

    private function normalizeHost(string $host): string
    {
        $host = trim($host);
        if ($host === '') {
            throw new InvalidArgumentException('SMTP host must not be empty.');
        }
        return $host;
    }

    private function normalizePort(?string $raw, int $default): int
    {
        if ($raw === null || $raw === '') {
            return $default;
        }
        $port = filter_var($raw, FILTER_VALIDATE_INT, [
            'options' => ['min_range' => 1, 'max_range' => 65535],
        ]);
        if ($port === false) {
            throw new InvalidArgumentException('SMTP port must be a valid integer between 1 and 65535.');
        }
        return $port;
    }

    private function normalizeBool(?string $raw, bool $default): bool
    {
        if ($raw === null || $raw === '') {
            return $default;
        }
        $val = filter_var($raw, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        if ($val === null) {
            throw new InvalidArgumentException('SMTP secure must be a boolean (true/false, 1/0, yes/no).');
        }
        return $val;
    }

    private function normalizeUsername(string $username): string
    {
        $username = trim($username);
        if ($username === '') {
            throw new InvalidArgumentException('SMTP username must not be empty.');
        }
        return $username;
    }

    private function normalizeTimeout(?string $raw, int $default): int
    {
        if ($raw === null || $raw === '') {
            return $default;
        }
        $timeout = filter_var($raw, FILTER_VALIDATE_INT, [
            'options' => ['min_range' => 1, 'max_range' => 120],
        ]);
        if ($timeout === false) {
            throw new InvalidArgumentException('SMTP timeout must be an integer between 1 and 120 seconds.');
        }
        return $timeout;
    }
}

代码逻辑分步解析

  • 命名空间与标准
    • 使用 namespace App\Service; 保持与用户给定命名空间一致,遵循 PSR-4 自动加载约定。
    • 使用 declare(strict_types=1); 强制严格类型。
  • 环境变量注入
    • 禁止在代码中硬编码敏感凭证,password 必须通过环境变量 SMTP_PASSWORD 提供。
    • 其他参数提供安全的默认值:host=smtp.local, port=587, secure=true, username=noreply, timeout=5。
  • 参数规范化与校验
    • host:非空校验。
    • port:整数范围 1–65535。
    • secure:宽松布尔解析(true/false/1/0/yes/no)。
    • username:非空校验。
    • timeout:整数范围 1–120 秒。
  • 异常处理
    • 缺少必要凭证或参数非法时抛出 InvalidArgumentException/RuntimeException。
    • 对底层实例化异常进行包装,避免泄漏敏感配置细节。
  • 实例化
    • 按构造函数签名顺序传入参数:host, port, secure, username, password, options(包含 timeout)。

使用注意事项和最佳实践建议

  • 自动加载配置
    • composer.json 示例(确保 Mailer 与 MailerFactory 位于 src/ 目录):
      • "autoload": { "psr-4": { "App\": "src/" } }
      • 执行 composer dump-autoload 生效。
  • 环境变量管理
    • 在生产环境使用进程级环境变量或容器密钥管理服务(如 Kubernetes Secret、AWS Secrets Manager)。
    • 开发环境可使用 vlucas/phpdotenv 管理 .env(勿将 .env 提交到版本库)。
  • 日志与观测
    • 在捕获异常后,使用 PSR-3 Logger 安全记录(不包含密码或完整连接串)。示例中仅抛出异常,实际项目建议记录上下文但排除敏感信息。
  • 与 DI 容器集成
    • 在 Symfony/Laravel 等框架中,将 MailerFactory 注册为服务,由容器注入配置。避免在业务代码中直接读取环境变量。
  • 安全
    • 不要将 SMTP_PASSWORD 写入源码或提交到仓库。
    • 若需本地调试,使用专用低权限账户与最小化权限策略。

常见问题解决方案

  • 问:为什么不直接使用构造函数默认的 's3cr3t' 密码?
    • 答:这属于硬编码凭证,违反安全最佳实践与本规则。必须通过环境变量或安全配置源注入。
  • 问:在某些环境 getenv() 返回空,怎么办?
    • 答:示例依次检查 $_ENV、$_SERVER 和 getenv()。若仍为空,请确认 PHP-FPM/Apache 配置传递环境变量,或改用配置文件/容器密钥管理。
  • 问:SMTP_SECURE 传入 "on"/"off" 失败?
    • 答:使用 true/false、1/0、yes/no。其他值会触发 InvalidArgumentException。
  • 问:如何使用?
    • 答:
      • $factory = new \App\Service\MailerFactory();
      • try { $mailer = $factory(); } catch (\Throwable $e) { /* 记录日志并处理 */ }
  • 问:端口或超时配置错了导致实例化异常?
    • 答:工厂在实例化前会校验范围并抛出清晰异常,修正环境变量后重试。

如需我基于具体框架(如 Symfony/Laravel)给出容器配置与依赖注入示例,请告知使用的框架与版本。

标题:基于依赖注入的 OrderController 实例化(PSR 规范、异常处理与可维护性)

说明:以下代码展示了使用依赖注入创建 App\Http\Controller\OrderController 的标准做法。包含控制器定义、PSR-11 工厂类(推荐)、以及手动实例化示例。代码遵循 PSR-12、使用严格类型、并包含必要的异常处理与注释说明。

完整的PHP实例化代码

<?php
declare(strict_types=1);

namespace App\Http\Controller;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
use App\Service\OrderService;

/**
 * OrderController
 *
 * 通过依赖注入获取 LoggerInterface、OrderService 与 ResponseFactoryInterface。
 * 示例包含一个简单的动作方法,展示服务调用与响应构建,包含必要的异常处理与日志记录。
 */
final class OrderController
{
    public function __construct(
        private readonly LoggerInterface $logger,
        private readonly OrderService $service,
        private readonly ResponseFactoryInterface $responseFactory
    ) {
    }

    /**
     * 示例动作:创建订单
     * - 从请求中读取数据
     * - 调用应用服务创建订单
     * - 返回 JSON 响应
     */
    public function create(ServerRequestInterface $request): ResponseInterface
    {
        $response = $this->responseFactory->createResponse();

        try {
            $payload = $request->getParsedBody() ?? [];

            // 建议在 OrderService 内部完成更严格的输入校验、事务与领域规则校验
            $orderId = $this->service->createOrder($payload);

            $response->getBody()->write(\json_encode(['id' => $orderId], JSON_THROW_ON_ERROR));

            return $response
                ->withStatus(201)
                ->withHeader('Content-Type', 'application/json');
        } catch (\DomainException $e) {
            // 领域异常:可能是业务校验失败
            $this->logger->warning('Order creation failed due to domain rule', [
                'message' => $e->getMessage(),
            ]);

            $response->getBody()->write(\json_encode(['error' => 'Invalid order data'], JSON_THROW_ON_ERROR));
            return $response
                ->withStatus(400)
                ->withHeader('Content-Type', 'application/json');
        } catch (\Throwable $e) {
            // 未预期错误:记录错误并返回 500
            $this->logger->error('Unexpected error during order creation', [
                'exception' => $e,
            ]);

            $response->getBody()->write(\json_encode(['error' => 'Server error'], JSON_THROW_ON_ERROR));
            return $response
                ->withStatus(500)
                ->withHeader('Content-Type', 'application/json');
        }
    }
}
<?php
declare(strict_types=1);

namespace App\Http\Controller\Factory;

use App\Http\Controller\OrderController;
use App\Service\OrderService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Log\LoggerInterface;

/**
 * OrderControllerFactory
 *
 * PSR-11 工厂,负责从容器解析依赖并实例化控制器。
 * 在 Laminas/Mezzio/Slim/Symfony(自定义) 等框架中均可采用类似模式。
 */
final class OrderControllerFactory
{
    /**
     * @throws \RuntimeException 当依赖解析失败时抛出运行时异常
     */
    public function __invoke(ContainerInterface $container): OrderController
    {
        try {
            $logger = $container->get(LoggerInterface::class);
            $service = $container->get(OrderService::class);
            $responseFactory = $container->get(ResponseFactoryInterface::class);
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
            // 将容器错误封装为通用运行时异常,避免将容器细节泄漏到上层
            throw new \RuntimeException('Failed to resolve dependencies for OrderController.', 0, $e);
        }

        return new OrderController($logger, $service, $responseFactory);
    }
}
<?php
declare(strict_types=1);

// 手动实例化示例(在无容器或测试环境中)
use App\Http\Controller\OrderController;
use App\Service\OrderService;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Log\LoggerInterface;

// 在真实项目中,请从应用上下文获取以下依赖对象:
/** @var LoggerInterface $logger */
$logger = /* your LoggerInterface instance */;

/** @var OrderService $service */
$service = /* your OrderService instance */;

/** @var ResponseFactoryInterface $responseFactory */
$responseFactory = /* your ResponseFactoryInterface instance */;

// 实例化控制器
$orderController = new OrderController($logger, $service, $responseFactory);

代码逻辑分步解析

  • 命名空间与导入

    • 使用命名空间:namespace App\Http\Controller; 符合 PSR-4 自动加载约定。
    • 引入 PSR-3 日志接口、PSR-7 请求响应接口以及业务服务类。
  • 控制器构造函数

    • 通过构造函数注入 LoggerInterface、OrderService、ResponseFactoryInterface,属性标记为 readonly,保证依赖不可变,提升可维护性与可测试性。
  • 动作方法示例 create()

    • 从 ServerRequestInterface 获取解析后的请求体。
    • 调用 OrderService 执行业务逻辑。
    • 使用 ResponseFactoryInterface 创建响应并返回 JSON,开启 JSON_THROW_ON_ERROR 以避免静默失败。
    • 捕获 DomainException 返回 400,并记录 warning 日志;捕获其他 Throwable 返回 500,并记录 error 日志。
  • 工厂类 OrderControllerFactory

    • 通过容器解析依赖,分别请求 LoggerInterface、OrderService、ResponseFactoryInterface。
    • 捕获 NotFoundExceptionInterface 与 ContainerExceptionInterface,将其封装为 RuntimeException 抛出,避免上层依赖容器实现细节。
    • 返回组装好的 OrderController 实例。

使用注意事项与最佳实践

  • 优先使用 DI 容器

    • 使用 PSR-11 容器统一管理依赖。控制器只声明依赖,不负责创建依赖,保持单一职责。
  • 类型声明与严格类型

    • declare(strict_types=1) 与完整的参数/返回类型声明有助于在开发期捕获错误。
  • 不要在控制器中做复杂业务

    • 将业务规则封装在 OrderService 内部,控制器负责协调、调用和拼接 HTTP 响应。
  • 异常与日志

    • 区分可预期的业务异常(如 DomainException)与系统异常(Throwable)。前者输出 4xx,后者输出 5xx,并记录足够的日志上下文信息。
  • 内容协商与响应

    • 明确设置 Content-Type: application/json;如需多种响应格式,可在响应工厂或中间件中实现内容协商。
  • 自动加载配置

    • 确保 composer.json 存在类似配置:
      • "autoload": { "psr-4": { "App\": "src/" } }
      • 对应文件路径应为 src/Http/Controller/OrderController.php 与 src/Http/Controller/Factory/OrderControllerFactory.php

常见问题与解决方案

  • 问题:容器找不到依赖(NotFoundExceptionInterface)

    • 解决:检查容器配置是否为 LoggerInterface、OrderService、ResponseFactoryInterface 注册了正确的实例或工厂。
  • 问题:命名空间/自动加载错误导致类找不到

    • 解决:确认文件路径与命名空间符合 PSR-4 规则,执行 composer dump-autoload 刷新自动加载。
  • 问题:JSON 编码失败或中文乱码

    • 解决:使用 JSON_THROW_ON_ERROR 并捕获异常;需要中文不转义可加 JSON_UNESCAPED_UNICODE;同时确保响应头为 application/json。
  • 问题:测试环境如何实例化

    • 解决:在单元测试中可手动创建 LoggerInterface、ResponseFactoryInterface 的替身(如使用 PHPUnit mocks)并直接 new OrderController()。
  • 问题:响应体已写入后再次写入

    • 解决:谨慎在中间件/控制器中多处写入 body;如需流式输出,确保响应流状态可写且逻辑单一。

以上代码与说明可直接复制到项目中使用或做为基线模板进行扩展。

工厂模式下实例化 ProductRepository(含健壮的参数校验与异常处理)

下面的示例展示如何在工厂模式下实例化 Domain\Repository\ProductRepository。代码遵循 PSR-12、严格类型、合理的异常封装与参数校验,避免硬编码敏感凭证,推荐从环境变量加载配置。

完整PHP代码

<?php

declare(strict_types=1);

namespace Domain\Repository\Exception;

use RuntimeException;

/**
 * 封装仓储创建相关的异常,避免向上层泄露底层驱动细节和敏感信息
 */
final class RepositoryCreationException extends RuntimeException
{
}

namespace Domain\Repository;

use Domain\Repository\Exception\RepositoryCreationException;
use PDO;
use PDOException;

/**
 * 产品仓储(示例)
 * - 使用 PDO 连接数据库
 * - 内置参数校验、DSN 构建与异常封装
 */
final class ProductRepository
{
    private PDO $pdo;

    /**
     * @param string $driver  例如:mysql、pgsql、sqlite(默认 mysql)
     * @param array<string, mixed> $config  连接配置:
     *  - mysql/pgsql: host, dbname, user, password[, port, charset]
     *  - sqlite: path
     *
     * 注意:不得在代码中硬编码敏感凭证(如 password)。请优先从环境变量或安全配置源加载。
     *
     * @throws RepositoryCreationException
     */
    public function __construct(string $driver = 'mysql', array $config = [])
    {
        $this->pdo = $this->connect($driver, $config);
    }

    /**
     * 示例:按主键查询产品
     *
     * @return array<string, mixed>|null
     */
    public function findById(int $id): ?array
    {
        $stmt = $this->pdo->prepare('SELECT id, name, price FROM products WHERE id = :id');
        $stmt->bindValue(':id', $id, PDO::PARAM_INT);
        $stmt->execute();

        $row = $stmt->fetch();
        return $row !== false ? $row : null;
    }

    /**
     * 建立 PDO 连接并返回实例
     *
     * @throws RepositoryCreationException
     */
    private function connect(string $driver, array $config): PDO
    {
        $driver = strtolower($driver);
        $allowedDrivers = ['mysql', 'pgsql', 'sqlite'];

        if (!in_array($driver, $allowedDrivers, true)) {
            throw new RepositoryCreationException(
                "Unsupported driver '{$driver}'. Allowed: " . implode(', ', $allowedDrivers)
            );
        }

        $config = $this->normalizeConfig($driver, $config);
        [$dsn, $user, $password] = $this->buildDsn($driver, $config);

        $options = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ];

        try {
            // 对于 sqlite,$user/$password 可为 null
            return new PDO($dsn, $user, $password, $options);
        } catch (PDOException $e) {
            // 打包安全的配置,避免泄露密码
            $safeConfig = $config;
            if (isset($safeConfig['password'])) {
                $safeConfig['password'] = '***redacted***';
            }

            $message = 'Failed to create PDO connection: ' . $e->getMessage()
                . ' | config=' . json_encode($safeConfig, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

            throw new RepositoryCreationException($message, (int) $e->getCode(), $e);
        }
    }

    /**
     * 规范化与校验配置,优先从环境变量读取缺失项
     *
     * @param array<string, mixed> $config
     * @return array<string, mixed>
     *
     * @throws RepositoryCreationException
     */
    private function normalizeConfig(string $driver, array $config): array
    {
        if ($driver === 'sqlite') {
            $config['path'] = $config['path'] ?? ($_ENV['DB_PATH'] ?? getenv('DB_PATH') ?: '');
            if ($config['path'] === '') {
                throw new RepositoryCreationException('SQLite requires a non-empty "path" in config or DB_PATH env.');
            }
            return $config;
        }

        // 非 sqlite:从环境变量补全
        $config['host']     = $config['host']     ?? ($_ENV['DB_HOST'] ?? getenv('DB_HOST') ?? '127.0.0.1');
        $config['dbname']   = $config['dbname']   ?? ($_ENV['DB_NAME'] ?? getenv('DB_NAME') ?? null);
        $config['user']     = $config['user']     ?? ($_ENV['DB_USER'] ?? getenv('DB_USER') ?? null);
        $config['password'] = $config['password'] ?? ($_ENV['DB_PASSWORD'] ?? getenv('DB_PASSWORD') ?? '');

        // 必填校验(避免空值导致隐式连接到错误库)
        foreach (['host', 'dbname', 'user'] as $key) {
            if (empty($config[$key]) || !is_string($config[$key])) {
                throw new RepositoryCreationException("Invalid or missing '{$key}' in config.");
            }
        }
        if (!is_string($config['password'])) {
            throw new RepositoryCreationException('Invalid "password" type in config.');
        }

        // 基础字符校验,防止将恶意字符注入 DSN(密码不做字符限制)
        $safePattern = '/^[A-Za-z0-9_\-\.]+$/';
        if (!preg_match($safePattern, $config['host'])) {
            throw new RepositoryCreationException('Host contains invalid characters.');
        }
        if (!preg_match($safePattern, $config['dbname'])) {
            throw new RepositoryCreationException('Database name contains invalid characters.');
        }
        if (!preg_match('/^[\w\-.]+$/', $config['user'])) {
            throw new RepositoryCreationException('User contains invalid characters.');
        }

        // 可选项:port, charset
        $config['port']    = isset($config['port']) && is_int($config['port']) ? $config['port'] : null;
        $config['charset'] = $config['charset'] ?? 'utf8mb4';

        return $config;
    }

    /**
     * 构建 DSN 及认证信息
     *
     * @param array<string, mixed> $config
     * @return array{0:string,1:?string,2:?string} [dsn, user, password]
     */
    private function buildDsn(string $driver, array $config): array
    {
        if ($driver === 'mysql') {
            $dsn = sprintf(
                'mysql:host=%s;%sdbname=%s;charset=%s',
                $config['host'],
                isset($config['port']) ? 'port=' . (int) $config['port'] . ';' : '',
                $config['dbname'],
                $config['charset']
            );
            return [$dsn, $config['user'], $config['password']];
        }

        if ($driver === 'pgsql') {
            $dsn = sprintf(
                'pgsql:host=%s;%sdbname=%s',
                $config['host'],
                isset($config['port']) ? 'port=' . (int) $config['port'] . ';' : '',
                $config['dbname']
            );
            return [$dsn, $config['user'], $config['password']];
        }

        // sqlite
        $dsn = 'sqlite:' . $config['path'];
        return [$dsn, null, null];
    }
}

namespace Domain\Factory;

use Domain\Repository\ProductRepository;

/**
 * 仓储工厂:集中管理仓储实例的创建逻辑
 */
final class RepositoryFactory
{
    /**
     * @param string $driver
     * @param array<string, mixed> $config
     */
    public static function createProductRepository(string $driver = 'mysql', array $config = []): ProductRepository
    {
        // 如需扩展:可在此添加缓存、日志、代理包装等
        return new ProductRepository($driver, $config);
    }
}

// ========================= 使用示例(Client Code) =========================
// 说明:以下为用法示例,建议放在应用启动处(例如 bootstrap 或容器配置)。
// 实际项目中请使用 Composer PSR-4 自动加载,并通过 dotenv 或安全配置中心加载环境变量。

namespace App;

use Domain\Factory\RepositoryFactory;
use Domain\Repository\Exception\RepositoryCreationException;

$config = [
    // 不要硬编码敏感信息;这里仅示例从环境加载,缺失项将由构造器进行校验并抛出异常
    'host'     => $_ENV['DB_HOST'] ?? getenv('DB_HOST') ?? '127.0.0.1',
    'dbname'   => $_ENV['DB_NAME'] ?? getenv('DB_NAME') ?? '',
    'user'     => $_ENV['DB_USER'] ?? getenv('DB_USER') ?? '',
    'password' => $_ENV['DB_PASSWORD'] ?? getenv('DB_PASSWORD') ?? '',
    // 'port'   => 3306,
    // 'charset'=> 'utf8mb4',
];

try {
    $productRepository = RepositoryFactory::createProductRepository('mysql', $config);
    // $product = $productRepository->findById(1);
} catch (RepositoryCreationException $e) {
    // 记录日志并按需处理;避免向前端暴露内部错误细节
    error_log($e->getMessage());
    // 可在此回退或中止启动
}

代码逻辑分步解析

  1. 命名空间与自动加载

    • ProductRepository 位于 Domain\Repository 命名空间,工厂 RepositoryFactory 位于 Domain\Factory。
    • 异常 RepositoryCreationException 统一封装在 Domain\Repository\Exception。
    • 符合 PSR-4,可通过 Composer 配置自动加载。
  2. 工厂模式实例化

    • 使用 RepositoryFactory::createProductRepository($driver, $config) 生成 ProductRepository 实例。
    • 工厂集中管理实例创建,便于后续添加代理、缓存、拦截器或容器集成。
  3. 构造函数与依赖处理

    • ProductRepository 构造函数接收 driver 与 config,内部统一完成:
      • 配置规范化与校验(必填项、字符合法性、环境变量补全)。
      • 构建 DSN(支持 mysql、pgsql、sqlite)。
      • 创建 PDO 对象,设置安全属性(异常模式、关联数组、禁用模拟预处理)。
  4. 安全与异常处理

    • RepositoryCreationException 保证异常向上抛出时不泄露密码。
    • DSN 构建前对 host、dbname、user 做基本字符校验,降低注入风 险。
    • 使用 PDO::ATTR_EMULATE_PREPARES = false,启用原生预处理,减少 SQL 注入风险。
  5. 示例方法

    • findById 使用预处理语句,类型安全绑定参数,示范仓储查询的基本写法。

使用注意事项与最佳实践

  • 配置来源

    • 切勿硬编码敏感凭证(如密码);通过环境变量、密钥管理服务(如 Vault)、CI/CD 注入或配置中心获取。
    • 推荐使用 vlucas/phpdotenv 在开发环境管理 .env 文件(生产环境仍使用安全配置源)。
  • PDO 驱动

    • 请确保启用了相应的 PDO 驱动扩展(pdo_mysql/pdo_pgsql/pdo_sqlite)。
    • 远程连接生产数据库时建议启用 TLS,并配置相应的 PDO SSL 选项(如 MySQL 的 PDO::MYSQL_ATTR_SSL_CA 等)。
  • 连接配置

    • MySQL 建议 charset 使用 utf8mb4。
    • 若有端口,显式传入 port(int)。
    • SQLite 必须提供 path。
  • 错误处理

    • 捕获 RepositoryCreationException 并记录日志,不要向前端泄露内部错误和配置细节。
    • 对于频繁的实例化,建议将实例交由依赖注入容器管理,避免重复建立连接。
  • 代码质量

    • 保持 PSR-12 规范与严格类型 declare(strict_types=1)。
    • 将不同类放置到独立文件中,便于维护与自动加载。

常见问题解决方案

  • 问:抛出 “Unsupported driver …”?

    • 解:仅支持 mysql、pgsql、sqlite。检查输入 driver 或扩展 buildDsn/normalizeConfig 以支持新驱动。
  • 问:提示缺失 dbname/user?

    • 解:确保从环境变量或配置中心正确注入 DB_NAME、DB_USER;或在传入的 $config 中显式提供。
  • 问:PDOException: could not find driver

    • 解:安装并启用对应的 PDO 扩展,例如:
      • Debian/Ubuntu: sudo apt-get install php-pdo_mysql
      • CentOS/RHEL: sudo yum install php-mysqlnd
      • 并在 php.ini 中确认 extension 已启用,重启 PHP-FPM/Apache。
  • 问:字符集乱码或表情符号无法存储

    • 解:MySQL 使用 utf8mb4 并设置合适的排序规则(如 utf8mb4_unicode_ci),同时数据库/表/连接保持一致。
  • 问:生产环境连接安全

    • 解:优先启用 TLS/SSL;不要在日志中打印完整连接串与密码;确保最小权限账户;限制来源 IP。
  • 问:如何与 DI 容器集成

    • 解:在容器中注册 RepositoryFactory 或直接将 ProductRepository 注册为服务,统一由容器读取配置并实例化,避免到处 new。

以上方案严格遵守安全与可维护性要求,并采用工厂模式实现 ProductRepository 的标准化实例化流程。

示例详情

📖 如何使用

30秒出活:复制 → 粘贴 → 搞定
与其花几十分钟和AI聊天、试错,不如直接复制这些经过千人验证的模板,修改几个 {{变量}} 就能立刻获得专业级输出。省下来的时间,足够你轻松享受两杯咖啡!
加载中...
💬 不会填参数?让 AI 反过来问你
不确定变量该填什么?一键转为对话模式,AI 会像资深顾问一样逐步引导你,问几个问题就能自动生成完美匹配你需求的定制结果。零门槛,开口就行。
转为对话模式
🚀 告别复制粘贴,Chat 里直接调用
无需切换,输入 / 唤醒 8000+ 专家级提示词。 插件将全站提示词库深度集成于 Chat 输入框。基于当前对话语境,系统智能推荐最契合的 Prompt 并自动完成参数化,让海量资源触手可及,从此彻底告别"手动搬运"。
即将推出
🔌 接口一调,提示词自己会进化
手动跑一次还行,跑一百次呢?通过 API 接口动态注入变量,接入批量评价引擎,让程序自动迭代出更高质量的提示词方案。Prompt 会自己进化,你只管收结果。
发布 API
🤖 一键变成你的专属 Agent 应用
不想每次都配参数?把这条提示词直接发布成独立 Agent,内嵌图片生成、参数优化等工具,分享链接就能用。给团队或客户一个"开箱即用"的完整方案。
创建 Agent

✅ 特性总结

一键生成PHP对象实例化代码,自动匹配构造参数与依赖,减少手写错误。
智能识别命名空间与文件组织,输出可直接落地的示例与引用写法。
自动补齐异常捕获与参数校验与边界处理,为上线环境预防常见崩溃场景。
内置多种场景模板,覆盖模型创建、服务初始化、组件接入等常见需求。
生成同时附带注释与使用说明,新人也能看懂、复用并快速上手,立即实践。
提供逐步解析与注意事项,帮助团队统一风格,减少代码审查反复沟通。
支持个性化参数与可选项,一次配置多场景复用,显著提升交付效率。
自动给出优化建议与易错提醒,让代码更易读、更易测、更易维护。
输出结构清晰便于沉淀文档与知识传承,缩短协作沟通与交接成本。
适配常见版本与主流框架习惯,减少环境切换带来的迁移与兼容成本。

🎯 解决的问题

打造一款面向PHP开发者的“一键对象实例化”智能提示词:用一次输入,自动产出可直接复制的高质量代码与讲解;覆盖带参构造、命名空间、错误处理等复杂情形;在原型开发、课堂演示、代码评审中显著提效;通过统一写法与清晰注释降低维护风险与新人上手成本,帮助个人与团队以更低试错成本快速验证价值并顺利完成付费落地。

🕒 版本历史

当前版本
v2.1 2024-01-15
优化输出结构,增强情节连贯性
  • ✨ 新增章节节奏控制参数
  • 🔧 优化人物关系描述逻辑
  • 📝 改进主题深化引导语
  • 🎯 增强情节转折点设计
v2.0 2023-12-20
重构提示词架构,提升生成质量
  • 🚀 全新的提示词结构设计
  • 📊 增加输出格式化选项
  • 💡 优化角色塑造引导
v1.5 2023-11-10
修复已知问题,提升稳定性
  • 🐛 修复长文本处理bug
  • ⚡ 提升响应速度
v1.0 2023-10-01
首次发布
  • 🎉 初始版本上线
COMING SOON
版本历史追踪,即将启航
记录每一次提示词的进化与升级,敬请期待。

💬 用户评价

4.8
⭐⭐⭐⭐⭐
基于 28 条评价
5星
85%
4星
12%
3星
3%
👤
电商运营 - 张先生
⭐⭐⭐⭐⭐ 2025-01-15
双十一用这个提示词生成了20多张海报,效果非常好!点击率提升了35%,节省了大量设计时间。参数调整很灵活,能快速适配不同节日。
效果好 节省时间
👤
品牌设计师 - 李女士
⭐⭐⭐⭐⭐ 2025-01-10
作为设计师,这个提示词帮我快速生成创意方向,大大提升了工作效率。生成的海报氛围感很强,稍作调整就能直接使用。
创意好 专业
COMING SOON
用户评价与反馈系统,即将上线
倾听真实反馈,在这里留下您的使用心得,敬请期待。
加载中...
📋
提示词复制
在当前页面填写参数后直接复制: