0

복잡한 중첩 된 (주문) Zend\Form을 여러 번 편집 할 수 있습니다. 사용자는 먼저 주문을 작성하지만 즉시 주문할 필요는 없습니다. 그는 단지 주문 (또는 더 정확하게는 데이터)을 저장하고 나중에 편집 할 수 있습니다. 이 경우 응용 프로그램은 Order 객체 (중첩 된 구조체 모두)와 bind 객체를 양식에로드합니다. 중요한 단계는 다음과 같습니다젠드 프레임 워크 2/3에서 유효성 검사를하기 전에 Zend Form에서 getData()하는 방법?

  1. ID
  2. $orderForm->bind($orderObject) 하여 Order 개체를 얻을 요청
  3. 에서 순서의 ID를 얻을 ...

가 지금은 데이터를 잡으려면 및 JSON으로 직렬화하십시오. (배경 : 양식 복제 - 다음 단계에서 비어있는 새 양식을 작성해야하며이를 전달해야하며 저장하면 클론을 얻습니다.) 23 사이에 발생해야합니다. 그래서

$formData = $this->orderForm->getData(); 
$formJson = json_encode($formData, JSON_UNESCAPED_SLASHES); 

을 시도하고 오류 받고 있어요 :

Zend\Form\Form::getData cannot return data as validation has not yet occurred

글쎄, 나는 그것과 validate 형태로 해결을 시도 할 수 있습니다 :

$formIsValid = $this->orderForm->isValid(); 

하지만 그것은 단지로 연결 추가 문제 :

Zend\InputFilter\BaseInputFilter::setData expects an array or Traversable argument; received NULL

유효성 검사 전에 양식 데이터를 가져 오는 방법이 있습니까?

+0

마지막 오류 메시지는 setData 메소드로 설정하려는 데이터가 null임을 나타냅니다. 유효성을 검사하기 전에 양식에 데이터를 입력해야합니다. 너의 길을 리팩터링하자. 첫 번째 : 주문 ID를 가져옵니다. 두 번째 : ID로 주문 오브젝트를 가져옵니다. 셋째 : 수화기로 주문 오브젝트의 데이터를 추출하십시오. 넷째, 양식의 setData 메소드를 통해 추출 된 데이터 (배열)를 양식에 제공하십시오. 다섯 번째 : 그것을 확인하십시오. 여섯째 : getData 메소드를 통해 양식의 필터링 된 유효성 검사 데이터를 가져옵니다. 주문 개체를 양식에 직접 바인딩 할 수 없습니다. – Marcel

답변

0

좋습니다. 댓글 공간이 너무 작아서 보관하려는 내용에 대한 모든 것을 말할 수 없습니다. 시작 게시물에서 언급 한 모든 단계를 리팩토링합시다. 이것은 우리를 당신의 목표로 이끌 것입니다. 그것은 수분 공급에 관한 것입니다.

이 예제는 제품이 포함 된 주문 엔터티가 어떻게 보이는지를 보여주는 작은 예입니다. 순서 엔티티가 제품 엔티티를 추적 한 후에이 예제에 필요한 엔티티.

namespace Application\Entity; 

class Order implements \JsonSerializable 
{ 
    /** 
    * ID of the order 
    * @var integer 
    */ 
    protected $orderID; 

    /** 
    * Array of \Application\Entity\Product   
    * @var array 
    */ 
    protected $products; 

    public function getOrderID() : integer 
    { 
     return $this->orderID; 
    } 

    public function setOrderID(integer $orderID) : Order 
    { 
     $this->orderID = $orderID; 
     return $this; 
    } 

    public function getProducts() 
    { 
     if ($this->products == null) { 
      $this->products = []; 
     } 

     return $this->products; 
    } 

    public function setProducts(array $products) : Order 
    { 
     $this->products = $products; 
     return $this; 
    } 

    /** 
    * @see \JsonSerializable::jsonSerialize() 
    */ 
    public function jsonSerialize() 
    { 
     return get_object_vars($this); 
    } 
} 

다음 엔터티는 제품을 나타냅니다.

class Product implements \JsonSerializable 
{ 
    protected $productID; 

    protected $name; 

    public function getProductID() : integer 
    { 
     return $this->productID; 
    } 

    public function setProductID(integer $productID) : Product 
    { 
     $this->productID = $productID; 
     return $this; 
    } 

    public function getName() : string 
    { 
     return $this->name; 
    } 

    public function setName(string $name) : Product 
    { 
     $this->name = $name; 
     return $this; 
    } 

    /** 
    * @see \JsonSerializable::jsonSerialize() 
    */ 
    public function jsonSerialize() 
    { 
     return get_object_vars($this); 
    } 
} 

위 항목에는 몇 가지 가능한 제품이 포함 된 단일 주문을 나타내는 당사 항목이 있습니다. 두 번째 멤버 제품은 Product 엔터티가있는 배열 일 수 있습니다. 이 엔티티는 간단한 순서의 데이터 구조를 나타냅니다.

이 시점에서이 엔테이트를 포함하는 데이터의 개체로 사용하는 양식이 필요합니다. 우리 양식의 가능한 공장은 이렇게 보일 수 있습니다.

namespace Application\Form\Factory; 

class OrderFormFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $parentLocator = $serviceLocator->getServiceLocator(); 
     $inputFilter = $parentLocator->get('InputFilterManager')->get(OrderInputFiler::class); 
     $hydrator = new ClassMethods(false); 
     $entity = new OrderEntity(); 

     return (new OrderForm()) 
      ->setInputFilter($inputFilter) 
      ->setHydrator($hydrator) 
      ->setObject($entity); 
    } 
} 

이것은 우리 양식의 공장입니다. 우리는 수화기, 입력 필터 및 형식에 대한 엔티티를 설정합니다. 그래서 당신은 뭔가를 구속하지 않아도됩니다. 다음 코드는이 양식으로 데이터를 처리하는 방법을 보여줍니다.

// retrieve an order from database by id 
// This returns a order entity as result 
$order = $this->getServiceLocator()->get(OrderTableGateway::class)->fetchById($id); 

// Extract the order data from object to array assumed the 
// retrieved data from data base is an OrderEntity object 
// the hydrator will use the get* methods of the entity and returns an array 
$data = (new ClassMethods(false))->extract($order); 

// fill the form with the extracted data 
$form = $this->getServiceLocator()->get('FormElementManager')->get(OrderForm::class); 
$form->setData($data); 

if ($form->isValid()) { 

    // returns a validated order entity 
    $order = $form->getData(); 
} 

아직 양식의 데이터를 가져올 수 없으며 아직 검증되지 않았습니다. 양식 데이터의 유효성을 검사해야만 양식에서 필터링 된/유효성 검사 된 데이터를 가져올 수 있습니다. 많은 데이터를 처리해야 할 때 수화기 및 엔티티가 도움이 될 것입니다.