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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?