duanqian1888 2014-05-24 19:09
浏览 32
已采纳

PHP对象数组得到密钥

I'm studying how objects and arrays work in PHP for a little project. Unfortunately it's difficult to find out what are good ways to deal with data, there are many solutions but i can't find the right solution for my problem. I think I prefer two work with an object.

I have two questions related to this example:

class cars {}

$cars = new cars();  

$cars->brand = new cars();
$cars->brand->audi = "A6";
$cars->brand->opel = "insignia";

question 1 How can I get each brand as output for example with a for each loop or other function?

echo somesolution will give audi

question 2 Is there a way like with arrays using parentheses to write the code without repeating $cars->brand->opel ?

question 3 Why do I need tho create the class cars?

  • 写回答

3条回答 默认 最新

  • dongqiongjiong4740 2014-05-24 19:55
    关注

    No matter your way is absolutely possible and of course, not so hard to make much more generic, it is as well very incorrect in the terms of Object oriented design.

    Brands should be a totally different object. In your design you inject a brand new instance of Cards to the current Cars instance, only to specify properties. For this purpose you can use standard class object stdClass.

    With foreach around your Brand object (cars), you will get as keys the property names audi, opel, etc. And as values their models.

    foreach ($cars->brand as $name => $value) {
        echo $name . ' ' . $value . "<br />";
    }
    

    which will result in audi a6, opel insignia.

    However, the thing you are looking for is the polymorphism. Each Brand is object of type Car, unless it's a brand of something else. This is the way which people might tell you it's the right one. Because when designing an application, you are seeking a good design as well as the work should be done.

    Each object, Audi, Opel, etc is a child of a superclass Car. Thus, you instantiate them for a given parameter.

    abstract class Car {
        protected $_name;
        protected $_model;
    
        public function __construct($model) {
            $this->_model = $model;
        }
    
        public function getName() {
            return $this->_name;
        }
    
        public function getModel() {
            return $this->_model;
        }
    }
    
    class Audi extends Car { protected $_name = 'Audi'; }
    class Opel extends Car { protected $_name = 'Opel'; }
    
    class CarsFactory {
        public static function createCars($name, $model) {
            switch($name) {
                case 'Audi':
                    return new Audi($model);
                case 'Opel':
                    return new Opel($model);
            }
        }
    }
    
    $cars[] = CarsFactory::createCars('Audi', 'A6');
    $cars[] = CarsFactory::createCars('Opel', 'Vectra');
    $cars[] = CarsFactory::createCars('Opel', 'insignia');
    
    foreach ($cars as $car) {
        echo $car->getName() . ' ' . $car->getModel() . "<br/>";
    }
    

    which results into

    Audi A6
    Opel Vectra
    Opel insignia
    

    Another way is to inject new Model object into the cars object. This is almost what you have done, but your brand property will not recieve the superclass, but a Model class (or Brand class)

    This way, you can provide interface for iterating or for just printing, in your both objects. Model and Car.

    class Car {
        /*
         * @var Model
         */
        private $_models;
    
        public function setModel(Model $model) {
            $this->_models[] = $model;
        }
    
        public function getModels() {
            return $this->_models;
        }
    
        public function getModelsByCar($car) {
            foreach ($this->getModels() as $model) {
                if ($model->getCarName() == $car) {
                    $models[] = $model;
                }
            }
            return $models;
        }
    
        public function getCarByModel($modelName) {
            foreach ($this->getModels() as $model) {
                if ($model->getModelname() == $modelName) {
                    return $model->getCarName();
                }
            }
        }
    }
    
    class Model {
        private $_carName;
        private $_modelName;
        public function __construct($name, $model) {
            $this->_carName = $name;
            $this->_modelName = $model;
        }
    
        public function getCarName() {
            return $this->_carName;
        }
    
        public function getModelName() {
            return $this->_modelName;
        }
    }   
    
    $cars = new Car();
    $cars->setModel(new Model('Audi', 'A6'));
    $cars->setModel(new Model('Audi', 'V8'));
    $cars->setModel(new Model('Audi', 'A8'));   
    $cars->setModel(new Model('Opel', 'insignia'));
    $cars->setModel(new Model('Opel', 'vectra'));
    
    foreach ($cars->getModels() as $model) {
        echo $model->getCarName() . ' ' .$model->getModelName() . "<br/>";
    }
    
    echo "-----------------------------<br/>";
    
    foreach ($cars->getModelsByCar('Audi') as $model) {
        echo $model->getModelName() . "<br />";
    }
    
    echo "-----------------------------<br/>";
    
    echo $cars->getCarByModel('insignia');
    

    Output:

    Audi A6
    Audi V8
    Audi A8
    Opel insignia
    Opel vectra
    -----------------------------
    A6
    V8
    A8
    -----------------------------
    Opel 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型