Основная структура PHP OOP

Я просто отправляю этот вопрос, чтобы некоторые из вас могли правильно указать мне. Я медленно прогрелюсь до ООП, начинаю понимать концепцию. Я хочу создать хорошее твердое ядро ​​или основу для использования в качестве CMS-сервера. Он также будет использовать MVC. Я использовал http://gilbitron.github.com/PIP/ в качестве базы MVC.

То, что я не могу понять, следующее:

Скажем, на странице проекта в бэкэнд у меня есть 2 раздела: htmltext и проекты, и я должен иметь возможность редактировать их оба. Ури будет примерно таким: //domain/backend/projects (метод будет индексом и покажет 2 раздела)

Когда я нажимаю на проекты, как это следует обрабатывать? //domain/backend/projects/projects/or // домен/Серверные/проекты/список/

Еще один шаг: проект будет содержать некоторые изображения или галерею: // домен/бэкенд/проекты/редактировать/5/галерея/2

Мой вопрос здесь, во-первых: будет ли это хорошим способом пойти и еще более важно, как это будет реализовано в ООП

главный контроллер проектов:

class projects {

    function index(){
        // view index
    }

    function edit{
        $project = new Project();
        $projectdata = $project->load(5);
    }
}

Один контроллер проекта

class project {

    function __construct(){
        $this->projectmodel = $this->loadModel('project_model'); // prepare the model to be used
    }

    function load($id){
        $this->projectmodel->loadproject($id);
    }
}

модель проекта

class project_model extends model { //extends for DB  access and such

    function __construct(){
        // do stuff
    }

    function loadproject($id){
        return $this->db->query("SELECT * FROM projects where id=" . $id . " LIMIT 1");
    }
}

Теперь мой вопрос. Если в этом проекте есть изображения, где я должен загрузить класс изображений для их обработки? Должен ли я загрузить его в project_model, например $this- > images = new Images(); и имеют функцию внутри модели

function loadimages($id){
    $this->images->load($id);
}

а затем изображения будут выглядеть примерно так:

class image extends model { //extends for DB  access and such 

    function __construct(){
    }

    function load($id){
        return $this->db->query("SELECT * FROM project_images where id=" . $id . " LIMIT 1");
    }
}

Кажется, что контроллеры и модели путаются таким образом. Но логичным способом проект является контейнером, который содержит projectinfo, который может представлять собой текст, изображения и, возможно, видео. Как я тоже собираюсь установить это логически.

Ответ 1

Оригинальный вопрос

Первая часть, о URL-адресах, называется: Routing или Dispatching. Существует неплохая статья об этом в связи с Symfony 2.x, но идея, стоящая за ней, важна. Кроме того, вы можете посмотреть, как реализуют другие среды.

Что касается ваших исходных примеров URL, галереи будут храниться в БД. Не так ли? И они будут иметь уникальный идентификатор. Что делает это, /backend/projects/edit/5/gallery/2 совершенно бессмысленным. Вместо этого ваш URL должен выглядеть больше:

/backend/gallery/5/edit         // edit gallery with ID 5
/backend/project/3              // view project with ID 3
/backend/galleries/project/4    // list galleries filtered by project with ID 4

URL должен содержать только информацию, которая вам нужна действительно.

Это также указывает на 3 контроллера:

  • Управление отдельными галереями
  • управление отдельными проектами
  • со списками галерей

И пример URL-адресов будет иметь аналогичный шаблон:

/backend(/:controller(/:id|:page)(/:action(/:parameter)))

Если часть /backend обязательна, но controller является необязательной. Если контроллер найден, то id (или страница, когда вы работаете со списками) и action является необязательным. Если действие найдено, дополнительный parameter является необязательным. Эта структура позволит вам заниматься большинством ваших маршрутов, если они написаны как регулярные выражения.

ООП вне классов

