【问题标题】:Building an array from unknown object properties从未知对象属性构建数组
【发布时间】:2012-02-16 23:09:47
【问题描述】:

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

// 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                                                      
    );        
}

上面的代码不起作用,但希望它说明了我正在尝试做的事情。任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: php arrays oop


    【解决方案1】:

    试试这样的:

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

    【讨论】:

      【解决方案2】:

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

      $objVariants->attr['pid']
      

      您也可以使用magic methods 使您的对象数组类似。

      【讨论】:

        【解决方案3】:

        您可以使用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]);
            }
        });
        

        【讨论】:

        • 了解一下很有用,但在这种情况下,我只想要特定的属性。该对象包含我不需要的其他对象。
        • @JamieDevine - 我添加了代码以从 get_objects_vars() 返回的数组中删除特定变量。
        【解决方案4】:

        听起来你真正想要的是子类或工厂模式。

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

        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)

        【讨论】:

        • 感谢您的回答,在这种情况下,我正在电子商务系统的框架内工作,因此我不得不使用那里的类和对象结构。
        • 无赖 - 然后将成为其他人的答案中的 foreach 循环之一 :)
        • 不过,如果我的回答很好,你会得到 +1 ;)
        猜你喜欢
        • 2020-10-17
        • 1970-01-01
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-02
        • 1970-01-01
        相关资源
        最近更新 更多