Mejor práctica: Aprendiendo PHP OOP -- php campo con object-oriented camp codereview Relacionados El problema

Best Practice: Learning PHP OOP


2
vote

problema

Español

Estoy aprendiendo PHP OOP. Estoy familiarizado con PHP, y el uso limitado de OOP, pero no escribiendo OOP. Tengo un pequeño sitio web exitoso que utiliza grandes matrices asociativas, pero ahora está sufriendo problemas de rendimiento porque las matrices absorben la memoria (My TeamArray contiene 16K equipos de los datos a continuación, más). Estoy reescribiendo el código para aprovechar OOP y, con suerte, lograr un mayor rendimiento como resultado. (Una prueba rápida reduce el uso de memoria por 16x).

Tengo esta clase:

  htmlspecialchars($key, ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5, "UTF-8")6  

}

El equipo es solo un contenedor de objetos que almacena todos los datos estáticos, por lo que tengo las funciones 998877766555443317 en privado.

Se puede agregar el equipo (¿no está seguro si debería extenderse? Probablemente la clase de Equipo_Class sería una mejor opción para ir al juego) en una clase de juego (aún no está escrito, donde se compitan dos equipos, fecha, fecha, Ubicación, puntajes, etc.), y también (probablemente extendida) a una clase de Team_Class (también no está escrita) donde obtienen propiedades sobre la temporada en la que está compitiendo (deporte, año, nivel, etc.).

¿Se puede mejorar? ¿Hay algún problema deslumbrante?

Dado que $ StateID es solo una referencia de identificación al estado, ¿debería almacenar el nombre del estado como parte del objeto? ¿Es mejor comparar StateID o State?

¿Necesito almacenar los $ TeamID?

¿Hay una mejor manera de manejar los coloresx? Estos son solo 2 cadenas de color de código hexagonal.

¿Puedo declarar todas las propiedades privadas como:

  htmlspecialchars($key, ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5, "UTF-8")8  

Estoy pensando que almacenaría todos los manipuladores de objetos (quizás hasta cien, tal vez miles) en una matriz para trabajar con ellos. ¿Hay una mejor manera?

  htmlspecialchars($key, ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5, "UTF-8")9  

Finalmente, ¿hay una buena, fácil "Fiddle" admite bases de datos?

Original en ingles

I am learning PHP OOP. I am familiar with PHP, and limited use of OOP, but not writing OOP. I have a small successful website that uses large associative arrays but is now suffering performance problems because the arrays soak up memory (My teamarray contains 16k teams of the data below, plus more). I am rewriting the code to take advantage of OOP and hopefully achieve greater performance as a result. (A quick trial reduced memory use by 16x).

I have this class:

class team { private $teamid; private $name; private $urlname; private $mascot; private $city; private $stateid; private $jv; private $color1; private $color2; private $address; private $zip; private $lat; private $lng;  function __construct($teamid) {     global $my_db;     $row = $my_db->query("SELECT * FROM `team` WHERE `teamid` = $teamid;")->fetchRow(MDB2_FETCHMODE_ASSOC);      $this->set_teamid = $row['teamid'];     $this->set_name = $row['name'];     $this->set_urlname = $row['urlname'];     $this->set_mascot = $row['mascot'];     $this->set_city = $row['city'];     $this->set_stateid = $row['stateid'];     $this->set_jv = $row['jv'];     $this->set_color1 = $row['color1'];     $this->set_color2 = $row['color2'];     $this->set_address = $row['address'];     $this->set_zip = $row['zip'];     $this->set_lat = $row['lat'];     $this->set_lng = $row['lng']; }   public function get_teamid() {     return $this->teamid; } private function set_teamid($new) {     $this->teamid = $new; }  public function get_name() {     return $this->name; } private function set_name($new) {     $this->name = $new; }  public function get_urlname() {     return $this->urlname; } private function set_urlname($new) {     $this->urlname = $new; }  public function get_mascot() {     return $this->mascot; } private function set_mascot($new) {     $this->mascot = $new; }  public function get_city() {     return $this->city; } private function set_city($new) {     $this->city = $new; }  public function get_stateid() {     return $this->stateid; } private function set_stateid($new) {     $this->stateid = $new; }  public function get_jv() {     return $this->jv; } private function set_jv($new) {     $this->jv = $new; }  private public function get_color1() {     return $this->color1; } private function set_color1($new) {     $this->color1 = $new; }  public function get_color2() {     return $this->color2; } private function set_color2($new) {     $this->color2 = $new; }  public function get_address() {     return $this->address; } private function set_address($new) {     $this->address = $new; }  public function get_zip() {     return $this->zip; } private function set_zip($new) {     $this->zip = $new; }  public function get_lat() {     return $this->lat; } private function set_lat($new) {     $this->lat = $new; }  public function get_lng() {     return $this->lng; } private function set_lng($new) {     $this->lng = $new; } 

}

