PEQUEÑO MVC para PHP -- php campo con object-oriented campo con mvc campo con library camp codereview Relacionados El problema

Small MVC for PHP


3
vote

problema

Español

La siguiente es una nueva pregunta basada en respuestas desde aquí: Pequeña plantilla de MVC PHP

He escrito una pequeña biblioteca de plantillas de MVC que me gustaría algunas críticas.

La biblioteca es ubicado aquí

Si está buscando dónde comenzar, consulte los archivos en la lib directorio.

Realmente me encantaría escuchar tus críticas:

  • calidad de código
  • Claridad de código
  • cómo mejorar
  • Cualquier otra cosa que necesita expansión de aclaración, etc.

Estoy más interesado en lo que estoy haciendo mal que el derecho.
El readme no está completo y hay Mucho más funcionalidad de lo que se documenta, si tiene alguna pregunta, pregúnteme.

Cualquier opinión sobre la utilidad real de la biblioteca es bienvenida.


Ejemplos de código (todo el código es igual, justo en mi última pregunta que me pidieron algunos fragmentos):

Bootstrap.php :

  <?php /**  * The main library for the framework  */ namespace SmallFrylib;  class_alias('SmallFrylibMySQL_Interface', 'SmallFrylibMySQL'); // MySQL class to be deprecated /**  * Description of Bootstrap  *  * @author nlubin  */ Class Bootstrap {      /**      *      * @var SessionManager      */     private $_session;     /**      *      * @var stdClass      */     private $_path;     /**      *      * @var AppController      */     private $_controller;     /**      *      * @var Template      */     private $_template;      /**      *      * @var Config      */     private $CONFIG;      /**      * @param Config $CONFIG       */     function __construct(Config $CONFIG) {         $this->CONFIG = $CONFIG;         $this->CONFIG->set('page_title', $this->CONFIG->get('DEFAULT_TITLE'));         $this->CONFIG->set('template', $this->CONFIG->get('DEFAULT_TEMPLATE'));         $this->_session = new SessionManager($this->CONFIG->get('APP_NAME'));         $this->_path = $this->readPath();         $this->_controller = $this->loadController();         $this->_template = new Template($this->_path, $this->_session, $this->_controller, $this->CONFIG); //has destructor that controls it         $this->_controller->displayPage($this->_path->args);   //run the page for the controller         $this->_template->renderTemplate($this->_path->args); //only render template after all is said and done     }      /**      * @return stdClass      */     private function readPath(){         $default_controller = $this->CONFIG->get('DEFAULT_CONTROLLER');         $index = str_replace("/", "", SmallFryConfigINDEX);          //use strtok to remove the query string from the end fo the request         $request_uri = !isset($_SERVER["REQUEST_URI"]) ? "/" : strtok($_SERVER["REQUEST_URI"],'?');;         $request_uri = str_replace("/" . $index , "/", $request_uri);          $path = $request_uri ?: '/'.$default_controller;         $path = str_replace("//", "/", $path);          $path_info = explode("/",$path);          $page = isset($path_info[2]) ? $path_info[2] : "index";         list($page, $temp) = explode('.', $page) + array("index", null);         $model = $path_info[1] ?: $default_controller;          $obj = (object) array(             'path_info' => $path_info,             'page' => $page,             'args' => array_slice($path_info, 3),             'route_args' => array_slice($path_info, 2),   //if is a route, ignore page             'model' => $model         );          return $obj;     }      /**      * @return AppController      */     private function loadController(){         $this->CONFIG->set('page', $this->_path->page);          //LOAD CONTROLLER         $modFolders = array('images', 'js', 'css');          //load controller         if(strlen($this->_path->model) == 0) $this->_path->model = $this->CONFIG->get('DEFAULT_CONTROLLER');          //find if is in modFolders:         $folderIntersect = array_intersect($this->_path->path_info, $modFolders);          if(count($folderIntersect) == 0){ //load it only if it is not in one of those folders             $controllerName = "{$this->_path->model}Controller";             $app_controller = $this->create_controller($controllerName);              if(!$app_controller)    {                 $route = $this->CONFIG->getRoute($this->_path->model);                 if($route)  {   //try to find route                     $this->_path->page = $route->page;                     $this->CONFIG->set('page', $route->page);   //reset the page name                     $this->_path->args = count($route->args) ? $route->args : $this->_path->route_args;                     $app_controller = $this->create_controller($route->controller);                     if(!$app_controller) {                         //show nothing                          header("HTTP/1.1 404 Not Found");                         exit;                     }                 }                 else    {                     //show nothing                      header("HTTP/1.1 404 Not Found");                     exit;                 }             }             return $app_controller;         }         else {  //fake mod-rewrite             $this->rewrite($this->_path->path_info, $folderIntersect);         }         //END LOAD CONTROLLER     }      /**      * @param string $controllerName      * @return AppController       */     private function create_controller($controllerName) {          $useOldVersion = !$this->CONFIG->get('DB_NEW');         $mySQLClass = "SmallFrylibMySQL_PDO";         if($useOldVersion)  {             $mySQLClass = "SmallFrylibMySQL_Improved";         }         //DB CONN         $firstHandle = null;         $secondHandle = null;         //Primary db connection         $database_info = $this->CONFIG->get('DB_INFO');         if($database_info)  {         $firstHandle = new $mySQLClass($database_info['host'], $database_info['login'],                     $database_info['password'], $database_info['database'], $this->CONFIG->get('DEBUG_QUERIES'));         }         else    {             exit("DO NOT HAVE DB INFO SET");         }          //Secondary db connection         $database_info = $this->CONFIG->get('SECONDARY_DB_INFO');         if($database_info)  {             $secondHandle = new $mySQLClass($database_info['host'], $database_info['login'],                                     $database_info['password'], $database_info['database'], $this->CONFIG->get('DEBUG_QUERIES'));         }         //END DB CONN          $nameSpacedController = "SmallFry\Controller\$controllerName";         if (class_exists($nameSpacedController) && is_subclass_of($nameSpacedController, __NAMESPACE__.'AppController')) {               $app_controller  = new $nameSpacedController($this->_session, $this->CONFIG, $firstHandle, $secondHandle);          } else {             return false;         }         return $app_controller;     }      /**      * @param array $path_info      * @param array $folderIntersect       */     private function rewrite(array $path_info, array $folderIntersect){          $find_path = array_keys($folderIntersect);         $find_length = count($find_path) - 1;         $file_name = implode(DIRECTORY_SEPARATOR,array_slice($path_info, $find_path[$find_length]));          $file = SmallFryConfigDOCROOT."webroot".DIRECTORY_SEPARATOR.$file_name;          if(is_file($file)){ //if the file is a real file             header("Last-Modified: " . date("D, d M Y H:i:s", getlastmod()));             include SmallFryConfigBASEROOT.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.'mime_type.php'; // needed for setups without `mime_content_type`             header('Content-type: ' . mime_content_type($file));             readfile($file);         }         else {             header("HTTP/1.1 404 Not Found");         }         exit;     } }   

