从未知对象属性构建数组


Building an array from unknown object properties

我正试图从PHP中的Object构建一个数组。我只想要对象的某些属性,但我不想要;I don’我不知道每次都会是什么样子。我需要的属性的名称存储在一个数组中。以下是我的代码目前的工作方式:

// Hard-coded attributes 'colour' and 'size'
while ($objVariants->next())
{   
    $arrVariants[] = array
    (   
        'pid' => $objVariants->pid,
        'size' => $objVariants->size,
        'colour' => $objVariants->colour,
        'price' => $objVariants->price                                                      
    );        
}

我不想对属性(颜色和大小)进行硬编码,而是想使用变量,因为它可能并不总是颜色和大小,这取决于用户在CMS中设置的内容。例如:

$arrVariantAttr = $this->getVariantAttr(); // Get the names of the custom variants and put them in an array e.g colour, size
while ($objVariants->next())
{   
    $arrVariants[] = array
    (   
        'pid' => $objVariants->pid,
        foreach($arrVariantAttr as $attr)
        {
            $attr['name'] => $objVariants-> . $attr['name']; // Get each variant out of the object and put into an array
        }
        'price' => $objVariants->price                                                      
    );        
}

上面的代码不起作用,但希望它能说明我正在努力做什么。任何帮助都将不胜感激,谢谢!

您可以使用get_object_vars()来获取对象的所有变量:

$arrVariants[] = get_object_vars($objVariants);

为了从对象中排除特定属性,您可以这样做:

$arrVariants = get_object_vars($objVariants);
// array containing object properties to exclude
$exclude = array('name');
// walk over array and unset keys located in the exclude array
array_walk($arrVariants, function($val,$key) use(&$arrVariants, $exclude) {
    if(in_array($key, $exclude)) {
        unset($arrVariants[$key]);
    }
});

您可以在包含属性的对象中创建一个数组:

$objVariants->attr['pid']

您还可以使用魔术方法使您的对象数组类似。

听起来您真正想要的是子类或Factory模式。

例如,你可以有一个基本的产品对象

class Product {
  protected $_id;
  protected $_sku;
  protected $_name;
  ...
  etc.
  //getters and setters
  etc.
}

然后使用子类来扩展该产品

final class Book extends Product {
  private $_isbn;
  private $_language;
  private $_numPages;
  ...
  etc.
  public function __construct() {
    parent::__construct();
  }
  //getters and setters
  etc.
}

这样一来,您的产品类型就具备了所需的所有属性,您不需要尝试使用"属性"数组四处乱跑——尽管您的CMS需要能够支持产品类型(这样,如果有人想添加新书,与书籍相关的字段就会出现在CMS中)。。。这只是一种稍微更面向对象的方法。

然后你就可以把它做成工厂模式;类似于(一个真正的基本示例):

class ProductFactory {
  const TYPE_BOOK = 'Book';
  const TYPE_CD = 'CD';
  const TYPE_DVD = 'DVD';
  ...
  etc.
  public static function createProduct($sProductType) {
    if(class_exists($sProductType)) {
      return new $sProductType();
    }
    else {
      //throw an exception
    }
  }
}

然后,您可以使用以下内容生成新产品:

$oWarAndPeace = ProductFactory::createProduct('Book')

或者更好:

$oWarAndPeace = ProductFactory::createProduct(ProductFactory::TYPE_BOOK)

试试这样的东西:

$arrVariants[] = Array(
  'pid' => $objVariants->pid,
  'price' => $objVariants->price
);
while( $objVariants->next() )
{
  foreach( $arrVariantAttr as $attr )
  {
    end($arrVariants)[$attr['name']] = $objVariants->$attr['name'];
  }
}