[DUDA] Funciones en PHP

Buenas.

Hoy he creado una funcion que me devolviese la cadena de sql para seleccionar de una base de datos. El return seria algo asi: SELECT * FROM tablaquesea WHERE campotal=variabletal.

A esta funcion le paso por parametros varias variables. La primera es los campos que selecciono. La 2a el nombre de la tabla. Y la 3a un array asociativo donde le puedo pasar en el indice el nombre del campo, y con el valor lo que quiero que tenga. Vamos, algo asi:

function funcionseleccion($campos, $tabla, $coincidencias=false) {
...
}


Ya nos han explicado que a una variable recibida por parametro puedes asignarle un valor por defecto, y que si no se la pasas, tomara ese valor. Asi que coincidencias, si no la recibe, toma por valor false.

El problema es que no se como hacer para asignarle un valor por defecto a la 1a o 2a variable. Vamos, en principio supongo que seria igual, en la funcion le asigno un valor como con $coincidencias, y ya. El problema es a la hora de llamar a la funcion. Por que he probado con esto y logicamente no funciona:

function funcionseleccion($campos='*', $tabla, $coincidencias=false) {
...
}

$sql=funcionseleccion(, cliente, $condiciones);


Al no pasarle ningun parametro antes de la coma, me da error. Alguien sabe si esto tiene solucion?

Gracias.
En la definición de la función, los valores predeterminados han de estar a la derecha de los indeterminados.
Podrias explicarmelo mejor? O algun link donde este bien explicado?

Gracias.

Editado:

He encontrado esto:

http://www.desarrolloweb.com/articulos/1484.php

Pero no me queda claro. Significa entonces que la declaracion de la funcion tendria que ser mas o menos asi:

function funcionseleccion($tabla, $campos=unset, $coincidencias=unset) {
...
}


Mmm, entonces si deberia funcionar. Ya que la variable tabla siempre se la tengo que pasar. Y campos y coincidencias podria o no. Pero, estoy en las mismas. Si le quiero pasar tabla y coincidencias, que hago con campos? Por que dependiendo del caso, podria necesitar pasar campos y no coincidencias, y viceversa.
Lo que quiere decir amuchamu (y en C++ creo que también pasa) es que los campos que tengan valores por defecto deben ir "los últimos", por así decirlo en la declaración de la función. De lo contrario, si no te viene bien, "debes" (para apañártelas, vamos) crear otra función con el mismo nombre y con el orden de los atributos cambiados. Ejemplo:

Si tienes

function funcionseleccion($campos='*', $tabla, $coincidencias=false) {
...
}


Nunca podrás hacer esta llamada:

funcionseleccion(,null,null)


porque estás alterando el orden a la hora de definir y pasar parámetros por defecto. Una solución podría ser:

function funcionseleccion($tabla, $campos='*', $coincidencias=false) {
...
}


Vamos, para resumirlo bien, con mis palabras: si al declarar una función le pones un valor predeterminado a uno de los parámetros, todos los parámetros declarados a partir de este deben tener valores predeterminados

Espero haber ayudado, un saludo.
Duqe escribió:Si le quiero pasar tabla y coincidencias, que hago con campos? Por que dependiendo del caso, podria necesitar pasar campos y no coincidencias, y viceversa.


Php no permite argumentos vacíos (f(1,,3)) ni dirigir un argumento de la llamada de la función a cierto argumento de entrada (f(1,$var3=3)), como sí permiten otros lenguajes (python, mismamente). Php tampoco permite sobrecargar funciones, así que la única opción que te queda es hacer otra función, con otro nombre, que llame a la original con los parámetros determinados.

Por ejemplo:

function foo($a, $b=0, $c=1){ ... }

function bar($a, $c){
   foo($a, 0, $c);
}


La primera cubriría ($a), ($a $b), ($a $b $c) y la segunda ($a $c). Es un coñazo, pero que yo sepa no hay otra.

Quedo muy lejos de ser un experto en php así que puede que haya dicho algo que ya no es correcto.

Saludos
Mas o menos lo que me habeis dicho, es lo que me explicaron despues en clase. Si, debo apañarmelas para dejar a la derecha las variables con un valor por defecto. Pero bueno, despues de saber esto, al final me las apañe para que la funcion quedase como esperaba.

Gracias a los 2.
Que yo sepa, PHP al menos el 5, sí soporta polimorfismo.

Puedes hacer dos funciones que se llamen iguales pero con distinta entrada de parámetros y distingue cual tiene que usar.


Un saludo.
Mmmm, mañana lo probare en clase.

Gracias.
Darthgon escribió:Que yo sepa, PHP al menos el 5, sí soporta polimorfismo.

Puedes hacer dos funciones que se llamen iguales pero con distinta entrada de parámetros y distingue cual tiene que usar.


Un saludo.


Eso no es polimorfismo, es sobrecarga de funciones (function overloading). Y no, php no lo soporta para distinto número de argumentos, que sería la única forma de sobrecargar una función en php ya que no es un lenguaje fuertemente tipado.

Ejemplo:

<?

function foo($arg1){
   echo $arg1;
}

function foo($arg1, $arg2){
   echo $arg1, $arg2;
}

foo(1);
foo(1,2);

?>

Resultado:

Fatal error: Cannot redeclare foo() (previously declared in /srv/http/test/overload.php:3) in /srv/http/test/overload.php on line 9

Esto en PHP 5.3.3.
amuchamu escribió:
Darthgon escribió:Que yo sepa, PHP al menos el 5, sí soporta polimorfismo.

Puedes hacer dos funciones que se llamen iguales pero con distinta entrada de parámetros y distingue cual tiene que usar.


Un saludo.


Eso no es polimorfismo, es sobrecarga de funciones (function overloading). Y no, php no lo soporta para distinto número de argumentos, que sería la única forma de sobrecargar una función en php ya que no es un lenguaje fuertemente tipado.

Ejemplo:

<?

function foo($arg1){
   echo $arg1;
}

function foo($arg1, $arg2){
   echo $arg1, $arg2;
}

foo(1);
foo(1,2);

?>

Resultado:

Fatal error: Cannot redeclare foo() (previously declared in /srv/http/test/overload.php:3) in /srv/http/test/overload.php on line 9

Esto en PHP 5.3.3.


Tienes razón, gracias por la iluminación ; )

De la WikiPedia:

Un método está sobrecargado si dentro de una clase existen dos o más declaraciones de dicho método con el mismo nombre pero con parámetros distintos, por lo que no hay que confundirlo con polimorfismo.
¿Entonces qué es el polimorfismo?

Pensé que era lo mismo que sobrecargar la función.
Supón que tienes una clase base con un método, y varias clases derivadas que pueden sobrescribir el método. Puedes tener un objeto de la clase base que en realidad es un objeto de una clase derivada y desde el que puedes llamar al método, eso es el polimorfismo.

Por ejemplo tienes la clase Base, y las clases derivadas Foo y Bar. La clase Base tiene el método imprimir, las clases Foo y Bar tienen su propia implementación (o no) del método. Podrías tener un vector de objetos Base cuyos miembros pueden ser objetos de cualquiera de las 3 clases, y recorrer el vector llamando al método sin importar si el objeto en cuestión es de la clase Base, Foo o Bar.

clase Base{
   método imprimir(){ ... }
}

clase Foo extiende Base{
   sobrescribe método imprimir(){ ... }
}

clase Bar extiende Base{
   ...
}

Base vector[] = { nuevo Base(), nuevo Foo(), nuevo Bar(), ... }

para_cada Base objeto en vector{
   objeto.imprimir()
}
11 respuestas