我有一个带有受保护属性的大对象,一个属性可以是其他对象的数组。我的目标是将整个Object打印为单个嵌套数组。所以我需要将对象转换为数组。
我已经尝试过:
$result = (array) $object;
但是这只将最高的杠杆对象转换为数组,并且用奇怪的问号标记弄乱了我的受保护属性名称。
我也试过这样的事情,但这只是返回一个空数组:
$ result = json_decode(json_encode($ object),true);
这是我的对象的样子:
object(Handling\Model\SearchBooking\Booking)[133]
protected 'jabooknr' => string '018024709' (length=9)
protected 'jitsbooknr' => string '' (length=9)
protected 'status' => string 'Y' (length=1)
protected 'platform' => int 4
protected 'agentid' => string '' (length=6)
protected 'paymentInfo' => null
protected 'transports' =>
array (size=2)
0 =>
object(Handling\Model\SearchBooking\Transport)[145]
protected 'depdate' =>
object(DateTime)[146]
public 'date' => string '2016-12-06 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
protected 'carriercode' => string 'TB' (length=2)
protected 'carriernumber' => string '2067' (length=4)
protected 'brochure' => string '' (length=6)
protected 'pax' =>
array (size=2)
0 =>
object(Handling\Model\SearchBooking\Pax)[147]
protected 'id' => int 1
protected 'title' => string 'MRS' (length=3)
protected 'firstname' => string 'MA' (length=7)
protected 'name' => string 'BEN' (length=5)
protected 'age' => int 58
protected 'luggage' => int 20
protected 'handLuggage' => null
1 =>
object(Handling\Model\SearchBooking\Pax)[148]
protected 'id' => int 2
protected 'title' => string 'MR' (length=2)
protected 'firstname' => string 'P' (length=6)
protected 'name' => string 'FT' (length=4)
protected 'age' => int 60
protected 'luggage' => int 20
protected 'handLuggage' => null
protected 'departureAirport' => string 'BRU' (length=3)
protected 'arrivalAirport' => string 'AGP' (length=3)
1 =>
object(Handling\Model\SearchBooking\Transport)[149]
protected 'depdate' =>
object(DateTime)[150]
public 'date' => string '2016-12-13 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
protected 'carriercode' => string 'TB' (length=2)
protected 'carriernumber' => string '2068' (length=4)
protected 'brochure' => string '' (length=6)
protected 'pax' =>
array (size=2)
0 =>
object(Handling\Model\SearchBooking\Pax)[151]
protected 'id' => int 1
protected 'title' => string 'MRS' (length=3)
protected 'firstname' => string 'MANE' (length=7)
protected 'name' => string 'BN' (length=5)
protected 'age' => int 58
protected 'luggage' => int 20
protected 'handLuggage' => null
1 =>
object(Handling\Model\SearchBooking\Pax)[152]
protected 'id' => int 2
protected 'title' => string 'MR' (length=2)
protected 'firstname' => string 'PIRE' (length=6)
protected 'name' => string 'FYT' (length=4)
protected 'age' => int 60
protected 'luggage' => int 20
protected 'handLuggage' => null
protected 'departureAirport' => string 'AGP' (length=3)
protected 'arrivalAirport' => string 'BRU' (length=3)
protected 'extraLuggage' => null
我班上有一个方法,我找到""看起来像这样的结果:
public function findBooking()
{
//here happens a bunch of logic to get the right result
var_dump($object); exit; // this is the result that is show above
return $object;
}
答案 0 :(得分:0)
有一些问题会让这很困难。
在尝试在课堂外阅读时,属性可见性(私有,受保护)可能会导致问题。这是预期的行为,因为这是不使用公共的。
课程不同。它们定义明确,我们提前了解它们,但它们太多样化,无法考虑所有属性名称,至少不会浪费很多精力。更不用说定义它们了#34;硬编码"以后会咬你,因为它会让你难以维持。例如,如果其中一个软件包进行了更新,并且您已编写了属性名称,则可能会在更改它们时出现问题。除此之外,这些属性不属于Public" API"但作为内部的一部分,他们改变是不合理的。
属性可以包含多种数据类型,包括其他类或对象。这可能会使其难以处理。
类是其他包/框架的一部分,编辑它们是不实际的,这限制了我们在这些类之外工作。
因此,考虑到这些困难,我建议使用反射来访问受保护的属性。 Reflection允许您检查类(和其他东西)的定义。
function jsonSerialize($obj){
return json_encode(toArray($obj));
}
function toArray($obj){
$R = new ReflectionObject($obj);
$proerties = $R->getProperties();
$data = [];
foreach($proerties as $k => $v){
$v->setAccessible(true);
$property = $v->getName();
$value = $v->getValue($obj);
if(!is_object($value)){
$data[$property] = $value;
}else if( is_a($obj,'\\DateTime')){
//if its a descendant of Datetime, get a formatted date.
// you can add other special case classes in this way
$data[$property] = $value->format('Y-m-d H:i:s');
}else{
$data[$property] = toArray($value); //call recursively
}
}
return $data;
}
假设我们有这些类
class foo{
private $bar; //private nested object
public function __construct(){
$this->bar = new bar();
}
}
class bar{
private $something = 'hello';
}
$obj = new foo;
echo jsonSerialize($obj);
在沙箱here
中查看输出:
{"bar":{"something":"hello"}}
另外值得注意的是我们对DateTime
类有特殊的考虑。我们只想要以某种标准方式格式化日期(可能),而不是获得所有这些属性。因此,通过使用is_a()(我老了)我们可以判断对象$value
是否有一个给定的类作为它的祖先。然后我们只是进行格式化。
可能有一些这样的特殊情况,所以我想提一下如何处理它们。