2017-09-28 94 views
0

我已經開始學習PHP面向對象編程。
我對PHP的使用經驗有限。PHP數組返回值只有

我有PHP代碼如下:

A 「汽車」 類:

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 

但是, m試圖得到:

4,default,generic 

foreach嘗試產生了類似的迴應。 我想了解我做錯了什麼。

+2

這不是OOP-你應該使用的getter/setter,而不是把所有的財產爲1個陣列+也沒有必要的靜態 –

+0

可能的複製的[PHP - 合併兩個數組(相同長度)爲一個關聯?](https://stackoverflow.com/questions/1200885/php-merge-two-arrays-same-length-into-one-associative) – War10ck

+0

爲什麼你在一個單獨的函數中設置細節?未來,你打算通過這些價值觀嗎?否則,爲什麼你不創建已經水合的陣列是沒有意義的。 – War10ck

回答

1

您發佈的代碼根本不是課程。它只是一堆全球性的函數和變量,帶有時髦的名字。儘量避免靜態屬性和方法,因爲它們不是OOP。同時儘量避免公共財產和獲取/設置者,因爲它們只是僞裝的程序性編程。

一個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的關鍵概念之一。它們在構造函數中設置。構造函數的作用是初始化對象,使其可以工作。確保構造函數初始化所有對象的屬性,並且不執行任何操作(構造函數中沒有任何工作)。

在類中爲您的類創建適當的操作。例如,汽車車輪的數量永遠不會改變,因此寫一種方法來設置不同數量的車輪是沒有意義的。但是汽車的顏色有時會改變,並且方法會處理該問題。

避免編寫「getters」(即與返回屬性值無關的方法)。他們是這樣一種信號:屬於這個類的某些代碼是寫在課程以外的某個地方(很多時候它在這裏和那裏以及在任何地方都被複制,只是很少或根本沒有變化)。只要有可能和適當,寫一個方法使用對象的屬性來生成一個有用的值(而不是編寫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 
+0

謝謝你,你的回覆是最豐富的。 我同意所提供的類不是真的類......我的重點是當時靜態變量和函數如何工作。 –

+0

靜態屬性只是具有複雜名稱(和可見性約束)的全局變量。他們不是遺傳的;你可以使用'self :: $ car_specs'從一個擴展'Cars'的類訪問一個靜態變量('Cars :: $ car_specs'),但除非你在子類中聲明瞭屬性'self: :子類中的$ car_specs'和'Cars :: $ car_specs'是一樣的。這是一種反直覺行爲,會導致混淆和錯誤。靜態方法只是具有複雜名稱(和可見性約束)的全局函數。 – axiac

0

有一個不言自明的功能,專爲

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

'implode'已經只在數組值上運行,這不是問題在這裏 – iainn

2

你已經初始化值的陣列,但也許你想用鑰匙將其初始化:

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

我看到這是如何工作,但不確定爲什麼比較我寫的? 我假設我做了一個壞習慣,當我只用鍵初始化一個數組,然後添加它們的值? –

+0

@ AviE.Koenig:當然,你是對的。只是這是「我做錯了什麼」這個問題的可能答案之一。 – Walrus

1

既然你已經有一個爲什麼你不爲每個密鑰創建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());