【问题标题】:Dynamic assignment of property names based on array values基于数组值动态分配属性名
【发布时间】:2018-09-08 21:26:26
【问题描述】:

我正在尝试创建一个将根据用户输入生成动态类属性的类。
将从用户输入数据创建一个数组。这个数组应该作为一个例子:

$array = array(
    # The boolean values are not relevant in this example
    # The keys are important

    'apple' => true,
    'orange' => false,
    'pear' => false,
    'banana' => true,
);

现在我想创建一个以数组键作为类属性的新类:

class Fruit {
    public $apple;
    public $orange;
    public $pear;
    public $banana;

(etc.)
}

我现在必须手动记下所有四个属性。
有没有办法让它自动化?

【问题讨论】:

  • 当然,php 是一种弱类型语言。这特别意味着你可以实现一个没有任何属性的类,但仍然可以分配你喜欢的任何属性:-) 所以你可以实现一个方法 setProperties() 或类似的方法,即使是一个参数数组。
  • 答案显示了如何使用您自己的类,但如果您只想要一个通用对象:$fruit = (object)$array;

标签: php arrays oop object properties


【解决方案1】:
<?php

class MyClass 
{
    public function __construct ($config = []) 
    {
        foreach ($config as $key => $value) {
            $this->{$key} = $value;
        }
    }
}

$myClass = new MyClass(['apple' => 1, 'orange' => 2]);

echo $myClass->apple;
?>

这应该对你有帮助

【讨论】:

    【解决方案2】:

    给你,

    我在里面放了一些额外的东西:

    class MyClass implements Countable, IteratorAggregate
    {
        protected $data = [];
    
        public function __construct (array $data = []) 
        {
            foreach ($data as $key => $value) {
                $this->{$key} = $value;
            }
        }
    
        public function __set($key, $value){
            $this->data[$key] = $value;
        }
    
        public function __get($key)
        {
            if(!isset($this->{$key})) return null; //you could also throw an exception here.
            return $this->data[$key];
        }
    
        public function __isset($key){
            return isset($this->data[$key]);
        }
    
        public function __unset($key){
            unset($this->data[$key]);
        }
    
        public function __call($method, $args){
    
            $mode = substr($method, 0, 3);
            $property = strtolower(substr($method, 3)); //only lowercase properties
            if(isset($this->{$property})) {
                if($mode == 'set'){
                    $this->{$property} = $args[0];
                    return null;
                }else if($mode == 'get'){
                    return $this->{$property};
                }
            }else{
                return null; //or throw an exception/remove this return
            }
            throw new Exception('Call to undefined method '.__CLASS__.'::'.$method);
        }
    
        //implement Countable
        public function count(){
            return count($this->data);
        }
    
        //implementIteratorAggregate
        public function getIterator() {
            return new ArrayIterator($this->data);
        }
    
    }
    

    测试一下:

    $myClass = new MyClass(['one' => 1, 'two' => 2]);
    
    echo $myClass->two."\n";
    
    //Countable
    echo count($myClass)."\n";
    
    //dynamic set
    $myClass->three = 3;
    
    echo count($myClass)."\n";
    
    //dynamic get/set methods. I like camel case methods, and lowercase properties. If you don't like that then you can change it.
    $myClass->setThree(4);
    echo $myClass->getThree()."\n";
    
    //IteratorAggregate
    foreach($myClass as $key=>$value){
        echo $key.' => '.$value."\n";
    }
    

    输出

    2 //value of 2
    2 //count of $data
    3 //count of $data after adding item
    4 //value of 3 after changing it with setThree
    //foreach output
    one => 1
    two => 2
    three => 4
    

    Test it online

    免责声明

    一般来说,虽然最好手动定义类,这样就像 IDE 的工作一样。您可能还会遇到问题,因为您不一定会提前知道类中定义的内容。您没有类的具体定义。

    几乎任何以__ 开头的方法(至少在我的代码中)都是 PHP 魔术方法(是的,这是一回事)。当我第一次学习如何使用它们时,我认为它很酷,但现在我几乎从不使用它们......

    现在,如果您想创建一个包含该代码的实际 .php 文件,那就另当别论了。 (不是 100% 清楚,如果您想要功能或实际文件)

    干杯。

    【讨论】:

      猜你喜欢
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 1970-01-01
      相关资源
      最近更新 更多