2011-09-05 78 views
2

對不起,如果我的問題已經問過。我不知道符合我的問題的搜索字詞。我搜索了'OOP孩子','PHP對象孩子'等,但我根本沒有線索。PHP:讓我的對象有孩子

所以,我們走吧。我想讓這樣的事情:

$school = new School; 
var_dump($school); 

並導致這樣的事情:

object(School)#1 (2) { 
    ["name"]=> 
    string(14) "All Way School" 
    ["object"]=> 
    object(School)#2 (2) { 
    ["art"]=> 
    object(School)#3 (1) { 
     ["student"]=> 
     int(25) 
    } 
    ["law"]=> 
    object(School)#4 (1) { 
     ["student"]=> 
     int(30) 
    } 
    } 
} 

看到輸出。 object有2個孩子:artlaw,每個孩子有一個孩子student。這樣,我可以通過$school->object->law->student訪問法律的總學生。但是,我不知道我班上寫什麼。我只知道我只能$school->nameSchool類是這樣的:

class School { 
    $name = "All Way School"; 
} 

我不知道如何使$object和其子。

注:我只是猜測輸出。我真的不明白如何得到它。我受到SimpleXMLElement的啓發。

編輯:我用$對象替換$ class以防止混淆。

回答

2

面向對象「的方式」將是爲每個SchoolSubject不同的對象(不能使用Class,因爲它是一個保留關鍵字)和Student。它們定義爲正常的,具有特殊性能:

Class School { 
    // methods, vars etc 
} 

Class Subject { 
    // ... 
} 

然後,您可以在School創建Class新實例,並將其分配給一個變量:

Class School { 

    var $subjects; 

    function __construct() { 
     $this->subjects = new Array(); 
    } 

} 

$mySchool = new School(); 

$mySchool->subjects[] = new Subject(); 

然後你就可以使用得到的主題:

$mySchool->subjects[1]->name; 

希望幫助

2

你可以讓孩子你分配一個名稱相同的方式:

class School { 
    $name = "All Way School"; 

    public function __construct() { // executed when creating a new School object 
     $this->classes = array(
      'art' => new SchoolClass('art'), 
      'law' => new SchoolClass('law') 
     ); 
    } 
} 

可以爲SchoolClass類做的一樣,使它包含所有的學生;

class SchoolClass { 
    $name; 

    public function __construct($name) { 
     $this->name = $name; // law, art, etc 
     $this->students = array(
      new SchoolStudent(2), 
      new SchoolStudent(5) 
     ); 
    } 
} 

(請注意,你通常不會把學生在這樣的構造硬編碼,而是從數據源加載它們。)

再算上學生例如:

$School = new School(); 
echo count($School->classes['law']->students); 
+0

但是藝術和法律是一個不同的對象,對吧? –

+0

@Dimas:它肯定是一個不同的對象實例,但不一定是一個不同的對象。 – Tomalak

0

您需要爲每個對象分別設置一個類,它們都可以是School的實例。例如,您的類School將有兩個屬性,namesubjects。然後你會有一個名爲subject的課程,其中包含一個名字和一個學生。請注意,我已經使用了「subject」這個詞而不是'class' - 這是因爲'class'是PHP中的一個保留字,即使它不是,如果您有一個名爲'class'的類,它會變得非常混亂。 。

所以,你可能做這樣的事情:

<?php 

    class School { 

    public $name; 
    public $subjects = array(); 

    function __construct ($name) { 
     $this->name = $name; 
    } 

    function addSubject ($subject) { 
     // Adds a new subject object 
     if (is_string($subject)) $subject = new Subject($subject); 
     $this->subjects[$subject->name] = $subject; 
    } 

    function getSubjectByName ($name) { 
     // returns a Subject object or FALSE on failure 
     return (isset($this->subjects[$name])) ? $this->subjects[$name] : FALSE; 
    } 

    function getStudentsBySubjectName ($name) { 
     // returns number of students for a subject or FALSE on failure 
     return (isset($this->subjects[$name])) ? $this->subjects[$name]->numberOfStudents : FALSE; 
    } 

    // ... more methods 

    } 

    class Subject { 

    public $name; 
    public $numberOfStudents; 

    function __construct ($name, $students = 0) { 
     $this->name = $name; 
     $this->numberOfStudents = $students; 
    } 

    // ... more methods 

    } 

    $school = new School('Useless City High'); 
    $school->addSubject(new Subject('Math', 2)); 
    $school->addSubject('Stupidity Studies'); 
    $school->subjects['Stupidity Studies']->numberOfStudents = 65; 
    $school->addSubject(new Subject('Law')); 
    var_dump($school); 

    $math = $school->getSubjectByName('Math'); 
    echo $math->numberOfStudents; // outputs '2' 
    echo $school->getStudentsBySubjectName('Math'); // outputs '2' 

    $stupidity = $school->subjects['Stupidity Studies']; 
    echo $stupidity->numberOfStudents; // outputs '65' 
    echo $school->getStudentsBySubjectName('Stupidity Studies'); // outputs '65' 

    echo $school->getStudentsBySubjectName('Law'); // outputs '0' 
    echo $school->subjects['Law']->numberOfStudents; // outputs '0' 

