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
相关产品推荐
相关产品推荐

