Вам нужен отдельный класс для каждого объекта, они не могут быть экземплярами School
. Например, ваш класс School
будет иметь два свойства, name
и subjects
. Тогда у вас будет класс с именем subject
, который содержит имя и число учеников. Обратите внимание, что я использовал слово «субъект» вместо «класс» - это потому, что «класс» является зарезервированным словом в PHP, и даже если бы его не было, было бы очень запутанно, если бы у вас был класс с именем «класс» .
Так что вы можете сделать что-то вроде этого:
<?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 - они представляют собой объекты одного и того же типа. Они могут содержать больше себя, но такая ситуация встречается редко.
Вы имеете дело с двумя различными типами объектов - школой и предметом. Думайте об этом, как о реальном мире - в школе не будет другой школы, в предмете не будет другого предмета, а за пределами школы предмета не будет.
Вы можете продвинуть вышеприведенный пример еще на шаг и создать класс с именем Student
, поскольку это еще один тип района. Студент может содержаться в школе или предмете, но он никогда не будет содержать ни одного из них. Точно так же, скажем, у вас был Book
класс, у ученика мог бы быть такой, у предмета мог бы быть один, или у школы мог бы быть такой. Но в Книге никогда не будет целой Школы - просто нет смысла.
ООП это все об объектах. Думайте об этом с точки зрения реального мира, это поможет вам понять, какие классы вам нужны, и как они могут взаимодействовать друг с другом.