PHP:让我的对象有孩子

时间:2011-09-05 13:08:08

标签: php class object

如果我之前已经提出过我的问题,我很抱歉。我不知道哪个搜索词符合我的问题。我搜索过'OOP child','PHP object child'等,但我根本没有找到任何线索。

所以,我们走了。我想做这样的事情:

$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->name课程中School这样:

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

我不知道如何制作$object及其子女。

注意:我只是猜测输出。我真的不明白怎么弄它。我受SimpleXMLElement的启发。

编辑:我用$ object替换$ class以防止混淆。

4 个答案:

答案 0 :(得分:2)

OOP'方式'是为每个SchoolSubject设置不同的对象(您不能使用Class,因为它是保留关键字)和{{1 }}。使用特定属性将它们定义为正常:

Student

然后,您可以在Class School { // methods, vars etc } Class Subject { // ... } 中创建Class的新实例,并将它们分配给变量:

School

然后你可以使用以下方式获得科目:

Class School {

    var $subjects;

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

}

$mySchool = new School();

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

希望有所帮助

答案 1 :(得分: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 );

答案 2 :(得分: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)

我知道这一切都不是你想要的,但我希望这些例子可以帮助你更好地了解自己的需求并提出正确的问题。你当前的问题含糊不清:即使我给你字面你所问的是什么,你也不会接受我的回答。

答案 3 :(得分: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的类,因为这是另一种distict类型。学生可能被学校或学科所包含,但它永远不会包含任何学生。同样地,假设您有一个Book课程,学生可以有一个,一个学科可以有一个,或者学校可以有一个。但是一本书永远不会包含整个学校 - 它只是没有意义。

OOP就是对象。从现实世界的角度考虑它,它将帮助您了解您需要什么类,以及它们如何相互作用。