jueves, 7 de marzo de 2013

Recomendada programacion orientada a objetos PHP

Ya hace un tiempo que programo con PHP, cerca de 2 años, el tema es que hasta hace 1 mas o menos no comprendía los beneficios de programar orientado a objetos (Ojo no soy un purista de esto, si me queda mas sencillo resolver algo proceduralmente lo haría sin ponerme colorado). 

La estructura basica que estoy usando es una forma de "modelado" en la cual por cada clase tengo dos clases, una que se ocupa de toda la comunicacion con la Base de datos y otra que es el objeto propiamente dicho al cual simplemente le envio mensajes tales como:
  • $usr = Usuario::obtenerPorId($id) y me devuelve un objeto Usuario al cual luego le puedo hacer cosas tales como  $usr->getNick() y me devolvería el nombre de usuario.. :)
Entonces si vamos al ejemplo de la clase usuario tendría las siguiente clases:
  • Usuario.php
  • dUsuario.php
Con estas clases podria resolver toda la lógica. 

La clase Usuario tendría toda la lógica incluyendo los geters y los seters y se ocuparía de hacer el mapeo a objetos de las tablas relacionales. 
Yo para hacer esto suelo tener un método estático que se ocupa de hacer dicho mapeo.
Simplemente le paso un registro de la base de datos obtenido con mysql_fetch_array o con mysqli.. :)

public static function  mapearTablaConObjeto($reg){
    $usuario = New Usuario();
    $usuario->setNick($reg["nombre"]);
    $usuario->setMail($reg["mail"]);
    $usuario->setPass($reg["clave"]);
    $usuario->setSid($reg["sid"]);
    $usuario->setIp($reg["ip"]);
    $usuario->setIdUsuario($reg["idUsuario"]);
    $usuario->setUltimaAccion($reg["ultima_accion"]);
    $usuario->setOnline($reg["online"]);
    $usuario->setPerfil($reg["perfil"]);
    return $usuario;
}

Basicamente la clase Usuario suele devolver un usuario en particular o un arreglo de varios usuarios.
Para mostrar un ejemplo voy a poner obtenerUsuarioPorId($id)

    /*
     * OBTIENE UN USUARIO A PARTIR DE UN ID
     */
    public static function obtenerUsuarioPorId($idUsuario){
        $reg_usuario = dObtenerUsuarioPorId($idUsuario);
if(!is_null($reg_usuario)){
    return Usuario::mapearTablaConObjeto($reg_usuario);
}
return NULL;
    }

Aquí lo que se hace es llamar a la función que se encuentra en dUsuario.php y se ocupa de obtener un usuario de la Base de Datos. 

Nota: Es importante que los datos lleguen validados. Es decir que si tiene que entrar un entero, sea un entero y que si tiene que ser una cadena sea una cadena valida. 

La función dObtenerUsuarioPorId($idUsuario) se veria como sigue:

function  dObtenerUsuarioPorId ($id){

    global $conexion;

    $registros = mysql_query("select * from usuarios 
                              where idUsuario=$id",$conexion) or
    die("Problemas en el select USUARIO:".mysql_error());
    if(mysql_num_rows($registros))
return mysql_fetch_array($registros);
    return NULL;
}

Puede verse que la dObtenerUsuarioPorId obtiene un usuario por un id, y en caso de que no recupere ninguno devuelve NULL, la funcion obtenerUsuarioPorId si recibe NULL devuelve NULL y si recibe un registro hace el mapeo y devuelve el objeto usuario!! para ser utilizado como plazca. 

Luego se podrían hacer cosas tales como:

include_once "Usuario.php";

$usr = Usuario::obtenerUsuarioPorId(1);
if(!is_null($usr)){
    echo $usr->getNick();   // Muestra el nick del usuario 1
    // Cambio el nick del objeto pero no lo persisto en la BD
    $usr->setNick("Otro nick");  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Vuelvo a obtener el usuario 1
    // Como no lo habia guardado en la BD vuelvo a mostrar el nick del usuario 1
    echo $usr->getNick(); 
    // Cambio el nick del objeto pero aún no lo persisto en la BD
    $usr->setNick("Otro nick"); 
    // Guardo los cambios en la BD. Si el usr->isNew() inserto sino actualizo
    $usr->save();  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Obtengo el usuario 1.
    echo $usr->getNick();   // Muestro "Otro nick" porque ya habia guardado los cambio. :) 
}

Espero que se haya entendido más o menos cual es mi idea, porque fue una explicación medio rapida.. :).. cualquier consulta hagan!. jeje 

Saludos! 

El proyecto de un juego de navegador

Bueno el proyecto del juego de navegador quedara relegado por el momento... :). es necesario a mi entender tener ciertos privilegios sobre la Base de Datos que en el servicio de hosting con el que cuento no los tienen (Y tampoco tengo el dinero para invertir, no es mucho pero tengo otras prioridades por el momento).

Para hacer que un juego on-line funcione, le cuento a los mas despistados tienen que resolver casi todo del lado del servidor sin estar obligado a que el usuario intervenga ni este conectado.
El usuario simplemente ejecuta una acción

Por ejemplo:

  • Transportar recursos o realizar un ataque.

Pero no tiene que ejecutar ninguna acción para que el transporte llegue a destino, simplemente envía y espera a que pase el tiempo necesario para que la acción concluya, el usuario puede estar conectado o fuera de linea al momento de la llegada, pero lo que es seguro es que la acción debe finalizar igual.. :)

La forma que encontré de desarrollar esta "Asincronidad" o "Desatendimiento" de las acciones fue utilizar Eventos de la Base de datos.. :)

En un primero momento lo hacia con javascript que cuando viera que se terminaba un tiempo revisara que se había finalizado... perooooo eso obliga al usuario a estar conectado o al menos con el navegador abierto.. jejeje detalles de diseño..

Si a alguno se le ocurre otra idea bienvenida, pense en usar Cron pero no hubo caso.