Foros del Web » Programando para Internet » PHP »

mi primera class en PHP

Estas en el tema de mi primera class en PHP en el foro de PHP en Foros del Web. hola amigos. llevo tiempo programando en PHP pero nunca me habia interesado demasiado por las clases y las habia dejado pasar, hasta que hoy se ...
  #1 (permalink)  
Antiguo 09/07/2003, 06:28
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
mi primera class en PHP

hola amigos.
llevo tiempo programando en PHP pero nunca me habia interesado demasiado por las clases y las habia dejado pasar, hasta que hoy se me a ocurrido ponerme a mirar como funcionan y a crear algun ejemplo, bueno he creado un ejemplo de calculadora me gustaria que le echarais un ojo, no pretendo enseñar a los demas(ya que es algo sencillo), quiero que me ayudeis a mi, decidme si habria alguna otra forma de hacerlo, si hay algo erroneo etcetera ;).
hay va el codigo de calculadora.inc.php:

Código PHP:
<?
class calculadora {

// definimos las variables
var $numero1;
var 
$numero2;
var 
$operador;
var 
$error;
var 
$resultado;


//creamos la funcion de calculo
function calcular($num1,$oper,$num2){
    if(empty(
$num1))$this->error .= "Numero1 no definido<br>";
    if(empty(
$num2))$this->error .= "Numero2 no definido<br>";
    if(empty(
$oper))$this->error .= "Operador no definido<br>";
    
    
$this->numero1 $num1;
    
$this->numero2 $num2;
    
$this->operador $oper;
    
    
//calculamos
    
if($this->operador == "+"){
        echo 
$num1+$num2;
    }elseif(
$this->operador == "-"){
        echo 
$num1-$num2;
    }elseif(
$this->operador == "*"){
        echo 
$num1*$num2;
    }elseif(
$this->operador == "/"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            echo 
$num1/$num2;
        }
    }elseif(
$this->operador == "%"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            echo 
$num1%$num2;
        }
    }else{
        
$this->error .= "El operador no es valido<br>";
    }
    
    if(!empty(
$this->error)){
        echo 
"Han ocurrido los siguientes errores:<br>".$this->error;
    }
}


// fin de la clase calculadora

?>
Y esta es la otra pagina, desde la que se carga la clase:

Código PHP:
<?
require ("calculadora.inc.php");
$cal = new calculadora;
$cal->calcular("2","+","3");
?>

Saludos y gracias.
__________________
Zepsilon.com
Diseño e imaginacion
  #2 (permalink)  
Antiguo 09/07/2003, 06:36
Avatar de grovervas
Usuario no validado
 
Fecha de Ingreso: junio-2002
Ubicación: Perú
Mensajes: 306
Antigüedad: 21 años, 10 meses
Puntos: 0
Creo que para empezar esta muy bien tu clase y creo que deberias mejorar un poco en que por cada opcion realizaras una funcion como por ejemplo en ls salida de error, pero es solo una apreciacion y no quiere decir de que lo que hiciste este mal, pero te ayudara mas a comprender el manejo cuando tengas clases complejas.
  #3 (permalink)  
Antiguo 09/07/2003, 07:13
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
gracias, ya de paso me podeis pasar algun manual que explique bien las clases?

bueno ahroa mire esto:
- http://www.php.net/manual/es/language.oop.php

y me kede con las cosas mas claras pero se me dais algun ejemplo o manual cmo dije arriba mejor :D

Última edición por Maycol; 09/07/2003 a las 07:21
  #4 (permalink)  
Antiguo 09/07/2003, 12:21
Avatar de Webstudio
Colaborador
 
Fecha de Ingreso: noviembre-2001
Ubicación: 127.0.0.1
Mensajes: 3.499
Antigüedad: 22 años, 5 meses
Puntos: 69
PAra aprender, nada mejor que el tutorial de Luis Argerich :

http://www.zonaphp.com/index.php?mod...cion=leer&id=1

En castellano y por uno de los más grandes del PHP.
__________________
Tutoriales Photoshop | Web-Studio.com.ar
Artículos PHP | ZonaPHP.com
  #5 (permalink)  
