PHP:使我的对象具有子对象

PHP:使我的对象具有子对象,php,class,object,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)

如果我的问题以前已经问过,我很抱歉。我不知道什么搜索词匹配我的问题。我搜索了“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)
    }
  }
}
class School {
  $name = "All Way School";
}
<?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'

?>
结果是这样的:

$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)
    }
  }
}
class School {
  $name = "All Way School";
}
<?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'

?>
查看输出<代码>对象有两个子项:
艺术
法律
,每个子项都有一个子项
学生
。这样,我可以通过
$school->object->law->student
访问law的学生总数。但是,我不知道在我的课堂上写什么。我所知道的是,我只能在我的
学校
课堂上这样做
$school->name

$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)
    }
  }
}
class School {
  $name = "All Way School";
}
<?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'

?>
我不知道如何制作
$object
及其子对象

注意:我只是猜测输出。我真的不知道怎么弄到它。我的灵感来自SimpleXMLElement


编辑:我用$object替换$class以避免混淆。

面向对象的“方法”是为每个
学校
科目
(你不能使用
,因为它是保留关键字)和
学生
。将其定义为普通,并具有特定属性:

Class School {
    // methods, vars etc
}

Class Subject {
    // ...
}
然后,您可以在
学校
中创建
的新实例,并将其分配给变量:

Class School {

    var $subjects;

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

}

$mySchool = new School();

$mySchool->subjects[] = new Subject();
然后,您可以使用以下方法获取主题:

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

希望这有帮助

你可以像给孩子起名字一样给孩子起名字:

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')
       );
   }
}
您可以对
学校类
类执行相同操作,使其包含所有学生

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 );

每个对象都需要一个单独的类,它们可以;不要都是
学校的实例。例如,您的类
学校
将有两个属性,
名称
主题
。然后,您将有一个名为
subject
的类,其中包含一个名称和一组学生。请注意,我使用了“subject”一词而不是“class”——这是因为“class”在PHP中是一个保留词,即使不是,如果有一个名为“class”的类,它也会变得非常混乱

所以你可以这样做:

$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)
    }
  }
}
class School {
  $name = "All Way School";
}
<?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都是XML元素——它们都是相同类型的对象。它们可能包含更多的自身,但这种情况很少见

你正在处理两种不同类型的对象-学校和科目。把它想象成现实世界——一所学校不会包含另一所学校,一个主题不会包含另一个主题,一个主题也不会存在于学校之外

您可以进一步使用上面的示例,创建一个名为
Student
的类,因为这是另一种distict类型。一个学生可能被一所学校或一个学科所包含,但它永远不会包含其中任何一个。同样,假设你有一本
课,一个学生可以有一本,一个科目可以有一本,或者一所学校可以有一本。但是一本书永远不会包含一整所学校——这根本没有意义

OOP是关于对象的。从现实世界的角度考虑一下,它将帮助你理解你需要什么课程,以及它们如何相互作用

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)
如果您不想手动键入每个类,请阅读和使用
\uu set()
/
\uu 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)

我知道这些都不是你想要的,但我希望这些例子能帮助你更好地理解自己的需求,并提出正确的问题。您当前的问题含糊不清:即使我按字面上的意思回答了您的问题,您也不会接受我的答案。

@Dimas:它当然是不同的对象实例,但不一定是不同的对象。因此它不可能像simplexml那样位于一个对象实例中?好吧。我只是想知道为什么simplexml和(对象)类型转换总是使它成为同一个对象实例中的子对象,
SimpleXMLElement
stdClass
+1个极好的答案!请注意,您可以使用“类”作为属性。哦,但是(对象)类型转换在类中不起作用。悲哀的:(我想我必须使用第一种方法。正如我所说的,我不会给你一个解决方案,因为你的问题不清楚。对不起,让我再解释一遍。我想知道的是,如何创建像simplexml这样的对象?你知道,每个simplexml对象都在同一个对象实例中:
SimpleXleElement
SimpleXleElement
不是一个简单的对象.AFAIK如果不使用C中的PHP内部构件,就无法做到这一点。