The team is just an object container storing all static data, so I have the set_ functions at private.

The team can be added (not sure if it should be extended? probably the team_class class would be a better choice for going into the game) into a game class (not yet written, where two teams compete, time, date, location, scores, etc), and also (probably extended) into a team_class class (also not yet written) where they get properties about the season they are competing in (sport, year, level, etc).

Can it be improved? Are there any glaring problems?

Since $stateid is just an ID reference to the state, should I store the state name as part of the object? Is it better to compare stateid or state?

Do I need to store the $teamid?

Is there a better way to handle the colorsX? These are just 2 hex code color strings.

Can I declare all the private properties like:

private $teamid, $name, ....; 

I'm thinking I would store all the object handlers (perhaps up to a hundred, maybe thousands) in an array for working with them. Is there a better way?

$teamarray[$teamid] = new team($teamid); $teamarray[$teamid]->get_name(); 

Finally, is there an good, easy "fiddle" supports databases?

     
   
   

Lista de respuestas

3
 
vote
vote
La mejor respuesta
 

De acuerdo, aquí hay un ordenado preliminar del código, con comentarios:

  .2  

Y aquí está sin comentarios:

  .3  

Nuevamente: el problema deslumbrante es que la consulta de SQL ... se puede inyectar fácilmente si no está haciendo ninguna comprobación de la consulta () y incluso si esto es así, un sitio de intranet, no se cobre en eso Por seguridad y pereza. Protege la base de datos a todos los costos.

ahora para sus preguntas:

puede mejorarse? ¿Hay algún problema deslumbrante?

ver notas anteriores sobre SQL

Dado que $ StateID es solo una referencia de identificación al estado, ¿debería almacenar el nombre del estado como parte del objeto? ¿Es mejor comparar StateID o State?

Siéntase libre de almacenarlo, o no. No importa de cualquier manera. Si lo necesita para su software, entonces mantenlo obviamente.

¿Necesito almacenar los $ TeamID?

nuevamente, no es necesario que su software no lo requiere, pero en la línea, puede convertirse en una referencia en algún pedazo de software u otro.

¿Hay una mejor manera de manejar los coloresx? Estos son solo 2 cadenas de color de código hexagonal.

Tal vez una matriz - es decir: .4 ? O puedes dejarlos como es.

editar

editado para Idiom:

  .5  
 

Okay, here's a preliminary tidying up of the code, with comments:

