我是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
的Json:
{
'name':'Sheldon Cooper',
'address': {
'street': '2311 N. Los Robles Avenue',
'city': 'Pasadena'
}
}
所以我不想写个别的构造函数,或者根本不想编写任何个人构件。
我确定使用反射可以开箱即用吗?
答案 0 :(得分:1)
使用Closures可以很容易地实现这一点。 甚至不需要创建setter函数。
<?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 :(得分:1)
您可以为受保护变量和私有变量提供setter方法:
public function setName($name)
{
$this->name = $name;
}
JsonMapper会自动使用它。
从版本1.1.0开始,JsonMapper支持映射私有和受保护的属性。
答案 2 :(得分:0)
抱歉,我没有足够的声誉&#39;所以无法添加评论。
我只使用Java几个月,但我的理解是你的Java课程都会有getter和设置,这就是Jackson能够设置私有财产的价值。
要在PHP中执行相同操作,我怀疑您需要将属性设为私有,并创建getter和setter方法......
public function setName($name) {
$this->name = name;
}
然后在Mapper中,使用反射来调用setter。
我这样做的方法是查看JSON中的键,并尝试将方法名称放在一起。
例如,如果JSON中的某个键标有&#39; name&#39; ...
$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();