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

PHP类中调用Trait内函数报错,求正确调用方法

问题分析与解决方案

你遇到的错误是因为Trait的使用方式、构造函数冲突以及命名空间引用错误导致的,以下是具体修正步骤:

1. 重构ValueValidationTrait

Trait中不能包含独立的构造函数(会与Validator类的构造函数冲突),改为声明需要的属性,由使用Trait的类注入依赖:

<?php

namespace App\Validation\Common;

use App\Entity\AbstractCustomField;
use SimitiveTranslationsBundle\Provider\TranslationsProvider;

trait ValueValidationTrait{
    // 声明依赖属性,由使用类注入值
    protected \Doctrine\ORM\EntityManagerInterface $entityManager;
    private \SimitiveTranslationsBundle\Provider\TranslationsProvider $translationsProvider;
    
    public function validateCustomFieldTypesWithValues(string $type, string $value): void
    {
        switch ($type) {
                case AbstractCustomField::TYPE_BOOLEAN:
                    if (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === null) {
                        $this->addViolation($this->translationsProvider->translate(
                            TranslationsProvider::DEFAULT_LANGUAGE,
                            'entity.user_custom_field_value.message.invalid_boolean_value'
                        ));
                        break;
                    }
                    break;
                case AbstractCustomField::TYPE_NUMERIC_INTEGER:
                    if (
                        filter_var($value, FILTER_VALIDATE_INT) !== 0 &&
                        !(filter_var($value, FILTER_VALIDATE_INT))
                    ) {
                        $this->addViolation(
                            $this->translationsProvider->translate(
                                TranslationsProvider::DEFAULT_LANGUAGE,
                                'entity.user_custom_field_value.message.invalid_numeric_value'
                            )
                        );
                        break;
                    }
                    break;
                default:
                    $this->addViolation(
                        $this->translationsProvider->translate(
                            TranslationsProvider::DEFAULT_LANGUAGE,
                            'entity.user_custom_field_value.message.invalid_custom_field_type'
                        )
                    );
                    break;
            }
    }
}

2. 修正Validator类的Trait使用方式

在类内部引入Trait,并通过自身构造函数注入依赖,传递给Trait使用:

<?php

namespace App\Validation\User;

use App\Entity\AbstractCustomField;
use App\Entity\CustomField\UserCustomFieldValue;
use App\Entity\CustomField\UserCustomFieldValueOption;
use App\Validation\Common\ValueValidationTrait;
use Doctrine\ORM\EntityManagerInterface;
use SimitiveTranslationsBundle\Provider\TranslationsProvider;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

/**
 * Validates user custom field values.
 */
class UserCustomFieldValueConstraintValidator extends ConstraintValidator
{
    // 在类内部引入Trait
    use ValueValidationTrait;

    public function __construct(
        EntityManagerInterface $entityManager,
        private TranslationsProvider $translationsProvider
    ) {
        // 将注入的依赖赋值给Trait声明的属性
        $this->entityManager = $entityManager;
        $this->translationsProvider = $translationsProvider;
    }

    public function validate($entity, Constraint $constraint): void
    {
        if (!$constraint instanceof UserCustomFieldValueConstraint) {
            throw new UnexpectedTypeException(
                $constraint,
                UserCustomFieldValueConstraint::class
            );
        }

        $userCustomFieldValues = $entity->getUserCustomFieldValues();

        if (!empty($userCustomFieldValues)) {
            foreach ($userCustomFieldValues as $userCustomFieldValue) {
                $type = $userCustomFieldValue->getUserCustomField()->getType();
                $value = $userCustomFieldValue->getValue();
                $userCustomFieldValueOption = $userCustomFieldValue->getUserCustomFieldValueOption();

                if (
                    in_array(
                        $type,
                        AbstractCustomField::getCustomFieldTypesWithValues()
                    ) &&
                    !empty($value)
                ) {
                    // 现在可以正常调用Trait中的方法
                    $this->validateCustomFieldTypesWithValues($type, $value);
                }

                if (
                    in_array($type, AbstractCustomField::getCustomFieldsTypesWithOptions()) &&
                    !empty($userCustomFieldValueOption)
                ) {
                    $this->validateUserCustomFieldTypesWithOptions(
                        $userCustomFieldValueOption,
                        $userCustomFieldValue
                    );
                }
            }
        }
    }
}

错误原因说明

  • Trait引入位置错误:你之前把Trait的use语句放在文件顶部的命名空间区域,正确做法是在类内部使用use引入Trait。
  • 构造函数冲突:Symfony的ConstraintValidator子类依赖自身构造函数注入服务,Trait中的构造函数会覆盖或冲突,需将依赖注入逻辑转移到Validator类中。
  • 命名空间缺失:引入Trait时未指定完整命名空间App\Validation\Common\ValueValidationTrait,导致PHP无法找到该Trait。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:45:41