JSON-строка для php-объекта через отражение / как Джексон маппер

Я фанат Джексона Маппера в Java, и я немного потерян без него в php. Я хотел бы эквивалент.

Пока что мне ближе всего это, однако, требуется, чтобы поля были объявлены как публичные, и я не хочу этого делать:

https://github.com/netresearch/jsonmapper

Я хочу что-то, что делает все, что делает, с такого рода кодом:

<?php
class Contact
{
/**
* Full name
* @var string
*/
public $name; //<- I want this to be private

/**
* @var Address //<- and this
*/
public $address;
}

class Address
{
public $street;<- and this
public $city;<- and this

public function getGeoCoords()
{
//do something with the $street and $city
}
}

$json = json_decode(file_get_contents('http://example.org/bigbang.json'));
$mapper = new JsonMapper();
$contact = $mapper->map($json, new Contact());

Джсон из file_get_contents:

{
'name':'Sheldon Cooper',
'address': {
'street': '2311 N. Los Robles Avenue',
'city': 'Pasadena'
}
}

Поэтому я не хочу писать отдельных конструкторов или что-то индивидуальное вообще.

Я уверен, что будет что-то, что делает это из коробки, используя отражение?

0

Решение

Это может быть достигнуто очень легко и красиво, используя Closures.
Нет даже необходимости создавать сеттер-функции.

<?php

class A {
private $b;
public $c;

function d() {

}
}

$data = [
'b' => 'b-value',
'c' => 'c-value',
'd' => 'function',
];

class JsonMapper {
public function map( $data, $context ) {
$json_mapper = function() use ( $data ) {
foreach ($data as $key => $value) {
if ( property_exists( $this, $key ) ) {
$this->{$key} = $value;
}
}
};

$json_mapper = $json_mapper->bindTo( $context, $context );
$json_mapper();

return $context;
}
}

$mapper = new JsonMapper();
$a = $mapper->map( $data, new A );

print_r($a);
1

Другие решения

Вы можете предоставить метод установки для защищенных и закрытых переменных:

public function setName($name)
{
$this->name = $name;
}

JsonMapper будет автоматически использовать его.


Начиная с версии 1.1.0 JsonMapper поддерживает отображение частных и защищенных свойств.

1

Извините, мне не хватает «репутации», поэтому я не могу добавить комментарий.

Я использую Java всего несколько месяцев, но, насколько я понимаю, все ваши классы на Java будут иметь геттеры и настройки, и именно так Джексон может установить значение частного свойства.

Я подозреваю, что для того, чтобы сделать то же самое в PHP, вам нужно сделать свои свойства приватными и создать методы getter и setter …

public function setName($name) {
$this->name = name;
}

Затем в вашем Mapper используйте рефлексию, чтобы вызвать сеттер.

Я бы сделал так, чтобы посмотреть на ключи, которые есть в JSON, и попытаться составить имя метода.

Например, если в JSON есть ключ с именем «name» …

$className = "Contact";
$object = json_decode($jsonResponse);

$classObject = new $className();

foreach ($object as $key => $value) {
$methodName = "set" . ucfirst($key);

if (method_exists($classObject, $methodName)) {
$classObject->$methodName($value);
}
}

Вышесказанное может быть не совсем правильным, но я надеюсь, что это даст вам представление.

Чтобы расширить вышесказанное, я собрал следующий пример, который, кажется, делает то, что вам нужно?

class Contact {

private $name;
private $telephone;

public function setName($name) {
$this->name = $name;
}

public function setTelephone($telephone) {
$this->telephone = $telephone;
}

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

public function getTelephone() {
return $this->telephone;
}

}

class Mapper {

private $jsonObject;

public function map($jsonString, $object) {
$this->jsonObject = json_decode($jsonString);

if (count($this->jsonObject) > 0) {
foreach ($this->jsonObject as $key => $value) {
$methodName = "set" . ucfirst($key);

if (method_exists($object, $methodName)) {
$object->$methodName($value);
}
}
}

return $object;
}

}

$myContact = new stdClass();
$myContact->name = "John Doe";
$myContact->telephone = "0123 123 1234";

$jsonString = json_encode($myContact);

$mapper = new Mapper();
$contact = $mapper->map($jsonString, new Contact());

echo "Name: " . $contact->getName() . "<br>";
echo "Telephone: " . $contact->getTelephone();
0
По вопросам рекламы [email protected]