Ответ 1
В RedBeanPHP 2.0 есть функция массового экспорта, которая превращает всю коллекцию beans в массивы. Это работает с кодировщиком JSON.
json_encode( R::exportAll( $beans ) );
Я пытаюсь вывести списки объектов как json и хотел бы знать, есть ли способ сделать объекты пригодными для json_encode
? Код, который у меня есть, выглядит примерно так:
$related = $user->getRelatedUsers();
echo json_encode($related);
Прямо сейчас, я просто перебираю массив пользователей и отдельно экспортирую их в массивы для json_encode
, чтобы превратиться в полезный json для меня. Я уже пытался сделать объекты итерабельными, но json_encode
просто пропускает их в любом случае.
edit: здесь var_dump();
php > var_dump($a);
object(RedBean_OODBBean)#14 (2) {
["properties":"RedBean_OODBBean":private]=>
array(11) {
["id"]=>
string(5) "17972"
["pk_UniversalID"]=>
string(5) "18830"
["UniversalIdentity"]=>
string(1) "1"
["UniversalUserName"]=>
string(9) "showforce"
["UniversalPassword"]=>
string(32) ""
["UniversalDomain"]=>
string(1) "0"
["UniversalCrunchBase"]=>
string(1) "0"
["isApproved"]=>
string(1) "0"
["accountHash"]=>
string(32) ""
["CurrentEvent"]=>
string(4) "1204"
["userType"]=>
string(7) "company"
}
["__info":"RedBean_OODBBean":private]=>
array(4) {
["type"]=>
string(4) "user"
["sys"]=>
array(1) {
["idfield"]=>
string(2) "id"
}
["tainted"]=>
bool(false)
["model"]=>
object(Model_User)#16 (1) {
["bean":protected]=>
*RECURSION*
}
}
}
и вот что мне дает json_encode:
php > echo json_encode($a);
{}
Я закончил с этим:
function json_encode_objs($item){
if(!is_array($item) && !is_object($item)){
return json_encode($item);
}else{
$pieces = array();
foreach($item as $k=>$v){
$pieces[] = "\"$k\":".json_encode_objs($v);
}
return '{'.implode(',',$pieces).'}';
}
}
Он принимает массивы, полные этих объектов или только отдельные экземпляры, и превращает их в json - я использую его вместо json_encode. Я уверен, что есть места, где я мог бы сделать это лучше, но я надеялся, что json_encode сможет обнаружить, когда итерации через объект на основе его открытых интерфейсов.
В RedBeanPHP 2.0 есть функция массового экспорта, которая превращает всю коллекцию beans в массивы. Это работает с кодировщиком JSON.
json_encode( R::exportAll( $beans ) );
Все свойства вашего объекта являются частными. aka... не доступны вне их класса.
Если вы хотите сериализовать свои частные и защищенные объекты, вам необходимо реализовать функцию кодирования JSON внутри вашего класса, которая использует json_encode()
для структуры данных, которую вы создаете для этой цели.
class Thing {
...
public function to_json() {
return json_encode(array(
'something' => $this->something,
'protected_something' => $this->get_protected_something(),
'private_something' => $this->get_private_something()
));
}
...
}
Используйте новый интерфейс JsonSerializable
, чтобы предоставить свое собственное json-представление, которое будет использоваться json_encode
class Thing implements JsonSerializable {
...
public function jsonSerialize() {
return [
'something' => $this->something,
'protected_something' => $this->get_protected_something(),
'private_something' => $this->get_private_something()
];
}
...
}
В PHP >= 5.4.0 появился новый интерфейс для сериализации объектов в JSON: JsonSerializable
Просто реализуйте интерфейс в своем объекте и определите метод JsonSerializable
, который будет вызываться при использовании json_encode
.
Итак, решение для PHP >= 5.4.0 должно выглядеть примерно так:
class JsonObject implements JsonSerializable
{
// properties
// function called when encoded with json_encode
public function jsonSerialize()
{
return get_object_vars($this);
}
}
Я еще не видел этого, но beans имеет встроенный метод под названием getProperties()
.
Итак, чтобы использовать его:
// What bean do we want to get?
$type = 'book';
$id = 13;
// Load the bean
$post = R::load($type,$id);
// Get the properties
$props = $post->getProperties();
// Print the JSON-encoded value
print json_encode($props);
Выводится:
{
"id": "13",
"title": "Oliver Twist",
"author": "Charles Dickens"
}
Теперь сделайте шаг вперед. Если у нас есть массив из beans...
// An array of beans (just an example)
$series = array($post,$post,$post);
... тогда мы могли бы сделать следующее:
Прокрутите массив с помощью цикла foreach
.
Замените каждый элемент (a bean) массивом свойств bean.
Итак, это...
foreach ($series as &$val) {
$val = $val->getProperties();
}
print json_encode($series);
... выводит это:
[
{
"id": "13",
"title": "Oliver Twist",
"author": "Charles Dickens"
},
{
"id": "13",
"title": "Oliver Twist",
"author": "Charles Dickens"
},
{
"id": "13",
"title": "Oliver Twist",
"author": "Charles Dickens"
}
]
Надеюсь, это поможет!
Следующий код работал у меня:
public function jsonSerialize()
{
return get_object_vars($this);
}
Обычно я включаю в мои объекты небольшую функцию, которая позволяет мне сбрасывать массив или json или xml. Что-то вроде:
public function exportObj($method = 'a')
{
if($method == 'j')
{
return json_encode(get_object_vars($this));
}
else
{
return get_object_vars($this);
}
}
в любом случае, get_object_vars()
, вероятно, вам полезен.
$products=R::findAll('products');
$string = rtrim(implode(',', $products), ',');
echo $string;
для массива объектов, я использовал что-то вроде этого, следуя пользовательскому методу для php < 5,4:
$jsArray=array();
//transaction is an array of the class transaction
//which implements the method to_json
foreach($transactions as $tran)
{
$jsArray[]=$tran->to_json();
}
echo json_encode($jsArray);