Autor Tema: [OPINEN] Clase de usuarios  (Leído 3261 veces)

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
[OPINEN] Clase de usuarios
« en: 26 de Junio de 2011, 08:43:29 am »
¡Hola!

Bueno, como muchos sabrán, no soy muy diestro en lo que a programación orientada a objetos se refiere, así que quise superar mis conocimientos y probarme creando una clase para manejo de usuarios.

Para este sistema creé tres clases:
- Usuarios: Permite manejar varios usuarios a la vez.
- Usuario: Permite manejar un usuario específico, así como borrarlo, entre otras funciones.
- Registrar: Inserta un nuevo usuario en la base de datos (Basada en la clase publicada por Physlet)


Clase: clase_usuarios.php

Código: [Seleccionar]
<?php
/* Excepciones en tiempo de ejecución */
// No se encontraron usuarios con el término de búsqueda establecido
class noSeEncontraronUsuarios extends Exception{}

// Error al realizar determinada consulta
class errorMySQLi extends Exception{}

/* Clase para administración de usuarios */
class usuarios
{
protected $mysqli// Objeto de conexión MySQLi
private $condiciones// Condiciones de la búsqueda de usuarios

// Construcción del objeto
function __construct()
{
/* Conexión a MySQLi */
$this->mysqli = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;mysql&#39;,&#39;pruebas&#39;);
}

// Definición de las condiciones para la búsqueda de usuarios
function definirBusqueda($busqueda)
{
$this->condiciones $busqueda;
}

// Devolver un array con los resultados de la búsqueda
function usuariosEncontrados()
{
// Consulta a la base de datos
if($consulta $this->mysqli->query(&#39;SELECT * FROM usuarios &#39;.$this->condiciones))
{
// Si se encontraron resultados...
if($consulta->num_rows)
{
// Se crea un array con los resultados
$resultados = array();

// Se añaden los resultados al array
while($resultado $consulta->fetch_object())
{
$resultados[] = $resultado;
}

return $resultados;
}
else
{
// Si no se encontraron resultados
throw new noSeEncontraronUsuarios;
}
}
else
{
// Si hubo un error MySQLi
throw new errorMySQLi;
}
}

// Finalización de la conexión MySQLi
function cerrar()
{
$this->mysqli->close();
}
}
?>

Modo de uso: les voy a poner un ejemplo en donde muestro todos los usuarios de la base de datos en una tabla, para que entiendan cómo se utiliza la clase.

Código: [Seleccionar]
/<?php
// Llamada al archivo de la clase
require_once(&#39;include/clase_usuarios.php&#39;);

$usuarios = new usuarios// Se instancia el objeto usuarios
$usuarios->definirBusqueda(&#39;ORDER BY id&#39;); // Se definen los términos de la búsqueda

// Bloque Try para el manejo de excepciones
try
{
echo &#39;<table border="1">
<tr>
<td>ID</td>
<td>Nick</td>
<td>Contrasena</td>
</tr>&#39;;

// Se devuelve un array con los usuarios encontrados
$resultados $usuarios->usuariosEncontrados();

// Se crea un bucle para cada resultado obtenido
foreach($resultados as $usuario)
{
// Se muestran los datos
echo &#39;<tr>
<td>&#39;.$usuario->id.&#39;</td>
<td>&#39;.$usuario->nick.&#39;</td>
<td>&#39;.$usuario->contrasena.&#39;</td>
</tr>&#39;;
}

echo &#39;</table>&#39;;
}
catch(
noSeEncontraronUsuarios $e)
{
echo &#39;No se encontraron usuarios.&#39;;
}
catch(
errorMySQLi $e)
{
echo &#39;Ha ocurrido un error al buscar los usuarios.&#39;;
}

$usuarios->cerrar();
?>


Clase: clase_usuario.php

Código: [Seleccionar]
<?php
/* Excepciones en tiempo de ejecución */
// No se encontró el usuario especificado
class usuarioInexistente extends Exception{}

/* Clase para el manejo de usuarios */
class usuario extends usuarios
{
private $idusuario// ID del usuario a trabajar

// Se construye el objeto enviándole por parámetro la ID del usuario
function __construct($idusuario)
{
parent::__construct(); // Se construye la clase padre para poder usar MySQLi
$this->idusuario $this->mysqli->real_escape_string($idusuario);

// Se selecciona la fila de la tabla usuarios
parent::definirBusqueda(&#39;WHERE id = "&#39;.$this->idusuario.&#39;"&#39;);

// Bloque Try para el manejo de excepciones
try
{
// Se devuelve un array con los datos del usuario
$resultados parent::usuariosEncontrados();

// Se crea una variable para cada campo y su valor
foreach($resultados[0] as $campo => $valor)
{
eval(&#39;$this -> &#39;.$campo.&#39; = "&#39;.$valor.&#39;";&#39;);
}
}
catch(noSeEncontraronUsuarios $i)
{
// Si no se ha encontrado el usuario...
throw new usuarioInexistente;
}
}

// Eliminar el usuario
function eliminar()
{
if(!$this->mysqli->query(&#39;DELETE FROM usuarios WHERE id = "&#39;.$this->idusuario.&#39;"&#39;))
{
throw new errorMySQLi;
}
}
}
?>

Modo de uso: en este caso les voy a poner un ejemplo de como usarlo en un miniperfil de usuario, con la opción de borrar el usuario.

Código: [Seleccionar]
<?php
// Llamada a las clases necesarias
require_once(&#39;include/clase_usuarios.php&#39;);
require_once(&#39;include/clase_usuario.php&#39;);

// Si se especificó la ID de usuario por GET()
if(!empty($_GET[&#39;id&#39;]))
{
// Bloque Try para el manejo de excepciones
try
{
$usuario = new usuario($_GET[&#39;id&#39;]); // Se instancia el objeto usuario

// Se imprimen los datos
echo &#39;ID de usuario: &#39;.$usuario->id.&#39;<br />&#39;;
echo &#39;Nombre de usuario: &#39;.$usuario->nick.&#39;<br />&#39;;
echo &#39;Contraseña: &#39;.$usuario->contrasena.&#39;<br /><br />&#39;;
echo &#39;<a href="perfil.php?id=&#39;.$usuario->id.&#39;&borrar=true">Borrar</a>&#39;;

// Si se va a borrar el usuario...
if(!empty($_GET[&#39;borrar&#39;]))
{
// Bloque Try para el manejo de excepciones
try
{
// Se elimina el usuario
$usuario->eliminar();
echo &#39;<br /><br />El usuario ha sido borrado.&#39;;
}
catch(errorMySQLi $e)
{
// Si hubo un error MySQLi...
echo &#39;<br /><br />No se pudo borrar el usuario.&#39;;
}
}
}
catch(usuarioInexistente $e)
{
// Si el usuario no existe...
echo &#39;Este usuario no existe o ha sido borrado.&#39;;
}
catch(errorMySQLi $e)
{
// Si hubo un error MySQLi...
echo &#39;Ha ocurrido un al realizar la consulta&#39;;
}

}
?>


Clase: clase_usuario_registrar.php

Código: [Seleccionar]
<?php
/* Excepciones en tiempo de ejecución */
// Nombre de usuario ya existe
class usuarioNoDisponible extends Exception{}

// Las contraseñas no coinciden
class contrasenasNoCoinciden extends Exception{}

/* Clase para registrar un nuevo usuario */
class registrarUsuario extends usuarios
{
/* Datos a registrar del usuario */
private $usuario;
private $contrasena;

/* Asignación de datos */
function definirDatos($nick$pass)
{
$this->usuario htmlspecialchars($this->mysqli->real_escape_string($nick));
$this->contrasena md5($this->mysqli->real_escape_string($pass));
}

/* Comprobar si un nombre de usuario está disponible */
function comprobarUsuario()
{
$resultado parent::definirBusqueda(&#39;WHERE nick = "&#39;.$this->usuario.&#39;"&#39;);

try
{
if(parent::usuariosEncontrados())
{
throw new usuarioNoDisponible;
}
}
catch(noSeEncontraronUsuarios $i){}
}

/* Comprobar que las dos contraseñas coincidan */
function comprobarContrasena($pass2)
{
if($this->contrasena != md5($this->mysqli->real_escape_string($pass2)))
{
throw new contrasenasNoCoinciden;
}
}

/* Registrar el usuario */
function registrar()
{
if(!$this->mysqli->query(&#39;INSERT INTO usuarios (nick, contrasena) VALUES ("&#39;.$this->usuario.&#39;", "&#39;.$this->contrasena.&#39;")&#39;))
{
throw new errorMySQLi;
}
}
}
?>

Modo de uso: nuevamente, un ejemplo de su utilización en un registro simple.

Código: [Seleccionar]
<?php
// Llamada a las clases necesarias
require_once(&#39;include/clase_usuarios.php&#39;);
require_once(&#39;include/clase_usuario_registrar.php&#39;);

// Si se enviaron el nick y la contraseña por POST()
if(!empty($_POST[&#39;nick&#39;]) && !empty($_POST[&#39;pass&#39;]))
{
$registro = new registrarUsuario// Se instancia el objeto registrarUsuario
$registro->definirDatos($_POST[&#39;nick&#39;], $_POST[&#39;pass&#39;]); // Se definen los datos a insertar

// Bloque Try para el manejo de excepciones
try
{
$registro->comprobarUsuario(); // Comprobamos que el nombre de usuario esté disponible
$registro->comprobarContrasena($_POST[&#39;pass2&#39;]); // Comprobamos que ambas contraseñas sean iguales
$registro->registrar(); // Registramos el usuario

echo &#39;Regitrado exitosamente&#39;;
}
catch(usuarioNoDisponible $e)
{
// Si el nombre de usuario está ocupado...
echo &#39;Este usuario no está disponible.&#39;;
}
catch(contrasenasNoCoinciden $e)
{
// Si las contraseñas no coinciden...
echo &#39;Las contraseñas no coinciden.&#39;;
}
catch(errorMySQLi $e)
{
// Si hubo un error MySQLi...
echo &#39;Ha ocurrido un error al insertar el usuario.&#39;;
}

}
?>

<form method="post">
<input name="nick" value="<?=$_POST['nick']; ?>" />
<input name="pass" value="<?=$_POST['pass']; ?>" />
<input name="pass2"value="<?=$_POST['pass2']; ?>"  />
<input type="submit" value="Registrar" />
</form>

Bueno, espero que me den sus opiniones, críticas, sugerencias, mejoras o lo que quieran para la clase, ésta es una de las primeras que creo y bueno, quiero que opinen jejeje.

Saludos ^^
« Última modificación: 26 de Junio de 2011, 23:02:41 pm por Warlox »
- Moderador de PHP


Comunidad PHPeros

[OPINEN] Clase de usuarios
« en: 26 de Junio de 2011, 08:43:29 am »

Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:[OPINEN] Clase de usuarios
« Respuesta #1 en: 26 de Junio de 2011, 20:52:38 pm »
Solo colocaste la clase de usuarios, creí que publicarías las tres.
¿Por qué el objeto de MySQLi está como protected?

Y bueno, me gustaría ver las otras clases :P!
Por cierto, esto me recuerda que se me han ocurrido algunas cosas para mejorar esa clase de registro que hice en aquella ocasión.

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
Re:[OPINEN] Clase de usuarios
« Respuesta #2 en: 26 de Junio de 2011, 20:56:52 pm »
Las otras aún no las termino jeje, y el objeto MySQLi lo puse como protected para acceder a él desde otras clases por medio de la herencia :P

EDITO EL POST PRINCIPAL: Ya agregué la clase usuario y la clase registrarUsuario, con un ejemplo de su utilización. ;)
« Última modificación: 26 de Junio de 2011, 23:03:15 pm por Warlox »
- Moderador de PHP


Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:[OPINEN] Clase de usuarios
« Respuesta #3 en: 27 de Junio de 2011, 04:46:57 am »
Las otras aún no las termino jeje, y el objeto MySQLi lo puse como protected para acceder a él desde otras clases por medio de la herencia :P
Exactamente por eso te hacía la pregunta.
¿Por qué la clase "usuario" debe heredar de "usuarios"?
No es que diga que esté mal, es que me gusta leer explicaciones de otros para ver cómo analizan las cosas. Este tipo de cosas me ayudan a comprender a los demás y aprender cosas nuevas.

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
Re:[OPINEN] Clase de usuarios
« Respuesta #4 en: 27 de Junio de 2011, 06:59:30 am »
Claro, te explico.  Hay varias razones en realidad jeje.

1- En la clase "usuarios" declaro el objeto MySQLi, para así no tener que estar abriendo la conexión en cada clase distinta.
2- Por el uso de las funciones de búsqueda de la clase usuarios, como puedes ver en la construcción de la clase "usuario":

parent::__construct(); // Se construye la clase padre para poder usar MySQLi
$this->idusuario $this->mysqli->real_escape_string($idusuario);

// Se selecciona la fila de la tabla usuarios
parent::definirBusqueda(&#39;WHERE id = "&#39;.$this->idusuario.&#39;"&#39;);

// Bloque Try para el manejo de excepciones
try
{
	
// Se devuelve un array con los datos del usuario
	
$resultados parent::usuariosEncontrados();
        
// Y ahí el resto del código...
}


¿Entendiste porqué? xD, no sé si me estaré liando solo, pero así se me hace más fácil de entender o.O
- Moderador de PHP


Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:[OPINEN] Clase de usuarios
« Respuesta #5 en: 27 de Junio de 2011, 15:36:37 pm »
En vez de que tengas que llamar al método cerrar() cada vez que terminas el programa, mejor coloca el close() de MySQLi dentro de un destructor (__destruct()) que es aquel método que se ejecuta al destruir un objeto, cuando este ya no es referenciado (garbage collector/recolector de basura).

Y sobre lo otro, entiendo lo que hiciste, pero aún lo estoy analizando un poco mejor porque se me hace que no es la forma correcta de relacionar ambas clases (usuarios y usuario). Cuando termine de analizarlo te doy una respuesta más clara xD... Lo importante es que entiendes los conceptos.

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
Re:[OPINEN] Clase de usuarios
« Respuesta #6 en: 27 de Junio de 2011, 18:42:43 pm »
Vale jeje.

Mira, el mysqli->close() lo puse en el destructor, pero me daba error de MySQLi :S, por eso tuve que crear una función de cierre.
- Moderador de PHP


Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:[OPINEN] Clase de usuarios
« Respuesta #7 en: 27 de Junio de 2011, 20:37:38 pm »
Vale jeje.
Mira, el mysqli->close() lo puse en el destructor, pero me daba error de MySQLi :S, por eso tuve que crear una función de cierre.
¿Ah sí? ¿Qué error era? Está raro :/

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
Re:[OPINEN] Clase de usuarios
« Respuesta #8 en: 29 de Junio de 2011, 02:43:05 am »
Me reitero, lo volví a poner y misteriosamente ya no me da error xD
- Moderador de PHP


Desconectado bryanrq_123

  • PHPerit@
  • *
  • Mensajes: 1
  • Karma: 0
  • Nuev@ PHPer@
    • Ver Perfil
Re:[OPINEN] Clase de usuarios
« Respuesta #9 en: 19 de Agosto de 2011, 20:11:49 pm »
Mae bastante buena la clase, sirve muy bien de ejemplo para iniciar con el trabajo oriendado a objetos de PHP  :P

Desconectado Warlox

  • Moderadores PHP
  • PHPero Master
  • ****
  • Mensajes: 1.278
  • Karma: 77
  • Sexo: Masculino
  • A veces hay que aprender a correr antes de caminar
    • Ver Perfil
    • Página personal
Re:[OPINEN] Clase de usuarios
« Respuesta #10 en: 20 de Agosto de 2011, 03:33:59 am »
Muchas gracias amiguito Bryan, me pareces conocido de algún lado (?)... Jaja no mentira mae pura vida y bienvenido al foro!
- Moderador de PHP


Desconectado SoyJoaquin.

  • PHPero Master
  • ******
  • Mensajes: 2.737
  • Karma: 131
  • Sexo: Masculino
  • ส้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้ส้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้ Problem?
    • Ver Perfil
    • IsoMap
Re:[OPINEN] Clase de usuarios
« Respuesta #11 en: 06 de Octubre de 2011, 18:32:18 pm »
Me reitero, lo volví a poner y misteriosamente ya no me da error xD
¿CIERTO?
Esos errores del carajo lo ponen a uno en un estado desesperante, y mas desesperante es que cuando despues el error desaparece misterosamente y lo hacen ver a uno mismo como un loco ante los demas... :(

No estoy loco, no estoy loco...
Twitter: @JoakoM010