【问题标题】:PHP array return values only仅 PHP 数组返回值
【发布时间】:2018-03-10 10:10:01
【问题描述】:

我已经开始学习 PHP 面向对象编程。
总的来说,我对 PHP 的经验有限。

我的PHP代码如下:

“汽车”类:

class Cars {
    static $car_specs = array("wheel_count", "name", "color");
    static function set_car_detail() {
        self::$car_specs["wheel_count"] = 4;
        self::$car_specs["name"] = "default";
        self::$car_specs["color"] = "generic";
    }
    static function get_car_detail() {
        return self::$car_specs;
    }
}

然后我试图输出这个:

Cars::set_car_detail();
echo implode(',', Cars::get_car_detail());

回声是:

wheel_count,name,color,4,default,generic

但是我想得到:

4,default,generic

foreach 尝试产生了类似的响应。 我想知道我做错了什么。

【问题讨论】:

  • 这不是 OOP——你应该使用 getter/setter 而不是将每个属性放入 1 个数组中 + 也不需要静态
  • 为什么要在单独的函数中设置细节?将来,您是否打算传递这些值?否则,你为什么不创建已经水合的数组是没有意义的。
  • Cars "class" 根本不是一个类。它更像一个命名空间。避免使用静态成员和方法。它们是具有花哨名称的全局对象。

标签: php arrays oop


【解决方案1】:

您发布的代码根本不是一个类。它只是一堆具有时髦名称的全局函数和变量。尽量避免使用静态属性和方法,因为它们不是 OOP。还要尽量避免公共属性和 getter/setter,因为它们只是变相的过程编程。

Car 类的骨架可能如下所示:

class Car {
    private $wheel_count;
    private $name;
    private $color;

    public function __construct($wheel_count, $name, $color)
    {
        $this->wheel_count = $wheel_count;
        $this->name = $name;
        $this->color = $color;
    }

    public function paint($new_color)
    {
        $this->color = $new_color;
    }

    public function describe()
    {
        return sprintf('%d wheels, %s %s', $this->wheel_count, $this->color, $this->name);
    }
}

对象属性是私有的。封装是 OOP 的关键概念之一。它们在构造函数中设置。构造函数的作用是初始化对象,使其准备好工作。确保构造函数初始化了所有对象的属性并且它不做任何其他事情(在构造函数中没有工作。)

在类中为对您的类有意义的操作创建方法。例如,汽车的轮数永远不会改变,编写一个方法来设置不同的轮数是没有意义的。但是汽车的颜色有时会发生变化,paint() 方法会处理这种情况。

避免编写“getter”(即只返回属性值的方法)。它们表明属于该类的某些代码是在该类之外的某个地方编写的(并且很多时候它在这里和那里和任何地方都重复,只有很小的更改或没有更改)。只要可能且合适,就编写一个使用对象属性生成有用值的方法(而不是编写 getter 让有用值在其他地方计算)。

这就是下面描述的Car 类的使用方式:

$car1 = new Car(4, 'Mazda', 'red');
$car2 = new Car(8, 'big truck', 'blue');

echo($car1->describe());
# 4 wheels, red Mazda

$car1->paint('green');
echo($car1->describe());
# 4 wheels, green Mazda

【讨论】:

  • 谢谢。您的回复提供了最丰富的信息。我确实同意所提供的课程并不是真正的课程……我当时的重点是静态变量和函数的工作方式。
  • 静态属性只是具有复杂名称(和可见性约束)的全局变量。它们不是遗传的;您可以使用 self::$car_specs 从扩展 Cars 的类中访问静态变量 (Cars::$car_specs),但除非您(重新)在子类中声明该属性,否则子类中的 self::$car_specs 是相同的作为Cars::$car_specs。这是一种违反直觉的行为,会导致混乱和错误。静态方法只是具有复杂名称(和可见性约束)的全局函数。
【解决方案2】:

你已经用值初始化了数组,但也许你想用键来初始化它:

static $car_specs = array(
    "wheel_count" => null, 
    "name" => null, 
    "color" => null
);

【讨论】:

  • 我知道这是如何工作的,但不确定为什么与我写的相比?当我只用键初始化一个数组并稍后添加它们值时,我假设我做了一个不好的做法?
  • @AviE.Koenig:当然,你是对的。只是它是“我做错了什么”这个问题的可能答案之一。
【解决方案3】:

既然您已经有了一个key 值数组,为什么不为每个键创建一个对应的values 数组并使用array_combine()

class Cars {
    static $car_specs;

    static function set_car_detail() {
        $keys = array("wheel_count", "name", "color");
        $values = array(4, "default", "generic");

        self::$car_specs = array_combine($keys, $values);
    }

    static function get_car_detail() {
        return self::$car_specs;
    }
}

Cars::set_car_detail();
echo implode(',', Cars::get_car_detail());

【讨论】:

    【解决方案4】:

    有一个专门用于此的不言自明的功能

       static function get_car_detail() {
          return array_values(self::$car_specs);
       }
    

    【讨论】:

    • implode 已经只对数组值进行操作,这不是问题所在
    猜你喜欢
    • 2015-07-27
    • 2020-11-25
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2011-07-13
    相关资源
    最近更新 更多