PHP: сделать мои объекты дочерними - PullRequest
2 голосов
/ 05 сентября 2011

Извините, если мой вопрос уже задавался ранее.Я не знаю, какой критерий поиска соответствует моей проблеме.Я искал «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 детей: art и law, у каждого есть ребенок student.Таким образом, я могу получить доступ к общему числу студентов по закону $school->object->law->student.Но я не знаю, что написать в моем классе.Все, что я знаю, я могу сделать только $school->name в моем School классе, например:

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

Я не знаю, как сделать $object и его потомка.

ПримечаниеЯ просто угадываю вывод.Я действительно не понимаю, как это получить.Я вдохновлен SimpleXMLElement.

Редактировать: я заменяю $ class на $ object, чтобы избежать путаницы.

Ответы [ 4 ]

2 голосов
/ 05 сентября 2011
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)

Если вы не хотите вводить каждый класс вручную, прочитайте о перегрузке в PHP и прекрасных __set() / __get() методах.

Typecasting может быть другим решением, которое подходит:

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

Я понимаю, что все это не то, что вы ищете, но я надеюсь, что эти примеры помогут вам лучше понять ваши собственные потребности и задать правильный вопрос. Ваш текущий вопрос является неопределенным и неясным: даже если бы я дал вам буквально то, что вы спросили, вы не примете мой ответ.

2 голосов
/ 05 сентября 2011

Вы можете сделать ребенка таким же образом, как вы назначили имя:

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 голосов
/ 05 сентября 2011

ООП «путь» будет иметь разные объекты для каждого School, Subject (вы не можете использовать Class, поскольку это зарезервированное ключевое слово) и 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();

Затем вы можете получить предметы, используя:

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

Надеюсь, это поможет

0 голосов
/ 05 сентября 2011

Вам нужен отдельный класс для каждого объекта, они не могут быть экземплярами 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 класс, у ученика мог бы быть такой, у предмета мог бы быть один, или у школы мог бы быть такой. Но в Книге никогда не будет целой Школы - просто нет смысла.

ООП это все об объектах. Думайте об этом с точки зрения реального мира, это поможет вам понять, какие классы вам нужны, и как они могут взаимодействовать друг с другом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...