llamar - que significa class en php
Marco central PHP OOP (3)
Acabo de publicar esta pregunta para que algunos de ustedes puedan señalarme de la manera correcta. Me estoy calentando lentamente a OOP, comenzando a entender el concepto. Quiero hacer un buen núcleo sólido o base para ser utilizado como back-end de CMS. También usará MVC. He estado usando http://gilbitron.github.com/PIP/ como la base de MVC.
Lo que no puedo entender es lo siguiente:
Digamos, en la página de proyectos en el backend tengo 2 secciones: htmltext y proyectos y debería poder editarlos a ambos. El uri sería algo así como: // domain / backend / projects (el método sería el índice y mostrar las 2 secciones)
Cuando hago clic en proyectos, ¿cómo se debe manejar? // dominio / backend / projects / projects / o // domain / backend / projects / list /
Un paso más allá, un proyecto tendrá algunas imágenes o una galería: // domain / backend / projects / edit / 5 / gallery / 2
Mi pregunta aquí es, primero: ¿sería una buena manera de hacerlo y más importante aún cómo se implementaría esto en OOP?
el controlador principal de proyectos:
class projects {
function index(){
// view index
}
function edit{
$project = new Project();
$projectdata = $project->load(5);
}
}
Un solo controlador de proyecto
class project {
function __construct(){
$this->projectmodel = $this->loadModel(''project_model''); // prepare the model to be used
}
function load($id){
$this->projectmodel->loadproject($id);
}
}
modelo de proyecto
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");
}
}
Ahora mi pregunta. Si este proyecto tiene imágenes, ¿dónde debería cargar la clase de imagen para manejarlas? ¿Debo cargarlo en el project_model como $ this-> images = new Images (); y tiene una función dentro del modelo
function loadimages($id){
$this->images->load($id);
}
y luego las imágenes serían algo así como:
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");
}
}
Parece que los controladores y los modelos se mezclan de esta manera. Sin embargo, de manera lógica, un proyecto es un contenedor que contiene información del proyecto, que podría ser texto, imágenes y tal vez videos. ¿Cómo voy a configurarlo también lógicamente?
Si este proyecto tiene imágenes, ¿dónde debería cargar la clase de imagen para manejarlas? ¿Debo cargarlo en el project_model como $ this-> images = new Images (); y tiene una función dentro del modelo
Sí. El objetivo del modelo es encapsular la lógica empresarial para que solo tenga que escribir los algoritmos una vez y compartirlos varias veces. Lo que haría si fuera usted es agregar un método getImages()
al modelo del proyecto ya que las imágenes son un atributo directo de un proyecto, esto hace que cada proyecto sepa cómo recuperar sus propias imágenes.
A su código le faltan algunos conceptos clave en comparación con ORMS con los que he trabajado (clases de hidratación y peer / tabla), por lo que intentaré seguir con su código. Puede recuperar las imágenes a través del objeto Proyecto, luego hacer referencia a las imágenes a través de la vista 1 de 2 maneras:
// 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 ?>
Arriba es solo demostrativo, pero debe darle una idea. Sugeriría que eches un vistazo a Doctrine . Es un ORM probado y estable que proporciona gran parte de lo que está intentando escribir, además de que agrega los componentes faltantes que mencioné anteriormente; hidratación, relaciones de objetos y clases de tabla, junto con muchas otras características, como conjuntos anidados.
(dado que la pregunta fue lo suficientemente larga por sí misma, no quería extenderla, así que la agregué como respuesta)
projects.php este controlador extiende el controlador del proyecto. el objetivo principal es manejar los múltiples getAllProjects () usando su propio modelo y luego pasarlo al controlador del proyecto 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
el project_model no hace nada más que obtener datos de proyectos y datos relacionados como imágenes
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);
}
}
Lo bueno de este enfoque es que puedo usar la clase de proyecto por sí mismo y funcionará. Puedo encapsularlo en proyectos y también se puede usar.
¿Es este un buen (y el correcto) enfoque para hacer las cosas? ¿O sería mejor poner todo esto junto en un controlador y una clase de modelo?
La pregunta original
La primera parte, sobre las URL es algo llamado: Enrutamiento o envío. Hay un buen artículo sobre esto en relación con Symfony 2.x, pero la idea detrás de esto es lo que importa. Además, podría ver formas en cómo otros frameworks lo implementan.
En cuanto a los ejemplos originales de URL, las galerías se almacenarán en DB. ¿No es así? Y tendrán una identificación única . Lo que hace que esto, /backend/projects/edit/5/gallery/2
bastante inútil. En cambio, su URL debería verse más como:
/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
La URL debe contener solo la información que realmente necesita.
Esto también indicaría 3 controladores:
- gestión de galería única
- gestión de proyectos individuales
- lidiando con listas de galerías
Y las URL de ejemplo tendrían un patrón similar al siguiente:
/backend(/:controller(/:id|:page)(/:action(/:parameter)))
Donde la parte /backend
es obligatoria, pero el controller
es opcional. Si se encuentra el controlador, entonces id
(o página, cuando se trata de listas) y la action
es opcional. Si se encuentra acción, el parameter
adicional es opcional. Esta estructura le permitiría tratar con la mayoría de sus rutas, si se escribe como una expresión regular.
OOP más allá de las clases
Antes de comenzar a usar o escribir algún tipo de marco de PHP, debe aprender a escribir el código adecuado orientado a objetos. Y eso no significa "saber cómo escribir una clase". Significa que usted tiene que comprender realmente qué es programación orientada a objetos, en qué principios se basa, qué errores comunes comete la gente y cuáles son los conceptos erróneos más prevalentes. Aquí hay algunas conferencias que pueden ayudarlo con esto:
- Herencia, polimorfismo y pruebas
- Patrones avanzados de OO ( diapositivas )
- Examen de la unidad
- Los principios del diseño ágil
- Estado global y Singletons
- ¡No busques cosas!
- Más allá de los marcos ( diapositiva )
- Agilidad y calidad ( diapositivas )
- Limpiar el Código I: Argumentos
- Clean Code III: Funciones
Esto debería darle una visión general del tema ... sí, es mucho. Pero sospecha que preferirás videos sobre libros. De lo contrario, algunos materiales de lectura:
- Soluciones PHP orientadas a objetos
- Patrones de diseño explicados
- Patrones de la arquitectura de aplicaciones empresariales
Notarás que muchos materiales son independientes del idioma. Esto se debe a que la teoría, para los lenguajes orientados a objetos basados en clases, es la misma.
PD
Tenga cuidado con extends
palabra clave en su código. Significa " es un ". Está bien, si la class Oak extends Tree
, porque todos los robles son árboles. Pero si tiene class User extends Database
, es posible que alguien se ofenda. En realidad, hay un principio de POO que habla de ello: principio de sustitución de Liskov ... también hay una explicación muy breve