Фреймворк ядра ООП PHP - PullRequest
       11

Фреймворк ядра ООП PHP

5 голосов
/ 24 марта 2012

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

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

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

Когда я нажимаю на проекты, как это должно быть обработано? // домен / бэкэнд / проекты / проекты / или // домен / бэкенд / проекты / список /

Еще один шаг, проект будет содержать несколько изображений или галерею: // домен / бэкенд / проекты / редактировать / 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");
    }
}

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

Ответы [ 3 ]

23 голосов
/ 25 марта 2012

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

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

Что касается исходных примеров URL, галереи будут храниться в БД.Не так ли?И они будут иметь уникальный ID.Что делает это, /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 контроллера:

  1. управление одной галереей
  2. управление одним проектом
  3. работа со списками галерей

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

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

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

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

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

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

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

PS

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

2 голосов
/ 24 марта 2012

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

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

В вашем коде отсутствует несколько ключевых понятий по сравнению с классами ORMS, с которыми я работал (классы гидратации и одноранговой таблицы), поэтому я постараюсь придерживаться вашего кода.Вы можете получить изображения через объект Project, а затем ссылаться на изображения через представление 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, который предоставляет большую часть того, что вы пытаетесь написать, плюс он добавляет недостающие компоненты, о которых я упоминал ранее;гидратация, объектные отношения и классы таблиц, а также многие другие функции, такие как вложенные множества.

0 голосов
/ 24 марта 2012

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

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

}

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

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

...