?> 

雖然你可以在包含多個實例單個類寫這篇文章,它不會使語義意義在這種情況下這樣做。

SimpleXML元素是一個包含自身實例的子對象的對象。這是因爲這就是XML的工作原理 - 任何元素都可以包含任何其他元素(在合理範圍內)。例如。你可以有<div><div><div>Some Data</div></div></div>,但同樣你可以只有<div>Some Data</div>。所有這些div都是XML元素 - 它們都是相同類型的對象。他們可能包含更多自己,但這種情況很少。

您正在處理2種不同類型的對象 - 學校和科目。把它想象爲真實的世界 - 一所學校不會包含另一所學校,一個學校不會包含另一個學科,並且一個學科不會存在於學校之外。

您可以將上述示例更進一步,並創建一個名爲Student的類,因爲這是另一種類型。學生可能被學校或學科包含,但它不會包含任何一個學生。同樣,假設你有一個Book班,一個學生可以有一個,一個學科可以有一個,或者一個學校可以有一個。但是一本書永遠不會包含整個學校 - 它只是沒有意義。

OOP是關於對象的。從現實世界的角度思考它,它會幫助你理解你需要什麼類,以及它們如何相互交互。

+0

因此它不能在像simplexml這樣的一個對象實例中嗎? –

+0

看我上面的編輯 – DaveRandom

+0

好吧。我只是想知道爲什麼simplexml和(object)類型轉換總是使它在同一個對象實例中,即SimpleXMLElement和stdClass。 –

2
class School { 
    public $name, $class; 
    public function __construct() { 
     $this->class = new SchoolClass(); 
     $this->name = "All Way School"; 
    } 
} 

class SchoolClass { 
    public $art, $law; 
    public function __construct() { 
     $this->art = new SchoolStudent(25); 
     $this->law = new SchoolStudent(30); 
    } 
} 

class SchoolStudent { 
    public $student; 
    public function __construct($student) { 
     $this->student = $student; 
    } 
} 

$school = new School(); 

var_dump($school); 
var_dump($school->class->law->student); 

會給你正是這一點:

object(School)#1 (2) { 
    ["name"]=> 
    string(14) "All Way School" 
    ["class"]=> 
    object(SchoolClass)#2 (2) { 
    ["art"]=> 
    object(SchoolStudent)#3 (1) { 
     ["student"]=> 
     int(25) 
    } 
    ["law"]=> 
    object(SchoolStudent)#4 (1) { 
     ["student"]=> 
     int(30) 
    } 
    } 
} 
int(30) 

如果你不想通過手動輸入每一個類,閱讀overloading in PHP和美麗__set()/__get()方法。

鑄字可以是適合其他的解決辦法:

$school = (object) array(
    "name" => "All Way School", 
    "object" => (object) array(
    "art" => (object) array("student" => 25), 
    "law" => (object) array("student" => 30), 
), 
); 
var_dump($school); 
var_dump($school->object->law->student); 

,讓你

object(stdClass)#4 (2) { 
    ["name"]=> 
    string(14) "All Way School" 
    ["object"]=> 
    object(stdClass)#3 (2) { 
    ["art"]=> 
    object(stdClass)#1 (1) { 
     ["student"]=> 
     int(25) 
    } 
    ["law"]=> 
    object(stdClass)#2 (1) { 
     ["student"]=> 
     int(30) 
    } 
    } 
} 
int(30) 

我明白,這一切是不是你要找的東西,但我希望這些例子幫助你更好地理解你自己的需求並提出正確的問題。你目前的問題含糊不清:即使我給你字面上的你問了什麼,你不會接受我的答案。

+0

+1優秀的答案!請注意,您可以使用「class」作爲屬性。 – Herbert

+0

+1我喜歡類型轉換的方式。非常非常好的答案! –

+0

哦,但(對象)類型轉換在類中不起作用。傷心:( 我想我一定要用第一種方法 –