在 Symfony 中将实体转换为数组

问题描述 投票:0回答:5

我正在尝试从实体中获取多维数组。

Symfony Serializer 已经可以转换为 XML、JSON、YAML 等,但不能转换为数组。

我需要转换,因为我想要一个干净的

var_dump
。我现在的实体几乎没有联系,完全不可读。

我怎样才能做到这一点?

php symfony doctrine-orm
5个回答
12
投票

您实际上可以使用内置的序列化程序将学说实体转换为数组。事实上,我今天刚刚写了一篇关于这个的博客文章: https://skylar.tech/detect-doctrine-entity-changes-without/

你基本上调用了 normalize 函数,它会给你你想要的:

$entityAsArray = $this->serializer->normalize($entity, null);

我建议查看我的帖子以获取有关某些怪癖的更多信息,但这应该完全按照您的意愿进行,而无需任何其他依赖项或处理私有/受保护字段。


9
投票

显然,可以将对象转换为数组,如下所示:

<?php

class Foo
{
    public $bar = 'barValue';
}

$foo = new Foo();

$arrayFoo = (array) $foo;

var_dump($arrayFoo);

会产生类似的东西:

array(1) {
    ["bar"]=> string(8) "barValue"
}

如果您有私有和受保护的属性,请参阅此链接:https://ocramius.github.io/blog/fast-php-object-to-array-conversion/

从存储库查询中获取数组格式的实体

在您的 EntityRepository 中,您可以选择您的实体并指定您想要一个带有

getArrayResult()
方法的数组。
有关更多信息,请参阅Doctrine 查询结果格式文档

public function findByIdThenReturnArray($id){
    $query = $this->getEntityManager()
        ->createQuery("SELECT e FROM YourOwnBundle:Entity e WHERE e.id = :id")
        ->setParameter('id', $id);
    return $query->getArrayResult();
}

如果所有这些都不适合你应该去看看关于 ArrayAccess 接口的 PHP 文档。
它以这种方式检索属性:

echo $entity['Attribute'];


1
投票

PHP 8 允许我们将对象转换为数组:

$var = (array)$someObj;

对象只有公共属性很重要,否则你会得到奇怪的数组键:

<?php
class bag {
    function __construct( 
        public ?bag $par0 = null, 
        public string $par1 = '', 
        protected string $par2 = '', 
        private string $par3 = '') 
    {
        
    }
}
  
// Create myBag object
$myBag = new bag(new bag(), "Mobile", "Charger", "Cable");
echo "Before conversion : \n";
var_dump($myBag);
  
// Converting object to an array
$myBagArray = (array)$myBag;
echo "After conversion : \n";
var_dump($myBagArray);
?>

输出如下:

Before conversion : 
object(bag)#1 (4) {
  ["par0"]=>               object(bag)#2 (4) {
    ["par0"]=>                      NULL
    ["par1"]=>                      string(0) ""
    ["par2":protected]=>            string(0) ""
    ["par3":"bag":private]=>        string(0) ""
  }
  ["par1"]=>               string(6) "Mobile"
  ["par2":protected]=>     string(7) "Charger"
  ["par3":"bag":private]=> string(5) "Cable"
}


After conversion : 
array(4) {
  ["par0"]=>      object(bag)#2 (4) {
    ["par0"]=>                  NULL
    ["par1"]=>                  string(0) ""
    ["par2":protected]=>        string(0) ""
    ["par3":"bag":private]=>    string(0) ""
  }
  ["par1"]=>      string(6) "Mobile"
  ["�*�par2"]=>   string(7) "Charger"
  ["�bag�par3"]=> string(5) "Cable"
}

与 Serialiser 规范化相比,此方法有一个好处——这样您可以将对象转换为对象数组,而不是数组数组。


0
投票

我有同样的问题并尝试了其他 2 个答案。两者都不是很顺利。

  • $object = (array) $object;
    在我的密钥中添加了很多额外的文本 名字。
  • 序列化程序没有使用我的
    active
    属性,因为它前面没有
    is
    ,是一个
    boolean
    。它还改变了我的数据顺序和数据本身。

所以我在我的实体中创建了一个新函数:

/**
 * Converts and returns current user object to an array.
 * 
 * @param $ignores | requires to be an array with string values matching the user object its private property names.
 */
public function convertToArray(array $ignores = [])
{
    $user = [
        'id' => $this->id,
        'username' => $this->username,
        'roles' => $this->roles,
        'password' => $this->password,
        'email' => $this->email,
        'amount_of_contracts' => $this->amount_of_contracts,
        'contract_start_date' => $this->contract_start_date,
        'contract_end_date' => $this->contract_end_date,
        'contract_hours' => $this->contract_hours,
        'holiday_hours' => $this->holiday_hours,
        'created_at' => $this->created_at,
        'created_by' => $this->created_by,
        'active' => $this->active,
    ];

    // Remove key/value if its in the ignores list.
    for ($i = 0; $i < count($ignores); $i++) { 
        if (array_key_exists($ignores[$i], $user)) {
            unset($user[$ignores[$i]]);
        }
    }

    return $user;
}

我基本上将我所有的属性都添加到新的

$user
数组中,并制作了一个额外的
$ignores
变量,以确保可以忽略属性(以防您不想要所有属性)。

您可以在您的控制器中使用它,如下所示:

$user = new User();
// Set user data...

// ID and password are being ignored.
$user = $user->convertToArray(["id", "password"]);

0
投票

我将这个特征添加到实体中:

<?php

namespace Model\Traits;

/**
 * ToArrayTrait
 */
trait ToArrayTrait
{
    /**
     * toArray
     *
     * @return array
     */
    public function toArray(): array
    {
        $zval = get_object_vars($this);

        return($zval);
    }
}

然后你的猫做:

$myValue = $entity->toArray();

© www.soinside.com 2019 - 2024. All rights reserved.