তাই আমি ঘুরে বেড়ানো ছিল php.net serializing পিএইচপি তাদেরকে JSON করার বস্তু, যখন আমি নতুন জুড়ে পদস্খলিত সম্পর্কে তথ্যের জন্য JsonSerializable ইন্টারফেস । এটি কেবলমাত্র পিএইচপি> = 5.4 , এবং আমি 5.3.x পরিবেশে চলেছি।
এই ধরণের কার্যকারিতা কীভাবে পিএইচপি <5.4 অর্জন করেছে ?
আমি এখনও জেএসএনের সাথে খুব বেশি কাজ করি নি, তবে আমি একটি অ্যাপ্লিকেশনটিতে একটি এপিআই লেয়ার সমর্থন করার চেষ্টা করছি এবং ডেটা অবজেক্টটি ( যা অন্যথায় দর্শনে প্রেরণ করা হবে) জেএসএনে ডাম্প করা সঠিক হবে।
আমি যদি সরাসরি অবজেক্টটি সিরিয়ালাইজ করার চেষ্টা করি তবে এটি একটি খালি JSON স্ট্রিং দেয়; যার কারণ আমি ধরে নিয়েছি json_encode()
হ্যাক অবজেক্টটির সাথে কী করবে তা আমি জানি না। আমি যাও recursively একটি অ্যারের মধ্যে বস্তুর হ্রাস করা উচিত, এবং তারপর এনকোড যে ?
উদাহরণ
$data = new Mf_Data();
$data->foo->bar['hello'] = 'world';
echo json_encode($data)
একটি খালি বস্তু উত্পাদন করে:
{}
var_dump($data)
তবে প্রত্যাশার মতো কাজ করে:
object(Mf_Data)#1 (5) {
["_values":"Mf_Data":private]=>
array(0) {
}
["_children":"Mf_Data":private]=>
array(1) {
[0]=>
array(1) {
["foo"]=>
object(Mf_Data)#2 (5) {
["_values":"Mf_Data":private]=>
array(0) {
}
["_children":"Mf_Data":private]=>
array(1) {
[0]=>
array(1) {
["bar"]=>
object(Mf_Data)#3 (5) {
["_values":"Mf_Data":private]=>
array(1) {
[0]=>
array(1) {
["hello"]=>
string(5) "world"
}
}
["_children":"Mf_Data":private]=>
array(0) {
}
["_parent":"Mf_Data":private]=>
*RECURSION*
["_key":"Mf_Data":private]=>
string(3) "bar"
["_index":"Mf_Data":private]=>
int(0)
}
}
}
["_parent":"Mf_Data":private]=>
*RECURSION*
["_key":"Mf_Data":private]=>
string(3) "foo"
["_index":"Mf_Data":private]=>
int(0)
}
}
}
["_parent":"Mf_Data":private]=>
NULL
["_key":"Mf_Data":private]=>
NULL
["_index":"Mf_Data":private]=>
int(0)
}
অভিযোজ্য বস্তু
1)
সুতরাং এই toArray()
ফাংশনটি আমি Mf_Data
ক্লাসের জন্য তৈরি করেছি :
public function toArray()
{
$array = (array) $this;
array_walk_recursive($array, function (&$property) {
if ($property instanceof Mf_Data) {
$property = $property->toArray();
}
});
return $array;
}
তবে যেহেতু Mf_Data
অবজেক্টগুলিরও তাদের পিতামাতাকে ধারণ করে ( ধারণ করে ) অবজেক্ট রয়েছে তাই এটি পুনরাবৃত্তি করে ব্যর্থ হয়। আমি যখন _parent
রেফারেন্সটি সরিয়ে থাকি তখন কবজির মতো কাজ করে ।
2)
কেবল অনুসরণ করার জন্য, আমি যে জটিল ট্রি-নোড অবজেক্টটি দিয়েছিলাম তার রূপান্তর করার চূড়ান্ত কাজটি ছিল:
// class name - Mf_Data
// exlcuded properties - $_parent, $_index
public function toArray()
{
$array = get_object_vars($this);
unset($array['_parent'], $array['_index']);
array_walk_recursive($array, function (&$property) {
if (is_object($property) && method_exists($property, 'toArray')) {
$property = $property->toArray();
}
});
return $array;
}
3)
আমি আবার প্রয়োগ করছি, একটি বাস্তবায়ন কিছুটা ক্লিনার দিয়ে। একটি instanceof
চেকের জন্য ইন্টারফেস ব্যবহার করা তুলনায় অনেক পরিষ্কার মনে হয় method_exists()
( তবে method_exists()
ক্রস-কাট উত্তরাধিকার / বাস্তবায়ন হয় )।
ব্যবহারটিও unset()
কিছুটা অগোছালো মনে হয়েছিল এবং মনে হচ্ছে যুক্তিটি অন্য কোনও পদ্ধতিতে রিফ্যাক্ট করা উচিত। যাইহোক, এই বাস্তবায়ন করে সম্পত্তি অ্যারে (কপি কারণেarray_diff_key
,) অতএব আপনি ভেবে দেখুন কিছু।
interface ToMapInterface
{
function toMap();
function getToMapProperties();
}
class Node implements ToMapInterface
{
private $index;
private $parent;
private $values = array();
public function toMap()
{
$array = $this->getToMapProperties();
array_walk_recursive($array, function (&$value) {
if ($value instanceof ToMapInterface) {
$value = $value->toMap();
}
});
return $array;
}
public function getToMapProperties()
{
return array_diff_key(get_object_vars($this), array_flip(array(
'index', 'parent'
)));
}
}
JsonSerializable