Antiguo 09/07/2003, 12:31
Avatar de Manoloweb  
Fecha de Ingreso: enero-2002
Ubicación: Monterrey
Mensajes: 2.454
Antigüedad: 22 años, 2 meses
Puntos: 5
Solo un comentario...

Por que no le cambias de nombre a la funcion calcular y le pones calculadora? así la conviertes en constructor y puedes usarla así...

Código PHP:
<?
require ("calculadora.inc.php");
$cal = new calculadora("2","+","3");
?>
__________________
Manoloweb
  #6 (permalink)  
Antiguo 09/07/2003, 13:03
Ex Colaborador
 
Fecha de Ingreso: junio-2002
Mensajes: 9.091
Antigüedad: 21 años, 10 meses
Puntos: 16
Hola,

Un consejo, yo quitaria todos los echo de dentro de la clase. Me parece de muy mala educacion (por parte de la clase, no por el programador) que mande salida al navegador cuando simplemente quiero realizar un calculo. Tal como esta para modificar el estilo de la salida deberia modificar tu clase. Y tampoco la podria usar antes de un header(). Pero claro, tu puedes argumentar que es la represenacion grafica de la calculadora.

Sobre el estilo de programacion, cunado veas una cadena de if .. elseif ... comprobando una sola condicion, es mas elegante usar el switch.

Por cierto, tienes una propiedad (o variable miembro) llamada $resultado, pero mandas directamente el resultado por pantalla y no lo almacenas. Deberias almacenarlo en esa variable miembro. Ademas, añadir un nuevo metodo a la clase, que solo acepte 2 parametros, el operador y el segundo operando, y que realice la operacion con el resultado de la operacion anterior como primer operando.

Sobre la OOP (o POO), primero debes entender los conceptos de la orientacion a objetos, y luego ver como se usan en PHP. Si no entiendes el concepto de objeto, dificilmente haras un buen objeto. Simplemente usaras la sintaxis de clases en lugar de funciones.

El articulo de Argerich es un comienzo.

Saludos.
__________________
Josemi

Aprendiz de mucho, maestro de poco.
  #7 (permalink)  
Antiguo 09/07/2003, 14:35
Avatar de Manoloweb  
Fecha de Ingreso: enero-2002
Ubicación: Monterrey
Mensajes: 2.454
Antigüedad: 22 años, 2 meses
Puntos: 5
Bueno Maycol, todo lo que dice Josemi y Webstudio, y seguro Cluster mas tarde, son consejos que debes tomar bien en cuenta, aunque no por eso te desanimes o dejes de intentarlo.

Tu Classe me ha parecido buena, creo que es un buen principio para comenzar en el mundo OOP. Yo mismo apenas he dado mis pininos hace poco, y tengo aún mucho por aprender.

Sigue haciendo objetos, aunque parezcan funciones, pronto iras tomando experiencia e irás refinando tus resultados, pero... NO DEJES DE INTENTARLO!!!

__________________
Manoloweb
  #8 (permalink)  
Antiguo 09/07/2003, 17:56
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
gracias a todos ;)

webstudio mirare ese manual :D
josemi gracias mirare eso, al principio lo metia todo en $resultado pero no se que salia mal, ahora intentare eso de nuevo ;), tambien añadire la nueva funcion para hacer lo ke me dijsite
manoloweb gracias a ti tb por darme animos.

me habeis dado mas animos a si que ala le voy a dar ahora mismo a los objetos ;), cuando lo halla remodelao lo posteo y me comentais ;), demomento seguir comentando el objeto de arriba ;)
  #9 (permalink)  
Antiguo 09/07/2003, 18:01
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
ahh una pregunta si no lo saco con echo con que lo saco??
con print? con return no me funciona :P

lo de return ya entiendo porque no funciona, al hacer la funcion como un contructor al poner un echo fuera del objeto me sale objet y me tocaria crear otra variable con llamando a la funcion de nuevo y ya funciona, o sea esto:

Código PHP:
$cal = new calculadora("2","+","3");
$cal2 $cal->calculadora("2","+","3");
echo 
$cal2
asi si funciona pero para tener que hacer eso prefiero no poner la funcion como un constructor...



ahh sobre lo del swith lo pense pero preferi usas if ya que estoy mas familiarizado con el.

Última edición por Maycol; 09/07/2003 a las 18:13
  #10 (permalink)  