Прежде чем приступать к использованию или написанию своего рода фреймворка PHP, вы должны научиться писать правильный объектно-ориентированный код. И это не значит "умеет писать класс". Это означает, что вы должны действительно понимать, что такое объектно-ориентированное программирование, на каких принципах оно основано, на каких распространенных ошибках люди делают и каковы наиболее распространенные заблуждения. Вот несколько лекций, которые помогут вам в этом:

Это должно дать вам некоторое представление о предмете.. да, его много. Но подозреваю, что вы предпочтете видео по книгам. В противном случае некоторые материалы для чтения:

Вы заметите, что многие материалы являются языковыми-агностиками. Это потому, что теория для объектно-ориентированных языков на основе классов одинакова.

P.S.

Будьте осторожны с ключевым словом extends в вашем коде. Это означает, что -. Это нормально, если class Oak extends Tree, потому что все дубы - это деревья. Но если у вас class User extends Database, кто-то может обидеться. На самом деле существует принцип ООП, который говорит об этом: Принцип подстановки Лискова.. также есть очень краткое объяснение

Ответ 2

Если у этого проекта есть изображения, где я должен загрузить класс изображения для их обработки? Должен ли я загрузить его в project_model, например $this- > images = new Images(); и имеют функцию внутри модели

Да. Целью модели является инкапсуляция бизнес-логики, так что вам нужно только один раз написать алгоритмы и поделиться ими несколько раз. Что бы я сделал, если бы я был вами, это добавить метод getImages() к модели проекта, поскольку изображения являются прямым атрибутом проекта, что делает его таким, чтобы каждый проект знал, как получить его собственные изображения.

В коде отсутствует несколько ключевых концепций по сравнению с ORMS, с которыми я работал (классы гидратации и одноранговой сети), поэтому я попытаюсь придерживаться вашего кода. Вы можете получить изображения через объект "Проект", а затем ссылаться на изображения с помощью вида 1 из 2 способов:

// Controller
$this->project = new Project();
$this->projectImages = $project->getImages(); // Implemenation #2

// View

// Implemenation #1 (reference to object initialized in controller)
<?php foreach ($project->getImages() as $image): ?>
<img src="<?php echo $image['path'] ?>" />
<?php endforeach ?>

// Implemenation #2 (reference to separate variable initialized in controller)
<?php foreach ($projectImages as $image): ?>
<img src="<?php echo $image['path'] ?>" />
<?php endforeach ?>

Выше только демонстративное, но должно дать вам представление. Я бы посоветовал вам взглянуть на Doctrine. Это проверенная и стабильная ORM, которая обеспечивает большую часть того, что вы пытаетесь написать, плюс добавляет недостающие компоненты, о которых я упоминал ранее; гидратация, объектные отношения и классы таблиц, а также многие другие функции, такие как вложенные наборы.

Ответ 3

(так как вопрос был достаточно продолжительным сам по себе, я не хотел его расширять, поэтому я добавил это как ответ)

projects.php этот контроллер расширяет контроллер проекта. основная задача состоит в том, чтобы обрабатывать несколько getAllProjects(), используя свою собственную модель, а затем передать ее на контроллер проекта getProject()

class Projects extends Project{

public function __construct()
{
    parent::__construct();
    $this->projects_model = new Projects_model();
}       

public function getAllProjects()
{
    $res = $this->projects_model->getAllProjects();     
    if($res) foreach($res as $v) $projects[] = $this->getProject($v);

    return $projects;
}
}

project.php
project_model делает не что иное, как получение проектных данных и связанных с ними данных, таких как изображения

class Project{

public function __construct()
{
    $this->project_model = new Project_model;
    $this->images = new Images();
}


public function getProject($data=NULL)
{
    if($data==NULL) $data = $this->project_model->loadProject($data['id']);
    $images = $this->project_model->loadProjectImages($data['id']);

    return array('project_id' => $data, 'project' => $data, 'images' => $images);
}   


public function getProjectByID($id)
{
    $data = $this->project_model->loadProject($id);
    return getProject($data);
}   

}

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

Является ли это хорошим (и правильным) подходом к работе? Или было бы лучше объединить все это в один контроллер и один класс модели?