【问题标题】:Accessing the property name of the first property in an stdClass in PHP在 PHP 中访问 stdClass 中第一个属性的属性名称
【发布时间】:2018-03-12 15:27:45
【问题描述】:

在对 json 字符串执行 json_decode 之后,我有一个包含许多 stdClasses 的数组。

看起来像这样:

product: array(3)
0: stdClass
   PropertyAbc: "Product 1|Product 5"
1: stdClass
   PropertyXyz: "Product 2|Product 9|Product 10"
2: stdClass
   PropertyEfg: "Product 3|Product 12"

我需要将其转换为以下格式的所有值的管道分隔字符串:PropertyName>Value 作为我的最终结果:

PropertyAbc>产品 1|PropertyAbc>产品 5|PropertyXyz>产品 2|PropertyXyz>产品 9|PropertyXyz>产品 10|PropertyEfg>产品 3|PropertyEfg>产品 12

这是我尝试的方法,但无法弄清楚在循环 stdClasses 时如何获取第一个属性的值和名称(注意:每个 stdClass 始终只有一个属性):

foreach ($json->products as $product) {
    // Put all products in an array
    $arr = explode('|', $NEED-VALUE-OF-FIRST-PROP);

    // Loop through array and combine values
    foreach ($arr as $key => $value) {
        $arr[$key] = $NEED-NAME-OF-FIRST-PROP . ">" . $value;
    }
}

【问题讨论】:

  • 当使用foreach ($arr as $key => $value) 迭代对象时,$key 将保留属性名称。

标签: php php-5.6


【解决方案1】:

只需将其转换为数组

$products=json_decode(json_encode($json), true);

然后您就可以像使用简单数组一样对其进行操作了。

实施:

<?php
$p1 = new StdClass();
$p1->PropertyAbc = "Product 1|Product 5";

$p2 = new StdClass();
$p2->PropertyXyz = "Product 2|Product 9|Product 10";

$p3 = new StdClass();
$p3->PropertyEfg = "Product 3|Product 12";

$products_orig = [ $p1, $p2, $p3 ];
$products=json_decode(json_encode($products_orig), true);

?>
<pre><?= print_r($products, true) ?></pre>
<?php
$s='';
foreach($products as $a){
    foreach($a as $key=>$b){
        $c=explode('|', $b);
        foreach($c as $d){
            $s.=(($s==='')?'':'|').$key.'>'.$d;
        }
    }
}
echo $s;

?>

【讨论】:

  • 只有在类是 json_serializable 且没有副作用的情况下才有效
  • @Kancholliev 我按照你说的做了,现在我有一个包含 3 个数组而不是 3 个 stdClasses 的数组。这对我有什么帮助?只是好奇有什么优势。如何获取属性名称?
  • @Kancholliev 我想说的是我现在有类似 Array(1) PropertyXyz:"Product 1 | Product 2" 的东西。如何在我的代码中获取它的 PropertyXyz 部分?键最终为 0,值最终为整个字符串:PropertyXyz:"Product 1 | Product 2
  • 顺便说一句,我认为你的问题是因为你做错了,错过了 json_decode 的第二个参数(true)
【解决方案2】:

get_object_vars 可用于将对象属性作为数组获取并从那里开始工作。

 $p1 = new StdClass();
 $p1->PropertyAbc = "Product 1|Product 5";

 $p2 = new StdClass();
 $p2->PropertyXyz = "Product 2|Product 9|Product 10";

 $p3 = new StdClass();
 $p3->PropertyEfg = "Product 3|Product 12";

 $products = [ $p1, $p2, $p3 ];
 foreach ($products as $product) {
    $productArray = get_object_vars($product);
    $productPropName = array_keys($productArray)[0];
    $productPropsValues = explode('|', array_values($productArray)[0]);
    foreach ($productPropsValues as $productPropsValue) {
        $result[] = $productPropName . '>' . $productPropsValue;
    }
}

var_dump(implode('|', $result));

string(155) "PropertyAbc>Product 1|PropertyAbc>Product 5|PropertyXyz>Product 2|PropertyXyz>Product 9|PropertyXyz>Product 10|PropertyEfg>Product 3|PropertyEfg>Product 12"

【讨论】:

  • 感谢您超越并为我提供解决方案。效果很好。
【解决方案3】:

您可以使用反射来获取对象的属性(参见http://php.net/manual/de/reflectionclass.getproperties.php):

class Foo {
    public    $foo  = 1;
    protected $bar  = 2;
    private   $baz  = 3;
}

$foo = new Foo();

$reflect = new ReflectionClass($foo);
$props   = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);

foreach ($props as $prop) {
    print $prop->getName() . "\n";
}

var_dump($props);

结果:

foo
bar
array(2) {
  [0]=>
  object(ReflectionProperty)#3 (2) {
    ["name"]=>
    string(3) "foo"
    ["class"]=>
    string(3) "Foo"
  }
  [1]=>
  object(ReflectionProperty)#4 (2) {
    ["name"]=>
    string(3) "bar"
    ["class"]=>
    string(3) "Foo"
  }
}

其余的拆分和连接应该是直截了当的!

更新: 更多的澄清。获得属性名称后,您可以使用动态访问器来获取属性的值:

$class = <stdClassObject>;
$reflectionClass = new ReflectionClass($class);
$properties = $reflectionClass->getProperties();

foreach($properties as $p){
  $value = $class->$p;

  // do some concatination here
}

【讨论】:

    【解决方案4】:

    您也可以将get_object_vars 方法设为单行:

    $obj->{array_keys(get_object_vars($obj))[0]};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 2021-01-04
      • 2013-10-17
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 2015-05-26
      相关资源
      最近更新 更多