Antiguo 09/07/2003, 18:21
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
a ver que os parece este, lo remodele como dije anteriormente.

Código PHP:
<?
class calculadora {

// definimos las variables
var $numero1;
var 
$numero2;
var 
$operador;
var 
$error;
var 
$resultado;
var 
$retornar;



//creamos la funcion de calculo
function calcular($num1,$oper,$num2){
    if(empty(
$num1))$this->error .= "Numero1 no definido<br>";
    if(empty(
$num2))$this->error .= "Numero2 no definido<br>";
    if(empty(
$oper))$this->error .= "Operador no definido<br>";
    
    
$this->numero1 $num1;
    
$this->numero2 $num2;
    
$this->operador $oper;
    
    
//calculamos
    
if($this->operador == "+"){
        
$this->resultado $this->numero1+$this->numero2;
    }elseif(
$this->operador == "-"){
        
$this->resultado $this->numero1-$this->numero2;
    }elseif(
$this->operador == "*"){
        
$this->resultado $this->numero1*$this->numero2;
    }elseif(
$this->operador == "/"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            
$this->resultado $this->numero1/$this->numero2;
        }
    }elseif(
$this->operador == "%"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            
$this->resultado $this->numero1%$this->numero2;
        }
    }else{
        
$this->error .= "El operador no es valido<br>";
    }
    
    if(!empty(
$this->error)){
        
$this->error .= "Han ocurrido los siguientes errores:<br>";
        
$this->retornar $this->error;
    }else{
        
$this->retornar $this->resultado;
    }
    return 
$this->retornar;
}

//creamos la funcion de calculo teniendo como primer numero el resultado del ultimo calculo
function calcular2($oper,$num2){
    if(empty(
$this->resultado))$this->error .= "No se ha realizado anteriormente un calculo";
    if(empty(
$num2))$this->error .= "Numero2 no definido<br>";
    if(empty(
$oper))$this->error .= "Operador no definido<br>";
    
    
$this->numero2 $num2;
    
$this->operador $oper;
    
    
//calculamos
    
if($this->operador == "+"){
        
$this->resultado $this->resultado+$this->numero2;
    }elseif(
$this->operador == "-"){
        
$this->resultado $this->resultado-$this->numero2;
    }elseif(
$this->operador == "*"){
        
$this->resultado $this->resultado*$this->numero2;
    }elseif(
$this->operador == "/"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            
$this->resultado $this->resultado/$this->numero2;
        }
    }elseif(
$this->operador == "%"){
        if(
$this->numero1 == or $this->numero2 == 0){
            
$this->error .= "No existen divisiones con denominador o numerador igual a 0<br>";
        }else{
            
$this->resultado $this->resultado%$this->numero2;
        }
    }else{
        
$this->error .= "El operador no es valido<br>";
    }
    
    if(!empty(
$this->error)){
        
$this->error .= "Han ocurrido los siguientes errores:<br>";
        
$this->retornar $this->error;
    }else{
        
$this->retornar $this->resultado;
    }
    return 
$this->retornar;
}

// fin de la clase calculadora


$cal = new calculadora;
echo 
$cal->calcular("2","+","3")."<br>".$cal->calcular2("*","2");
?>
__________________
Zepsilon.com
Diseño e imaginacion
  #11 (permalink)  
Antiguo 09/07/2003, 18:34
Avatar de Manoloweb  
Fecha de Ingreso: enero-2002
Ubicación: Monterrey
Mensajes: 2.454
Antigüedad: 22 años, 2 meses
Puntos: 5
Yo te recomiendo (como creo que alguien ya lo hizo)

Que utilices la estructura de switch en lihar de tanto if-- elseif
__________________
Manoloweb
  #12 (permalink)  
Antiguo 09/07/2003, 21:47
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Te faltó un método que llame a tu variable que contiene los errores (mensajes) para mostrarlos cuando y si los requiere el usuario de dicha clase .. algo típo:

Código PHP:
function VerErrores(){
   return 
$this->error;

Así a cada cálculo que hago .. puedo llamar a dicho método para ver si hay errores ..

Una sugerencia más .. El método Calcular() .. podría devolver un "booleano" (FALSE por ejemplo) si el cálculo ha producido un error .. para que luego pueda llamar al método que me muestra el mensaje(s) que tenga .. Ademas q estos podrían estar en un array como para gestionarlos mejor; por ejemplo .. para hacerle un 'extended' a tu classe y tener esos mensajes de error en vários idiomas o fácilmente editables y reusables si alguno se repite" ..

Código PHP:
if ($total=$cal->calcular(....)){
  echo 
"El total es: ".$total;
} else {
echo 
"Hay errores: ".$cal->VerError();

Un saludo,
__________________
Por motivos personales ya no puedo estar con Uds. Fue grato haber compartido todos estos años. Igualmente los seguiré leyendo.
  #13 (permalink)  
Antiguo 09/07/2003, 21:52
Avatar de Webstudio
Colaborador
 
Fecha de Ingreso: noviembre-2001
Ubicación: 127.0.0.1
Mensajes: 3.499
Antigüedad: 22 años, 5 meses
Puntos: 69
Bueno Maycol, si bien el primer intento no estaba del todo mal, ya con el segundo has dado unos pasos para atrás...

Uno de los mejores consejos que me dieron cuando estaba aprendiendo PHP y POO, es que si ves que un método de un objeto te está tomando más de 10 o 15 líneas... entonces que pensara que algo estaba haciendo mal y que viera de separar el metodo en dos o mas. En tu caso, si ves, estás repitiendo el código casi exacto en dos métodos... no te parece extraño ?
no sería mucho pero mucho más sencillo, que calcular2, sea algo como :

Código PHP:
<?php
function calcular2($oper$valor)
{
    return 
$this->calcular($this->resultado$oper$valor);
}
?>
Otro consejo, en POO, antes de escribir código, hay que pensar el doble lo que se va a hacer ANTES.

Otro consejo importante que te puedo dar y que a mi me sirve mucho, es que antes de comenzar a programar un objeto o una clase, es que imagines y pienses que API le vas a dar a ese objeto (o sea, que metodos el objeto queres que tenga, para hacerte el uso sencillo y entendible).

Una de las ventajas increibles que tienen los objetos es que son evolutivos, extensibles... y me parece que tu método "Calcular" hace demasiadas cosas. Yo personalmente, hubiera creado métodos para la suma, la resta, la multiplicacion y la division. Es más, si nos atenemos a la correcta programación de objetos, el método de multiplicacion no serian más que sucesivas llamadas al metodo suma();

Bueno, eso es lo que puedo comentarte de momento, ya sabes, la mejor manera de aprender es practicando, pero en OOP, esto no alcanza, y hay que leer mucho, para escribir poco código.

Saludos.
__________________
Tutoriales Photoshop | Web-Studio.com.ar
Artículos PHP | ZonaPHP.com
  #14 (permalink)  
Antiguo 10/07/2003, 05:07
Avatar de Maycol  
Fecha de Ingreso: diciembre-2001
Ubicación: Ávila (España)
Mensajes: 539
Antigüedad: 22 años, 3 meses
Puntos: 0
gracias por la ayuda de todos ;)
me pondre a leer y a programar sobre objetos y cuando tenga alguna duda o algo interesante ya os comentare
  #15 (permalink)  
Antiguo 10/07/2003, 13:55
Ex Colaborador
 
Fecha de Ingreso: junio-2002
Mensajes: 9.091
Antigüedad: 21 años, 10 meses
Puntos: 16
Hola,

Concepto basico: el constructor solo sirve para inicializar el objeto: dar valores iniciales a las propiedades y demas tareas de inicializacion. Pero no debe devolver nada. En lenguajes compilados te daria un error de compilacion poner un return en un constructor.

Entonces pon un constructor que inicialice las propiedades (pon a 0 los operandos y el resultado, especifica que no esta en error). El calculo lo haces en los otros metodos y usas el return.

Cluster tiene razon con lo de devolver FALSE en caso de error, pero le ha fallado la implementacion. Recuerda que 0 se evalua como FALSE, asi que tendrias que comparar explicitamente y estrictamente (===) con FALSE, ya que creo que 0 es un valor valido que puede retornar el metodo.

Webstudio tiene razon en la implementacion de calcular2(), pero no solo es un fallo de diseño en OOP, tambien en el mundo estructurado (funciones) se intenta reutilizar el codigo. Mas que nada es por mantenimiento. Imaginate que modificas como se realiza el calculo. Si tienes el codigo solo en un metodo, los posibles bugs solo pueden estar en ese trozo de codigo. Si lo tienes puesto en muchos lugares, tendrias que tener cuidado de mantener todos esos trozos iguales en todos los sitios, y eso a veces con las prisas es muy dificil. Asi que para facilitar la vida de los de amntenimiento, repitas codigo innecesariamente.

En lo que no estoy de acuerdo en este caso concreto con Webstudio es con eso de tener una funcion sumar(). Me parece complicar el codigo para una operacion sencilla. Es conocido el termino KISS (Keep It SImple, Stupid: Mantenlo sencillo, no seas estupido). Creo que en este caso aumentaria la complejidad del diseño. En este caso, claro. Si ahora me dices que en lugar de solo hacer operaciones con numeros decimales, tambien va a hacer esas operaciones, pero los operandos pueden ser numeros complejos, en ese caso ya admito que exista una funcion sumar() que se comporte de una forma diferente sea unos operandos decimales o complejos.

Saludos.
__________________
Josemi

Aprendiz de mucho, maestro de poco.
  #16 (permalink)  
Antiguo 10/07/2003, 14:07
Avatar de Webstudio
Colaborador
 
Fecha de Ingreso: noviembre-2001
Ubicación: 127.0.0.1
Mensajes: 3.499
Antigüedad: 22 años, 5 meses
Puntos: 69
Claro josemi, a eso es a lo que me referia, ya pensando en una etapa más avanzada del diseño del objeto, y pensando que se podría incluso mantener el metodo calcular() que solo dependiendo del "signo" del operador, llamara a los métodos sumar, restar, multiplicar, etc...
Uff.. y si ya fueramos "harto" específicos y "correctos", hasta tendría que tener una clase Sumador, otra Restador, etc.. pero ya no le compliquemos la vida ( por ahora ).
Saludos.
__________________
Tutoriales Photoshop | Web-Studio.com.ar
Artículos PHP | ZonaPHP.com
  #17 (permalink)  
Antiguo 10/07/2003, 14:23
Avatar de Pino  
Fecha de Ingreso: abril-2003
Ubicación: Cangas do Morrazo, Pontevedra, Galicia, España, Europa, etc
Mensajes: 490
Antigüedad: 21 años
Puntos: 0
Hola, ya se que como siempre vengo a dar la vara pero... ¿que ventajas tiene hacer clases?

Un saludo
__________________
Pïno
Webmaster de Programas Lynx
Usuario Registrado de Linux #327681

Mi cuerpo en windows, pero mi mente pensando en linux.
  #18 (permalink)  
Antiguo 11/07/2003, 04:22
Avatar de epplestun  
Fecha de Ingreso: octubre-2001
Mensajes: 1.621
Antigüedad: 22 años, 5 meses
Puntos: 5
Una idea asi para que quede mas bonito , tu calculadora solo deja operar con dos numeros, que pasa si queremos operar con 20?¿ o con 100 o con 3 jeje, bueno el caso es: en el metodo que usas para hacer los calculos yo no le pondria un numero de parametros fijos, es decir le indicaria uno, que seria el operador y el resto se los pondria asi sin mas, recorriendo los datos y almacenandolos en un array, en vez de en variables de la clase, de esa manera podras trabajar con todos los numeros que quieras.

La idea seria:

Código PHP:
class calculadora
{
var 
$_numeros = array();
var 
$_total;
function 
calculadora()
{
$this->_numeros func_get_args ();
}
function 
calcular($operador)
{
switch(
$operador)
{
case 
'+': foreach($this->_numeros as $numero){ $this->_total += $numero} break;
case 
'-':   foreach($this->_numeros as $numero){ $this->_total -= $numero} break;
case 
'/':   foreach($this->_numeros as $numero){ $this->_total /= $numero} break;
case 
'*':  foreach($this->_numeros as $numero){ $this->_total *= $numero} break;

return 
$this->_total;
}

Esa seria la idea mas o menos, el codigo no creo que sea funcional ya que ni lo e probado lo e ido escribiendo al vuelo, pero espero que te sirva la idea.
__________________
Usuario registrado de Linux #288725
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:32.