<?php  class team {   # You can stream line the private fields   private $teamid, $name, $urlname, $mascot, $city, $stateid, $jv;           $color1, $color2, $address, $zip, $lat, $lng;    # Avoid `global $my_db`, perhaps direct injection    # of the db class into the constructor?   function __construct($teamid) {       global $my_db;        # $teamid is not safe in this query it would seem...perhaps consider prepared statements?        $row = $my_db->query("SELECT * FROM `team` WHERE `teamid` = $teamid;")->fetchRow(MDB2_FETCHMODE_ASSOC);        # Let's clarify this...you're using functions as such:       # $this->set_teamid($row['teamid']);        # We're not doing any variable checking, so why not        # just set the variable directly and get rid of a        # bunch of functions and function calls?       $this->teamid   = $row['teamid'];       $this->name     = $row['name'];       $this->urlname  = $row['urlname'];       $this->mascot   = $row['mascot'];       $this->city     = $row['city'];       $this->stateid  = $row['stateid'];       $this->jv       = $row['jv'];       $this->color1   = $row['color1'];       $this->color2   = $row['color2'];       $this->address  = $row['address'];       $this->zip      = $row['zip'];       $this->lat      = $row['lat'];       $this->lng      = $row['lng'];   }      # Below, we will remove all the set_* functions    # and concatenate all the get_* functions into 1    # switch function   public function get($varname){     switch($varname){       case 'teamid'   : $return = $this->teamid; break;       case 'name'     : $return = $this->name; break;       case 'urlname'  : $return = $this->urlname; break;       case 'mascot'   : $return = $this->mascot; break;       case 'city'     : $return = $this->city; break;       case 'stateid'  : $return = $this->stateid; break;       case 'jv'       : $return = $this->jv; break;       case 'color1'   : $return = $this->color1; break;       case 'color2'   : $return = $this->color2; break;       case 'address'  : $return = $this->address; break;       case 'zip'      : $return = $this->zip; break;       case 'lat'      : $return = $this->lat; break;       case 'lng'      : $return = $this->lng; break;       default         : $return = "Error in get()."; break;     }      return $return;   }    # Replaced   #public function get_teamid() {   #    return $this->teamid;   #}     # Removed   #private function set_teamid($new) {   #    $this->teamid = $new;   #}    # Replaced   #public function get_name() {   #    return $this->name;   #}    #Removed   #private function set_name($new) {   #    $this->name = $new;   #}    # Replaced   #public function get_urlname() {   #    return $this->urlname;   #}    # Removed   #private function set_urlname($new) {   #    $this->urlname = $new;   #}    # Replaced   #public function get_mascot() {   #    return $this->mascot;   #}    # Removed   #private function set_mascot($new) {   #    $this->mascot = $new;   #}    # Replaced   #public function get_city() {   #    return $this->city;   #}    # Removed   #private function set_city($new) {   #    $this->city = $new;   #}    # Replaced   #public function get_stateid() {   #    return $this->stateid;   #}    # Removed   #private function set_stateid($new) {   #    $this->stateid = $new;   #}    # Replaced   #public function get_jv() {   #    return $this->jv;   #}    # Removed   #private function set_jv($new) {   #    $this->jv = $new;   #}    # Replaced   #public function get_color1() {   #    return $this->color1;   #}    # Removed   #private function set_color1($new) {   #    $this->color1 = $new;   #}    # Replaced   #public function get_color2() {   #    return $this->color2;   #}    # Removed   #private function set_color2($new) {   #    $this->color2 = $new;   #}    # Replaced   #public function get_address() {   #    return $this->address;   #}    # Removed   #private function set_address($new) {   #    $this->address = $new;   #}    # Replaced   #public function get_zip() {   #    return $this->zip;   #}    # Removed   #private function set_zip($new) {   #    $this->zip = $new;   #}    # Replaced   #public function get_lat() {   #    return $this->lat;   #}    # Removed   #private function set_lat($new) {   #    $this->lat = $new;   #}    # Replaced   #public function get_lng() {   #    return $this->lng;   #}    # Removed   #private function set_lng($new) {   #    $this->lng = $new;   #} }  ?> 

And here it is without comments:

<?php  class team {   private $teamid, $name, $urlname, $mascot, $city, $stateid, $jv;           $color1, $color2, $address, $zip, $lat, $lng;    function __construct($teamid) {       global $my_db;       $row = $my_db->query("SELECT * FROM `team` WHERE `teamid` = $teamid;")->fetchRow(MDB2_FETCHMODE_ASSOC);        $this->teamid   = $row['teamid'];       $this->name     = $row['name'];       $this->urlname  = $row['urlname'];       $this->mascot   = $row['mascot'];       $this->city     = $row['city'];       $this->stateid  = $row['stateid'];       $this->jv       = $row['jv'];       $this->color1   = $row['color1'];       $this->color2   = $row['color2'];       $this->address  = $row['address'];       $this->zip      = $row['zip'];       $this->lat      = $row['lat'];       $this->lng      = $row['lng'];   }     public function get($varname){     switch($varname){       case 'teamid'   : $return = $this->teamid; break;       case 'name'     : $return = $this->name; break;       case 'urlname'  : $return = $this->urlname; break;       case 'mascot'   : $return = $this->mascot; break;       case 'city'     : $return = $this->city; break;       case 'stateid'  : $return = $this->stateid; break;       case 'jv'       : $return = $this->jv; break;       case 'color1'   : $return = $this->color1; break;       case 'color2'   : $return = $this->color2; break;       case 'address'  : $return = $this->address; break;       case 'zip'      : $return = $this->zip; break;       case 'lat'      : $return = $this->lat; break;       case 'lng'      : $return = $this->lng; break;       default         : $return = "Error in get()."; break;     }      return $return;   } }  ?> 

Again - the glaring issue is that SQL query...can easily be injected if you're not doing any checking in query() itself - and even if this is say, an intranet site, don't hedge on that for safety and laziness. Protect the database at all costs.

Now for your questions:

Can it be improved? Are there any glaring problems?

See above notes about SQL

Since $stateid is just an ID reference to the state, should I store the state name as part of the object? Is it better to compare stateid or state?

Feel free to store it, or not. Doesn't matter either way. If you require it for your software, then keep it obviously.

Do I need to store the $teamid?

Again, you don't need to if your software doesn't require it, but down the line, it might become a reference in some piece of software or other.

Is there a better way to handle the colorsX? These are just 2 hex code color strings.

Perhaps an array - ie: $colors[1]; $colors[2];? Or you can leave them as is.

EDIT

Edited for idiom:

<?php  class team {   private $row;    function __construct($teamid) {       global $my_db;       $this->row = $my_db->query("SELECT * FROM `team` WHERE `teamid` = $teamid;")->fetchRow(MDB2_FETCHMODE_ASSOC);   }    public function get($item){     return $this->row[$item] ? $this->row[$item] : NULL;   } }  # Usage:  $t = new team(14); echo $t->get('city');  ?> 
 
 
         
         
1
 
vote

Uso OOP Para describir su dominio, proporcione la encapsulación, haga que el código de código, etc. oop no haga que el código sea inherente, ejecute más eficientemente . Un objeto con 13 propiedades utiliza tanta memoria (si no un poco más) que una matriz con 13 teclas.

Mi enfoque de OOP es describir primero el dominio del problema. Preocuparse por la base de datos en este punto solo complicará las cosas.

Obviamente, no entiendo su dominio problemático, sino, para fines de discusión, digamos que tengo estas cosas: equipo, temporada, competencia

Ahora, pensando en una API o cómo estas cosas interactúan entre sí, podría tener algo como esto para registrar equipos para una temporada:

  $fireBalls = new Team(); $fireBalls->setName('Fire Balls');  $springSeason = new Season(); $springSeason->setName('spring'); $sprintSeason->setYear(2013); $springSeason->registerTeam($fireBalls);   

para configurar un juego tal vez:

  $game1 = new Game(); $game1->setTime(new DateTime('2012-03-01 15:00:00')); $game1->setTeams($fireBalls, $dragons); //these two teams already created/fetched   

Hay mucho omitido aquí, pero el punto es entender cómo se relacionan sus objetos entre sí y qué tipo de comportamiento se necesita. Pase un tiempo escribiendo todo esto en una pizarra o papel. Háblelo con otros que entiendan el dominio. Asegúrese de que describe correctamente el dominio antes de escribir una sola línea de código real. Tenga en cuenta que un modelo no es simplemente entidades con un montón de colonos / consignos. El modelo debe contener comportamientos reales (como RegistSteam), lo que generalmente hace más que simplemente establecer 1 valor interno. El comportamiento modifica el estado del modelo realizando cálculos, comprobando la validez, etc.

Una vez que esté listo para persistir algunos de estos datos, le recomiendo que utilice una biblioteca de persistencia existente, como la doctrina, propelle, etc. Algunos de estos trabajan de manera diferente entre sí, pero la idea es que capturan el estado de Su modelo asignando sus objetos a su base de datos relacional y vuelva a crear sus objetos de la base de datos relacionales cuando los necesita nuevamente.

Con respecto a algunas de sus preguntas específicas:

¿Hay algún problema deslumbrante? No soy un gran fan de las cosas de persistencia que admite mis entidades, pero esto es una preferencia personal. Sin embargo, si desea utilizar este patrón (llamado Registro Activo BTW), el objeto DB debe inyectarse, ya que otros ya han declarado. Además, con la aprobación de una identificación al constructor, ¿cómo se iría a crear una nueva entidad?

Todos tus colonos son privados. ¿Es la clase de equipo considerada solo lectura?

Dado que $ StateID es solo una referencia de identificación al estado, ¿debería almacenar el nombre del estado como parte del objeto? Depende de si consideras que el estado es una propiedad simple del equipo o si en realidad es parte de alguna entidad relacionada, como la dirección o la ubicación.

¿Necesito almacenar los $ TeamID? Si usas un ORM, déjalo preocuparse por eso.

¿Hay una mejor manera de manejar los coloresx? Manejarlo verticalmente en lugar de horizontalmente. I.e.

  $team->addColor(1, 'red'); $team->addColor(2, 'green');   

Estoy pensando que almacenaría todos los manipuladores de objetos (quizás hasta cien, tal vez miles) en una matriz para trabajar con ellos. ¿Hay una mejor manera? ¡Esto suena como la fuente de tu problema original! Las grandes matrices pueden masticar mucho de memoria. No importa si es una matriz de matrices o una matriz de objetos. Una base de datos relacional es mucho mejor para el trabajo. Hay muchos para elegir, PostgreSQL, MySQL, SQLite, Oracle, etc

 

Use oop to describe your domain, provide encapsulation, make code testable, etc. Oop does not inherently make code run more efficiently. An object with 13 properties uses just as much memory (if not slightly more) than an array with 13 keys.

My approach to oop is to describe the problem domain first. Worrying about the database at this point will only complicate things.

Obviously, I don't understand your problem domain but, for discussion purposes, let's say I have these things: Team, Season, Competition

Now, thinking about an api or how these things interact with each other you might have something like this to register teams for a season:

$fireBalls = new Team(); $fireBalls->setName('Fire Balls');  $springSeason = new Season(); $springSeason->setName('spring'); $sprintSeason->setYear(2013); $springSeason->registerTeam($fireBalls); 

To set up a game perhaps:

$game1 = new Game(); $game1->setTime(new DateTime('2012-03-01 15:00:00')); $game1->setTeams($fireBalls, $dragons); //these two teams already created/fetched 

There is much omitted here but the point is to understand how your objects relate to one another and what kind of behavior is needed. Spend some time writing this all out on a whiteboard or paper. Talk it over with others who understand the domain. Make sure it properly describes the domain before writing a single line of actual code. Note that a model is not simply Entities with a bunch of setters/getters. The model should contain actual behavior (such as registerTeam) which usually does more than just set 1 internal value. Behavior modifies the state of the model by performing calculations, checking validity, etc.

Once you are ready to persist some of this data, I highly recommend that you use an existing persistence library such as Doctrine, Propel, etc. Some of these work differently from one another but the idea is that they capture the state of your Model by mapping your Objects to your Relational Database and re-create your Objects from the Relational Database when you need them again.

Regarding some of your specific questions:

Are there any glaring problems? I'm not a huge fan of sticking persistence stuff into my Entities but, this is personal preference. However, if you want to use this pattern (called Active Record btw), the db object should be injected as others have already stated. Also, with passing an id to the constructor, how would one go about creating a new Entity?

All of your setters are private. Is the team class considered read only?

Since $stateid is just an ID reference to the state, should I store the state name as part of the object? It depends on whether you consider State to be a simple property of team or whether it is actually part of some related entity such as Address or Location.

Do I need to store the $teamid? If you use a ORM, let it worry about that.

Is there a better way to handle the colorsX? Handle it vertically instead of horizontally. i.e.

$team->addColor(1, 'red'); $team->addColor(2, 'green'); 

I'm thinking I would store all the object handlers (perhaps up to a hundred, maybe thousands) in an array for working with them. Is there a better way? This sounds like the source of your original problem! Large arrays can chew up alot of memory. It does not matter if it's an array of arrays or an array of objects. A Relational Database is much better for the job. There are many to choose from, postgresql, mysql, sqlite, oracle, etc

 
 

Relacionados problema

1  Clase de juego, escrito usando enums  ( Playing card class written using enums ) 
Escribí una clase de tarjeta A Mientras vuelvas a esta publicación aquí: Pregunta previa Sé que ha pasado mucho tiempo, pero recientemente regresé al proyec...

10  "Stardust" Simulador 2D Gravity - Seguimiento 1: Los planetas  ( Stardust 2d gravity simulator follow up 1 the planets ) 
Este es un seguimiento para el juego de gravedad del simulador 2D pregunta. Desde entonces, he desarrollado mis habilidades de JavaScript, y ahora esto...

5  Solicitud de Tkinter para administrar las tareas escolares  ( Tkinter application to manage school tasks ) 
Soy un principiante en la programación de la OOP y me pregunto cuál es la mejor manera de poner todas las ventanas y funciones de una aplicación de ventana en...

1  Pasando un objeto a la vista en CodeIgner  ( Passing an object to the view in codeigniter ) 
Estoy tratando de usar un objeto y persistirlo en la base de datos. He creado una clase en la carpeta de la biblioteca. <?php if (!defined('BASEPATH'))...

8  Árbol fractal orientado a objetos  ( Object oriented fractal tree ) 
Hice un árbol fractal orientado a objetos en JavaScript utilizando la biblioteca P5, consta de tres archivos: fraternal tree.js sucursal.js flower.js ...

6  Objetos de Java para un programa de sniffer de red  ( Java objects for a network sniffer program ) 
Estoy trabajando en un programa de sniffer de red, cuya estructura utiliza 3 clases principales: clase de marco - uno por marco monitoreado, sostiene la re...

3  General Pathfinder en Python  ( General pathfinder in python ) 
Recientemente trabajé en un proyecto donde tuve la siguiente configuración: $_{456}$6 Ninguno del Código es relevante, no tendrá que poder ejecutar nada...

0  Creación de múltiples objetos del extracto de SQL Server  ( Creating multiple objects from sql server extract ) 
He creado una solución prototipo simplificada como una especie de prueba de concepto antes de comenzar un programa más grande. Aquí están los datos de prueb...

5  ¿Podría mejorarse este sistema de profundidad para un juego?  ( Could this depth system for a game be improved ) 
Todavía soy nuevo en C ++ y no tengo una gran idea de mi codificación, así que estaría muy agradecido a cualquiera y todos los que le otorgan consejos. Ade...

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...




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