Модель Page страницы, Вопрос по созданию и взаимодействию с моделью Страница

codrilla

Новичок
Здравствуйте.
Берём простой случай. Требования к сайту:
- динамическая генерация страниц
- блок новостей
То есть по идее должны быть две CRUD модели. Понятно, что редактирование, обновление и удаление доступно админу, чтение - всем пользователям.
Вопросы в следующем:
1) как правильно организовать модели и контроллеры?
2) как взаимодействовать с базой?

Все запросы будут отправляться файлу index.php, в нём создаваться экземпляр класса Route, в котором вызывается метод start
PHP:
static function start($mRequestUri)
        {
            // контроллер и действие по умолчанию
            $controller_name = 'Page';
            $action_name = 'index';           
            
            $routes = explode('/', $mRequestUri);
    
            // получаем имя контроллера
            if ( !empty($routes[1]) )
            {	
                $controller_name = $routes[1];
            }
            
            // получаем имя экшена
            if ( !empty($routes[2]) )
            {
                $action_name = $routes[2];
            }
    
            // добавляем префиксы
            $model_name = 'Model_'.$controller_name;
            $controller_name = 'Controller_'.$controller_name;
            $action_name = 'action_'.$action_name;
    
            // подцепляем файл с классом модели (файла модели может и не быть)
    
            $model_file = strtolower($model_name).'.php';
            $model_path = "application/models/".$model_file;
            if(file_exists($model_path))
            {
                include "application/models/".$model_file;
            }
    
            // подцепляем файл с классом контроллера
            $controller_file = strtolower($controller_name).'.php';
            $controller_path = "application/controllers/".$controller_file;
            if(file_exists($controller_path))
            {
                include "application/controllers/".$controller_file;
            }
            else
            {
                /*
                правильно было бы кинуть здесь исключение,
                но для упрощения сразу сделаем редирект на страницу 404
                */
                Route::ErrorPage404();
            }
            
            // создаем контроллер
            $controller = new $controller_name;
            $action = $action_name;
            
            if(method_exists($controller, $action))
            {
                // вызываем действие контроллера
                $controller->$action();
            }
            else
            {
                // здесь также разумнее было бы кинуть исключение
                Route::ErrorPage404();
            }
        
        }
Контроллер страницы вероятно должен выглядеть следующим образом
PHP:
class Controller_Page extends Controller {
        
        function __construct()
    	{
    		$this->model = new Model_Page();
    		$this->view = new View();
    	}
        
        function action_index()
    	{
    		$data = $this->model->get_data();		
    		$this->view->generate('index_view.php', 'template_view.php', $data);
    	}
        
    }
Класс Модели
PHP:
 class Model
    {
        public function get_data()
        {
        }
    }
Для упрощения модель страницы описал так
PHP:
<?php
    class Model_Page extends Model {
        function get_data() {
            $mysqli = new mysqli('localhost', 'root', 'pass', 'dbname');
            $result = $mysqli->query("SELECT * FROM ru_pages WHERE id=1");
            $row = $result->fetch_object();
            return array ('title' => $row->title);
            $result->close();
        }
    }
Еще раз вопросы:
как правильно организовать модель и контроллер?
как вытащить обращение к базе в отдельный класс?
 

radioheaded

PHP нуб
Еще раз: нет никакого «правильно» и «неправильно». Есть «выполняет поставленную задачу» и «не выполняет».

Нужны варианты — посмотрите существующие фреймворки (а лучше используйте один из них и не изобретайте еще один).
Про класс работы с БД не понял вопроса. Что значит, как вытащить?
 

codrilla

Новичок
Еще раз: нет никакого «правильно» и «неправильно». Есть «выполняет поставленную задачу» и «не выполняет».
Правильно = Выполняет поставленную задачу. Задачу постарался описать.
Про класс работы с БД не понял вопроса. Что значит, как вытащить?
Есть файл bootstrap.php, который инклудится в index.php. Хочу в нём написать
PHP:
$mysqli = new mysqli('localhost', 'root', 'pass', 'dbname');
Route::start(mRequestUri);
А в модели уже эту строчку не использовать.
 

radioheaded

PHP нуб
Правильно = Выполняет поставленную задачу. Задачу постарался описать.
Тогда вам виднее, вы же автор и задачи, и кода. Если код не работает, то задавайте конкретные вопросы по проблемным местам.

Есть файл bootstrap.php, который инклудится в index.php. Хочу в нём написать
PHP:
$mysqli = new mysqli('localhost', 'root', 'pass', 'dbname');
Route::start(mRequestUri);
А в модели уже эту строчку не использовать.
Для начала можете и так делать, хотя это плохо. Но почему именно плохо никто вам объяснить нормально не сумеет, точнее, на каждое объяснение вы найдете свои «но». Просто делайте дальше, усложняйте логику и постепенно сами увидите, как вот эта ваша реализация начнет вам мешать и выглядеть жутко.
 

codrilla

