2015-11-09 2 views
0

Объект цены имеет три свойства,Как настроить вывод объекта во время json_encode?

/** @var float */ 
public $amount = 0.0; 

/** @var string */ 
public $currency = ''; 

/** 
* @var \DateTime 
*/ 
public $dueDate; 

При сериализации этого объекта JSON с помощью Symfony2 Symfony\Component\HttpFoundation\JsonResponse, он будет выглядеть следующим образом:

{ 
    "price": { 
    "amount": 235, 
    "currency": "EUR", 
    "dueDate": { 
     "date": "2015-10-25 00:00:00.000000", 
     "timezone": "UTC", 
     "timezone_type": 3 
    } 
    } 
} 

Я хочу \ DateTime быть отформатирован как просто строка:

"dueDate": "2015-10-22 00:00:00.000000" 

Как получить это сделать, это не масштаб вопроса, так как я в настоящее время обрабатывать этот случай в кон объекта structor:

/** 
* Price constructor. 
* @param float   $amount 
* @param string   $currency 
* @param \DateTime|null $dueDate 
*/ 
public function __construct($amount = 0.0, $currency = "", $dueDate) 
{ 
    $this->amount = $amount; 
    $this->currency = $currency; 
    $this->dueDate = $dueDate;; 

    if ($dueDate instanceof \DateTime) { 
     $this->dueDate = $dueDate->format(\DateTime::ATOM); 
    } 
} 

пока он не чувствовать совершенно права, и мне интересно, если я мог бы настроить процесс сериализации по-разному, в том смысле, вместо кодирования моего представления, изменить способ объекта сериализации ,

Рассуждение состоит в том, чтобы все объекты \DateTime были сериализованы, которые сериализованы везде, где в объекте, подлежащем сериализации, определенным образом, без дублирующей логики. (Я предполагаю, что я мог бы поставить обращение в абстрактном классе или где-то похожи, но простирающиеся объекты также имеет свои подводные камни)

В основном:

Есть ли поймать onserialize «событие», где я могу добавить некоторую логику, или мне лучше смотреть в JMSSerializer?

+2

только ваш класс реализует класс ['JsonSerializable'] (http://php.net/manual/en/class.jsonserializable.php) и создает метод с именем [' jsonSerialize'] (http://php.net/manual/en/jsonserializable.jsonserialize.php), который возвращает массив данных, которые вы хотите сериализовать с помощью '' json_encode() ') (http://php.net/manual/en/function.json -encode.php) –

ответ

2

Я не знаю, почему я не представил это как ответ. Так как PHP 5.4.0 класс библиотеки JsonSerializable поставляется с установкой PHP. Вы можете реализовать этот класс самостоятельно и создать метод с именем jsonSerialize, который будет вызываться всякий раз, когда json_encode() вызывается с классом в качестве аргумента. Решение вашего затруднительного положения может быть похоже на это:

<?php 
class Price implements JsonSerializable { 
    private 
     $amount 
    , $currency 
    , $dueDate 
    ; 
    /** 
    * Price constructor. 
    * @param float   $amount 
    * @param string   $currency 
    * @param \DateTime|null $dueDate 
    */ 
    public function __construct($amount = 0.0, $currency = "", $dueDate = NULL) 
    { 
     $this->amount = $amount; 
     $this->currency = $currency; 
     $this->dueDate = $dueDate; 
    } 

    public function jsonSerialize(){ 
     return array(
      'amount' => $this->amount 
     , 'currency' => $this->currency 
     , 'dueDate' => $this->dueDate instanceof \DateTime ? $this->dueDate->format(\DateTime::ATOM) : $this->dueDate 
    } 
} 

echo json_encode(new Price(235, "EUR", new DateTime())); 
1

Так у вас есть 3 варианта:

  • Используйте интерфейс JsonSerializable как @ IAM-кодировщик предложенного.
  • Используйте полноразмерный сериализатор, такой как JMS (может быть медленным).
  • Использование transformer, плюс сторона этого заключается в том, что ваш выход отделен от ваших данных, и вы можете изменять и тестировать каждый компонент самостоятельно.
Смежные вопросы