一种解决方案(我不知道它是否是更好的解决方案,但一种可能的解决方案)是创建这样的函数:
function from_obj(&$type,$default = "") {
return isset($type)? $type : $default;
}
然后
$data = '{"name": "Pavel", "job": "programmer"}';
$object = json_decode($data);
$name = from_obj( $object->name , "unknown");
$job = from_obj( $object->job , "unknown");
$skill = from_obj( $object->skills[0] , "unknown");
$skills = from_obj( $object->skills , Array());
echo "Your name is $name. You are a $job and your main skill is $skill";
if(count($skills) > 0 ) {
echo "\n\nYour skills: " . implode(",",$skills);
}
我认为这很方便,因为你在脚本的顶部有你想要的和它应该是什么(数组、字符串等)
编辑:
另一种解决方案。您可以创建一个扩展 ArrayObject 的 Bridge 类:
class ObjectBridge extends ArrayObject{
private $obj;
public function __construct(&$obj) {
$this->obj = $obj;
}
public function __get($a) {
if(isset($this->obj->$a)) {
return $this->obj->$a;
}else {
// return an empty object in order to prevent errors with chain call
$tmp = new stdClass();
return new ObjectBridge($tmp);
}
}
public function __set($key,$value) {
$this->obj->$key = $value;
}
public function __call($method,$args) {
call_user_func_array(Array($this->obj,$method),$args);
}
public function __toString() {
return "";
}
}
$data = '{"name": "Pavel", "job": "programmer"}';
$object = json_decode($data);
$bridge = new ObjectBridge($object);
echo "My name is {$bridge->name}, I have " . count($bridge->skills). " skills and {$bridge->donald->duck->is->paperinik}<br/>";
// output: My name is Pavel, I have 0 skills and
// (no notice, no warning)
// we can set a property
$bridge->skills = Array('php','javascript');
// output: My name is Pavel, my main skill is php
echo "My name is {$bridge->name}, my main skill is {$bridge->skills[0]}<br/>";
// available also on original object
echo $object->skills[0]; // output: php
我个人更喜欢第一个解决方案。它更清晰,更安全。