Новичок
Для начала можете и так делать, хотя это плохо. Но почему именно плохо никто вам объяснить нормально не сумеет, точнее, на каждое объяснение вы найдете свои «но». Просто делайте дальше, усложняйте логику и постепенно сами увидите, как вот эта ваша реализация начнет вам мешать и выглядеть жутко.
Проблема в том, что вот так
PHP:
$mysqli = new mysqli('localhost', 'root', 'pass', 'dbname');
Route::start(mRequestUri);
не работает. Я потому и спрашиваю. А писать подключение к базе в данной модели глупо, так как у меня используется для подключения следующая конструкция.
PHP:
 if(is_string($config))
        $config=require($config);
        $mysqli = new mysqli($config["db"]['host'], $config["db"]['username'], $config["db"]['passwd'], $config["db"]['dbname']);
Дублировать это в каждой модели нерационально.
 

radioheaded

PHP нуб
Вот видите, вы уже сталкиваетесь с неудобством. Давайте придумаем, как можно не дублировать этот код. Может быть, написать класс со статическим методом, который будет возвращать это подключение? Или класс, который в конструктор будет принимать конфиг, разбирать его, создавать подключение и отдавать его динамическим геттером? Попробуйте. Как только снова станет неудобно — возвращайтесь.
 

codrilla

Новичок
Может быть, написать класс со статическим методом, который будет возвращать это подключение?
Я понимаю жто так: мы будем в классе модели Model где нибудь в конструкторе вызывать DbConnection со статическим методом connect. Вопрос в том, как этот метод узнает о содержимой переменной конфиг. Мне это непонятно
PHP:
    class DbConnection {
        static function connect () {
            $mysqli = new mysqli($host, $username, $passwd, $dbname);
            return $mysqli;
        }
    }

    class Model extends DbConnection {
        public $mysqli;
        function __construct() {
            $this->mysqli = DbConnection::connect();
        }
        public function get_data()
        {
        }
    }
Как определить эти переменные $host, $username, $passwd, $dbname из конфига. Да, можно их прописать непосредственно в самом классе, но хочется вынести всю конфигурацию в отдельный файл вроде
PHP:
return array (
        "lang" => array ('ru', 'en'),
        "db" => array (
                    'host' => 'localhost',
                    'username' => 'username',
                    'passwd' => 'pass',
                    'dbname' => 'dbname',
                    
                    ),
                );
Или класс, который в конструктор будет принимать конфиг, разбирать его, создавать подключение и отдавать его динамическим геттером
А вот с этим что-то не совсем непонятно.
PHP:
class DbConnection {
        
        private $config = aaray();

        public __construct($config) {
                 if(is_string($config))
                          $this->config=require($config);
                 
        }
        
        public function connect() {
                return $mysqli = new mysqli($this->config["db"]['host'], $this->config["db"]['username'], $this->config["db"]['passwd'], $this->config["db"]['dbname']);
        }

        /*здесь непонятно что делать геттерами и сеттерами...*/
}
И опять же непонятно, в какой момент вызывать этот класс.
 

radioheaded

PHP нуб
Мне непонятно, с чем конкретно у тебя проблемы. Сначала было понятно: хотелось избавиться от копипасты. Ты написал пару штук, которые более-менее это решают. Теперь в чем проблема?
 

codrilla

Новичок
Вы написали
которые более-менее это решают
Но не решают. Проблема осталась в следующем
Как определить эти переменные $host, $username, $passwd, $dbname из конфига. Да, можно их прописать непосредственно в самом классе, но хочется вынести всю конфигурацию в отдельный файл вроде
Конфиг разбирается в bootstrap.php. Как передать эти переменные в класс соединения с бд - непонятно.
 

radioheaded

PHP нуб
Зачем разбирать конфиг где-то кроме того места, где он реально нужен? Чем не устраивает второй вариант с передачей конфига в конструктор?
 

codrilla

Новичок
Чем не устраивает второй вариант с передачей конфига в конструктор?
1) в конфиге содержится информация не только о подключении к бд
2) я так и не понял как пользоваться вторым вариантом с геттерами и сеттерами, как их использовать и где вызывать класс?
 

radioheaded

PHP нуб
1) в конфиге содержится информация не только о подключении к бд
2) я так и не понял как пользоваться вторым вариантом с геттерами и сеттерами, как их использовать и где вызывать класс?
Такой конфиг не нужен. Не надо запихивать все возможные настройки в одно место. Посмотрите все же на реализацию в одном из фреймворков, сразу легче станет.

Зачем вам там геттеры и сеттеры? Вам пока что (если я правильно понял из примеров) нужно только выполнять query. Так вот получайте объект коннекта и вызывайте у него query.
 

codrilla

Новичок
PHP:
Такой конфиг не нужен. Не надо запихивать все возможные настройки в одно место. Посмотрите все же на реализацию в одном из фреймворков, сразу легче станет.
Ну я и смотрю на yii там как раз такой конфиг.
PHP:
Зачем вам там геттеры и сеттеры?
Ну про них вы сами выше написали.
Буду дальше разбираться с yii. Спасибо за помощь.
 

radioheaded

PHP нуб
Ну про них вы сами выше написали.
Я писал про геттер коннекта ) В вашем примере это метод connect.

Если храните все в одном огромном массиве, то передавайте в класс только нужную часть. Еще лучше — класс конфига. Еще лучше — отдельный класс конфига для БД.
 
Сверху