AppController.php3 :

  <?php namespace SmallFrylib; /**  * Description of AppController  *  * @author nlubin  */ class AppController {      private $pageOn;     protected $name = __CLASS__;     protected $helpers = array();     protected $validate = array();     protected $posts = array();     protected $session;     protected $validator;     protected $template;     protected $CONFIG;      /**      *      * @param SessionManager $SESSION      * @param Config $CONFIG      * @param MySQL_Interface $firstHandle      * @param MySQL_Interface $secondHandle       */     public function __construct(SessionManager $SESSION, Config $CONFIG, MySQL_Interface $firstHandle, MySQL_Interface $secondHandle = null) {          $this->CONFIG = $CONFIG;         $this->pageOn = $this->CONFIG->get('page');         $this->session = $SESSION;         $model_name = isset($this->modelName) ? $this->modelName : $this->name;      /* Build the AppModel */         $this->$model_name = &AppModelFactory::buildModel($model_name, $CONFIG, $firstHandle, $secondHandle);      /* Get all posts */         $this->posts = $this->$model_name->getPosts();          $this->CONFIG->set('view', strtolower($model_name));          if(!$this->session->get(strtolower($model_name))){             $this->session->set(strtolower($model_name), array());         }      }      private function getPublicMethods(){         $methods = array();         $r = new ReflectionObject($this);         $r_methods = $r->getMethods(ReflectionMethod::IS_PUBLIC);         $notAllowedMethods = array("__construct", "init", "__destruct"); //list of methods that CANNOT be a view and are `keywords`         foreach($r_methods as $method){             if($method->class !== 'SmallFrylibAppController' && !in_array($method->name, $notAllowedMethods)){                  //get only public methods from extended class                 $methods[] = $method->name;             }         }         return $methods;     }      /**      *      * @param Template $TEMPLATE       */     public function setTemplate(Template $TEMPLATE){         $this->template = $TEMPLATE;         $this->setHelpers();     }      /**      * Function to run before the constructor's view function      */     public function init(){} //function to run right after constructor      /**      * Show the current page in the browser      *      * @param array $args      * @return string       */     public function displayPage($args)  {         $this->CONFIG->set('method', $this->pageOn);         $public_methods = $this->getPublicMethods();         if(in_array($this->pageOn, $public_methods))    {               call_user_func_array(array($this, $this->pageOn), $args);         }         else    {             if(!in_array($this->pageOn, $public_methods))   {                 header("HTTP/1.1 404 Not Found");             }             else {                 $this->CONFIG->set('method', '../missingfunction'); //don't even allow trying the page                 return($this->getErrorPage($this->CONFIG->get('view')."/{$this->pageOn} does not exist."));             }             exit;         }     }      /**      *      * @return string       */     function index() {}      /**      *      * @param string $msg      * @return string       */     protected function getErrorPage($msg = null)    {         $err = '<div class="error errors">%s</div>';         return sprintf($err, $msg);     }      protected function setHelpers(){         $helpers = array();         foreach($this->helpers as $helper){             $help = "{$helper}Helper";             $nameSpacedHelper = "SmallFry\helper\$help";             if(class_exists($nameSpacedHelper) && is_subclass_of($nameSpacedHelper, 'SmallFry\helper\Helper')){                 $this->$helper = new $nameSpacedHelper();                 $helpers[$helper] = $this->$helper;             }         }         $this->template->set('helpers', (object) $helpers);     }      protected function logout(){         session_destroy();         header('Location: '.WEBROOT.'index.php');         exit;     }      /**      *      * @param array $validate      * @param array $values      * @param boolean $exit      * @return boolean       */     protected function validateForm($validate = null, $values = null, $exit = true){          $this->validator = new FormValidator(); //create new validator          if($validate == null){             $validate = $this->validate;         }          foreach($validate as $field => $rules){             foreach($rules as $validate=>$message){                 $this->validator->addValidation($field, $validate, $message);             }         }          return $this->doValidate($values, $exit);     }      protected function doValidate($values = null, $exit = true){         if(!(!isset($_POST) || count($_POST) == 0)){             //some form was submitted             if(!$this->validator->ValidateForm($values)){                 $error = '';                 $error_hash = $this->validator->GetErrors();                 foreach($error_hash as $inpname => $inp_err)                 {                   $error .= $inp_err.PHP_EOL;                 }                 return $this->makeError($error, $exit);                             }         }         return true;     }      protected function makeError($str, $exit = true){         $return = $this->getErrorPage(nl2br($str));         if($exit) exit($return);         return $return;     }      protected function killPage(){ //Throw a 404 for the page         header("HTTP/1.1 404 Not Found");         exit;     } }   
Original en ingles

The following is a new question based on answers from here: Small PHP MVC Template

I have written a small MVC template library that I would like some critiques on.

The library is located here

If you are looking for where to start, check out the files in the lib directory.

I would really love to hear your critiques on:

  • Code quality
  • Code clarity
  • How to improve
  • Anything else that needs clarification expansion etc

I'm more interested in what I'm doing wrong than right.
The README is not complete and there is a lot more functionality than what is documented, if you have any questions, please ask me.

Any opinions on the actual usefulness of the library are welcome.


Code examples (all of the code is equal, just on my last question I was asked for some snippets):

Bootstrap.php:

<?php /**  * The main library for the framework  */ namespace SmallFry\lib;  class_alias('SmallFry\lib\MySQL_Interface', 'SmallFry\lib\MySQL'); // MySQL class to be deprecated /**  * Description of Bootstrap  *  * @author nlubin  */ Class Bootstrap {      /**      *      * @var SessionManager      */     private $_session;     /**      *      * @var stdClass      */     private $_path;     /**      *      * @var AppController      */     private $_controller;     /**      *      * @var Template      */     private $_template;      /**      *      * @var Config      */     private $CONFIG;      /**      * @param Config $CONFIG       */     function __construct(Config $CONFIG) {         $this->CONFIG = $CONFIG;         $this->CONFIG->set('page_title', $this->CONFIG->get('DEFAULT_TITLE'));         $this->CONFIG->set('template', $this->CONFIG->get('DEFAULT_TEMPLATE'));         $this->_session = new SessionManager($this->CONFIG->get('APP_NAME'));         $this->_path = $this->readPath();         $this->_controller = $this->loadController();         $this->_template = new Template($this->_path, $this->_session, $this->_controller, $this->CONFIG); //has destructor that controls it         $this->_controller->displayPage($this->_path->args);   //run the page for the controller         $this->_template->renderTemplate($this->_path->args); //only render template after all is said and done     }      /**      * @return \stdClass      */     private function readPath(){         $default_controller = $this->CONFIG->get('DEFAULT_CONTROLLER');         $index = str_replace("/", "", \SmallFry\Config\INDEX);          //use strtok to remove the query string from the end fo the request         $request_uri = !isset($_SERVER["REQUEST_URI"]) ? "/" : strtok($_SERVER["REQUEST_URI"],'?');;         $request_uri = str_replace("/" . $index , "/", $request_uri);          $path = $request_uri ?: '/'.$default_controller;         $path = str_replace("//", "/", $path);          $path_info = explode("/",$path);          $page = isset($path_info[2]) ? $path_info[2] : "index";         list($page, $temp) = explode('.', $page) + array("index", null);         $model = $path_info[1] ?: $default_controller;          $obj = (object) array(             'path_info' => $path_info,             'page' => $page,             'args' => array_slice($path_info, 3),             'route_args' => array_slice($path_info, 2),   //if is a route, ignore page             'model' => $model         );          return $obj;     }      /**      * @return AppController      */     private function loadController(){         $this->CONFIG->set('page', $this->_path->page);          //LOAD CONTROLLER         $modFolders = array('images', 'js', 'css');          //load controller         if(strlen($this->_path->model) == 0) $this->_path->model = $this->CONFIG->get('DEFAULT_CONTROLLER');          //find if is in modFolders:         $folderIntersect = array_intersect($this->_path->path_info, $modFolders);          if(count($folderIntersect) == 0){ //load it only if it is not in one of those folders             $controllerName = "{$this->_path->model}Controller";             $app_controller = $this->create_controller($controllerName);              if(!$app_controller)    {                 $route = $this->CONFIG->getRoute($this->_path->model);                 if($route)  {   //try to find route                     $this->_path->page = $route->page;                     $this->CONFIG->set('page', $route->page);   //reset the page name                     $this->_path->args = count($route->args) ? $route->args : $this->_path->route_args;                     $app_controller = $this->create_controller($route->controller);                     if(!$app_controller) {                         //show nothing                          header("HTTP/1.1 404 Not Found");                         exit;                     }                 }                 else    {                     //show nothing                      header("HTTP/1.1 404 Not Found");                     exit;                 }             }             return $app_controller;         }         else {  //fake mod-rewrite             $this->rewrite($this->_path->path_info, $folderIntersect);         }         //END LOAD CONTROLLER     }      /**      * @param string $controllerName      * @return AppController       */     private function create_controller($controllerName) {          $useOldVersion = !$this->CONFIG->get('DB_NEW');         $mySQLClass = "SmallFry\lib\MySQL_PDO";         if($useOldVersion)  {             $mySQLClass = "SmallFry\lib\MySQL_Improved";         }         //DB CONN         $firstHandle = null;         $secondHandle = null;         //Primary db connection         $database_info = $this->CONFIG->get('DB_INFO');         if($database_info)  {         $firstHandle = new $mySQLClass($database_info['host'], $database_info['login'],                     $database_info['password'], $database_info['database'], $this->CONFIG->get('DEBUG_QUERIES'));         }         else    {             exit("DO NOT HAVE DB INFO SET");         }          //Secondary db connection         $database_info = $this->CONFIG->get('SECONDARY_DB_INFO');         if($database_info)  {             $secondHandle = new $mySQLClass($database_info['host'], $database_info['login'],                                     $database_info['password'], $database_info['database'], $this->CONFIG->get('DEBUG_QUERIES'));         }         //END DB CONN          $nameSpacedController = "SmallFry\\Controller\\$controllerName";         if (class_exists($nameSpacedController) && is_subclass_of($nameSpacedController, __NAMESPACE__.'\AppController')) {               $app_controller  = new $nameSpacedController($this->_session, $this->CONFIG, $firstHandle, $secondHandle);          } else {             return false;         }         return $app_controller;     }      /**      * @param array $path_info      * @param array $folderIntersect       */     private function rewrite(array $path_info, array $folderIntersect){          $find_path = array_keys($folderIntersect);         $find_length = count($find_path) - 1;         $file_name = implode(DIRECTORY_SEPARATOR,array_slice($path_info, $find_path[$find_length]));          $file = \SmallFry\Config\DOCROOT."webroot".DIRECTORY_SEPARATOR.$file_name;          if(is_file($file)){ //if the file is a real file             header("Last-Modified: " . date("D, d M Y H:i:s", getlastmod()));             include \SmallFry\Config\BASEROOT.DIRECTORY_SEPARATOR.'functions'.DIRECTORY_SEPARATOR.'mime_type.php'; // needed for setups without `mime_content_type`             header('Content-type: ' . mime_content_type($file));             readfile($file);         }         else {             header("HTTP/1.1 404 Not Found");         }         exit;     } } 

AppController.php:

<?php namespace SmallFry\lib; /**  * Description of AppController  *  * @author nlubin  */ class AppController {      private $pageOn;     protected $name = __CLASS__;     protected $helpers = array();     protected $validate = array();     protected $posts = array();     protected $session;     protected $validator;     protected $template;     protected $CONFIG;      /**      *      * @param SessionManager $SESSION      * @param Config $CONFIG      * @param MySQL_Interface $firstHandle      * @param MySQL_Interface $secondHandle       */     public function __construct(SessionManager $SESSION, Config $CONFIG, MySQL_Interface $firstHandle, MySQL_Interface $secondHandle = null) {          $this->CONFIG = $CONFIG;         $this->pageOn = $this->CONFIG->get('page');         $this->session = $SESSION;         $model_name = isset($this->modelName) ? $this->modelName : $this->name;      /* Build the AppModel */         $this->$model_name = &AppModelFactory::buildModel($model_name, $CONFIG, $firstHandle, $secondHandle);      /* Get all posts */         $this->posts = $this->$model_name->getPosts();          $this->CONFIG->set('view', strtolower($model_name));          if(!$this->session->get(strtolower($model_name))){             $this->session->set(strtolower($model_name), array());         }      }      private function getPublicMethods(){         $methods = array();         $r = new \ReflectionObject($this);         $r_methods = $r->getMethods(\ReflectionMethod::IS_PUBLIC);         $notAllowedMethods = array("__construct", "init", "__destruct"); //list of methods that CANNOT be a view and are `keywords`         foreach($r_methods as $method){             if($method->class !== 'SmallFry\lib\AppController' && !in_array($method->name, $notAllowedMethods)){                  //get only public methods from extended class                 $methods[] = $method->name;             }         }         return $methods;     }      /**      *      * @param Template $TEMPLATE       */     public function setTemplate(Template $TEMPLATE){         $this->template = $TEMPLATE;         $this->setHelpers();     }      /**      * Function to run before the constructor's view function      */     public function init(){} //function to run right after constructor      /**      * Show the current page in the browser      *      * @param array $args      * @return string       */     public function displayPage($args)  {         $this->CONFIG->set('method', $this->pageOn);         $public_methods = $this->getPublicMethods();         if(in_array($this->pageOn, $public_methods))    {               call_user_func_array(array($this, $this->pageOn), $args);         }         else    {             if(!in_array($this->pageOn, $public_methods))   {                 header("HTTP/1.1 404 Not Found");             }             else {                 $this->CONFIG->set('method', '../missingfunction'); //don't even allow trying the page                 return($this->getErrorPage($this->CONFIG->get('view')."/{$this->pageOn} does not exist."));             }             exit;         }     }      /**      *      * @return string       */     function index() {}      /**      *      * @param string $msg      * @return string       */     protected function getErrorPage($msg = null)    {         $err = '<div class="error errors">%s</div>';         return sprintf($err, $msg);     }      protected function setHelpers(){         $helpers = array();         foreach($this->helpers as $helper){             $help = "{$helper}Helper";             $nameSpacedHelper = "SmallFry\\helper\\$help";             if(class_exists($nameSpacedHelper) && is_subclass_of($nameSpacedHelper, 'SmallFry\\helper\\Helper')){                 $this->$helper = new $nameSpacedHelper();                 $helpers[$helper] = $this->$helper;             }         }         $this->template->set('helpers', (object) $helpers);     }      protected function logout(){         session_destroy();         header('Location: '.WEBROOT.'index.php');         exit;     }      /**      *      * @param array $validate      * @param array $values      * @param boolean $exit      * @return boolean       */     protected function validateForm($validate = null, $values = null, $exit = true){          $this->validator = new FormValidator(); //create new validator          if($validate == null){             $validate = $this->validate;         }          foreach($validate as $field => $rules){             foreach($rules as $validate=>$message){                 $this->validator->addValidation($field, $validate, $message);             }         }          return $this->doValidate($values, $exit);     }      protected function doValidate($values = null, $exit = true){         if(!(!isset($_POST) || count($_POST) == 0)){             //some form was submitted             if(!$this->validator->ValidateForm($values)){                 $error = '';                 $error_hash = $this->validator->GetErrors();                 foreach($error_hash as $inpname => $inp_err)                 {                   $error .= $inp_err.PHP_EOL;                 }                 return $this->makeError($error, $exit);                             }         }         return true;     }      protected function makeError($str, $exit = true){         $return = $this->getErrorPage(nl2br($str));         if($exit) exit($return);         return $return;     }      protected function killPage(){ //Throw a 404 for the page         header("HTTP/1.1 404 Not Found");         exit;     } } 
           
   
   

Lista de respuestas

8
 
vote

Algunas cosas:

En primer lugar, no es MVC. En MVC, los controladores no alimentan los datos de la vista. Este es un error común, pero la arquitectura que está usando aquí está más cerca del PAC. Consulte http://www.garfieldtech.com/blog/mvc-vs-pac y http://r.je/views-are-not-templates.html Para más información (Divulgación completa: i escribió el segundo artículo.)

En segundo lugar, sus modelos no son modelos, son de acceso simple de datos y apenas. Deben al menos resumen SQL de distancia. Tiene lógica de dominio, lógica de presentación y lógica de aplicación todo en el controlador. En MVC, el modelo debe almacenar el estado de la aplicación (y tener acceso al estado de dominio), el controlador debe responder a las acciones del usuario y la vista debe obtener los datos del modelo. Consulte http: //blog.astrumfutura. COM / 2008/12 / THE-M-IN-MVC-PORQUE-MODELOS: están mal entendidos, y sin apreciarse / para una descripción del modelo en MVC.

En tercer lugar, forzar modelos, vistas y controladores para extenderse desde las clases de base específicas en gran medida limita la flexibilidad. Sus controladores, vistas y modelos deben implementar interfaces en lugar de extender las clases de base. Aunque por experiencia, he encontrado que los controladores y modelos ni siquiera necesitan hacer eso.

Finalmente, siempre debe favorecer la inyección de dependencia en lugar de construir objetos arbitrariamente a lo largo del código. Consulte http://misko.hevery.com/code-reviewers-guide/ Flaw-constructor-hace-real-trabajos / (y el resto de su sitio muy excelente) para obtener más información.

Lamento sonar muy críticos, pero es importante obtener la arquitectura fundamental correcta antes de pedirle a las personas que critiquen la claridad y la calidad del código.

 

A few things:

Firstly, It's not MVC. In MVC, controllers do not feed the view data. This is a common misconception but the architecture you're using here is closer to PAC. See http://www.garfieldtech.com/blog/mvc-vs-pac and http://r.je/views-are-not-templates.html for more info (Full disclosure: I wrote the second article.)

Secondly, your models aren't models they're simple data access and barely even that. They should at least abstract SQL away. You have domain logic, presentation logic and application logic all in the controller. In MVC the model should store application state (and have access to domain state), the controller should respond to user actions and the view should fetch the data from the model. See http://blog.astrumfutura.com/2008/12/the-m-in-mvc-why-models-are-misunderstood-and-unappreciated/ for a description of the model in MVC.

Thirdly, forcing models, views and controllers to extend from specific base classes heavily limits flexibility. Your controllers, views and models should implement interfaces instead of extending base classes. Although from experience, I have found that controllers and models don't even need to do that.

Finally, you should always favour Dependency injection rather than constructing objects arbitrarily throughout the code. See http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/ (and the rest of his very excellent site) for more information.

Sorry to sound very critical, but it's important to get the fundamental architecture correct before asking people to critique code clarity and quality.

 
 
         
         
0
 
vote

Hay muchas cosas para criticar en su enfoque, y se reduce a las cosas habituales:

  1. tus clases hacen demasiadas cosas diferentes
  2. Sus clases no implementan la inyección de dependencia adecuada.
  3. Pero si lo hacen, tienen dependencias muy extrañas que se ajustarán a un caso de uso determinado, pero no todas.

Algunos detalles:

      $this->CONFIG->set('page_title', $this->CONFIG->get('DEFAULT_TITLE'));     $this->CONFIG->set('template', $this->CONFIG->get('DEFAULT_TEMPLATE'));   

Me parece extraño que la clase Bootstrap realmente cambie la configuración. La configuración para mí es un almacenamiento de valor de solo lectura. Se escribe en el objeto de configuración solo una vez en el ciclo de vida de la solicitud de solicitud: cuando se lee de su almacenamiento permanente.

El AppController para una razón extraña tiene dependencias en un administrador de sesión, un objeto de configuración y dos conexiones de base de datos. Ninguno de ellos debe ser el negocio de un controlador. La tarea de los controladores es ser la capa de combinación entre la solicitud entrante en el lado de entrada, una serie de modelos que actúan sobre los datos en la solicitud como la etapa de procesamiento y que pasan datos de la respuesta a la salida.

Analizar los datos de entrada de la solicitud generalmente se realiza ayudando a los objetos que representan formularios HTML para realizar la validación (ninguno de los negocios de los controladores). Los modelos generalmente hacen uso de algún acceso o sesión de base de datos, pero esto tampoco es para que el controlador lo sepa. Preparación de un medio de respuesta para presionar algunos valores a la respuesta, que en realidad podría ser prestado por una plantilla, pero esto tampoco es realmente el negocio del controlador.

Cuando miro su clase de AppController, veo que ofrece muchos métodos que no tienen nada que ver con las tareas del controlador, pero con los detalles de la implementación de una aplicación concreta. Veo métodos como displayPage , validateForm , 9988776655544333 , eso no debería estar allí. Especialmente me pregunto por qué 9988777665544334 no usa el 9988776665544335 para terminar la sesión.

Se mencionó anteriormente, pero quiero subrayar que si obliga a todas las clases de aplicación que se extenderán desde las clases de sus marcos, dificulta que otros usen su marco. Por ejemplo, el Helpers , por alguna razón, deben extenderse de su clase de ayuda a la madre. Un enfoque mucho mejor sería simplemente forzar solo la implementación de una interfaz y ofrecer una clase de ayuda abstracta que ya tiene una implementación básica que pueda extenderse si no hay necesidad de construir desde cero.

 

There is plenty of stuff to criticize in your approach, and it boils down to the usual stuff:

  1. Your classes do too much different stuff
  2. Your classes do not implement proper dependency injection.
  3. But if they do, they have very weird dependencies that will fit a certain use case, but not all.

Some details:

    $this->CONFIG->set('page_title', $this->CONFIG->get('DEFAULT_TITLE'));     $this->CONFIG->set('template', $this->CONFIG->get('DEFAULT_TEMPLATE')); 

I find it weird that the bootstrap class actually changes the configuration. Configuration to me is a read-only value storage. It gets written in the config object only once in the life cycle of the application request: When it's read from it's permanent storage.

The AppController for some weird reason has dependencies on a session manager, a configuration object, and TWO database connections. None of them should be the business of a controller. The controllers task is to be the combining layer between the incoming request on the input side, a number of models that act upon the data in the request as the processing step, and passing data back to the response as the output.

Analyzing the input data from the request usually is done by helping objects that represent HTML forms to do validation (none of the controllers business). The models usually make use of some database access or session, but this also is not for the controller to know. Preparing a response means to push some values into the answer, which might actually be rendered by a template, but this also is not really the business of the controller.

When I look at your AppController class, I see that it offers a whole lot of methods that have nothing to do with controller tasks, but with implementation details of a concrete application. I see methods like displayPage, validateForm, logout, that shouldn't be there. I especially wonder why logout() does not use the SessionManager to terminate the session.

It was mentioned before, but I want to underline that if you force all the application classes to be extended from your frameworks classes, you make it hard for others to use your framework. For example the Helpers - for some reason they have to be extended from your mother helper class. A much better approach would be to only force the implementation of an interface, and offer an abstract helper class that already has a basic implementation that can be extended if there is no need to build from scratch.

 
 
 
 

Relacionados problema

20  Construyendo una buena biblioteca de plantillas C ++ 11 - Tiempo compilado enumeró la matriz enumulada [cerrada]  ( Building a good c11 template library compile time checked enum array ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

2  libconfini (biblioteca compartida)  ( Libconfini shared library ) 
Recientemente escribí una pequeña biblioteca de análisis INI. El código también está en GitHub , con documentación . Me gustaría tener opiniones, sugerencia...

8  Envoltura Libusb Library en C ++  ( Wrapping libusb library in c ) 
Quiero usar la biblioteca de Libusb en mi aplicación C ++. He creado clases que envuelven las funciones de Libusb. Puede ver que la API de Libusb se divide en...

4  Helper Utilities para una evaluación comparativa más fácil en C  ( Helper utilities for easier benchmarking in c ) 
Tengo esta pequeña biblioteca para medir el tiempo de ejecución en milisegundos y devolver la duración más el resultado: execres.h X4 execres.c ...

3  Clase en una DLL para extraer datos de un archivo a través de muchos accesorios  ( Class in a dll to extract data from a file via many accessors ) 
Estoy haciendo una clase que toma un camino a un archivo de texto como un argumento en su constructor, y luego analiza el archivo de texto y extrae muchos dat...

2  Hacer un objeto Administrar datos personalizados en JavaScript  ( Making an object manage custom data in javascript ) 
Escribí este bloque de código como parte de una biblioteca de utilidad JS en la que estoy trabajando. Estaré agradecido si alguien pudiera escanearlo por even...

28  Biblioteca PHP AutoOoGer  ( Php autoloader library ) 
Básicamente, había escrito esta clase hace poco tiempo para aliviar la carga automática de nuestras bibliotecas locales. La premisa es que todo se divide po...

2  Punteros para el formato de encabezado, diseño y diseño de la biblioteca de la biblioteca C ++ / CLI  ( Pointers for c cli library header formatting layout and design ) 
He diseñado una biblioteca de Wrapper C ++ / CLI que permite aplicaciones C ++ en Windows, y otras plataformas que pueden cargar C DLLs (por ejemplo, Java a t...

8  Biblioteca básica de JavaScript  ( Basic javascript library ) 
Mi propio CMS está utilizando actualmente JQERY, pero como uno de los objetivos es que todo el proyecto sea muy pequeño, he decidido escribir mi propia biblio...

14  Eficiencia / diseño del código de la biblioteca ()  ( Efficiency design of trim library code ) 
Estoy trabajando en algún código de la biblioteca y estoy tratando de optimizar mis funciones 9988776665544330 . A tal efecto, estoy tratando de averiguar la...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos