PHP global en funciones


100

¿Cuál es la utilidad de la palabra clave global ?

¿Hay alguna razón para preferir un método a otro?

  • ¿Seguridad?
  • ¿Actuación?
  • ¿Algo más?

Método 1:

function exempleConcat($str1, $str2)
{
  return $str1.$str2;
}

Método 2:

function exempleConcat()
{
  global $str1, $str2;
  return $str1.$str2;
}

¿Cuándo tiene sentido usarlo global?

Para mí, parece peligroso ... pero puede ser solo una falta de conocimiento. Estoy interesado en razones técnicas documentadas (por ejemplo, con ejemplo de código, enlace a documentación ...).

¡Gracias por adelantado!


Generosidad

Esta es una buena pregunta general sobre el tema, yo (@Gordon) estoy ofreciendo una recompensa para obtener respuestas adicionales. No importa si su respuesta está de acuerdo con la mía o da un punto de vista diferente. Dado que el globaltema surge de vez en cuando, podríamos usar una buena respuesta "canónica" para enlazar.


2
Eche un vistazo a este enlace: stackoverflow.com/questions/1557787 Hay muchos artículos relacionados en la parte inferior derecha de esta página
JohnP

No es una respuesta directa a su pregunta, pero lea esta pregunta SO anterior .
Ólafur Waage

1
Entonces, no puedo leer ninguna palabra clave pro-global. 1) Por qué está aquí. 2) ¿Por qué la gente lo usa?
Pascal Qyy

@ G.Qyy ¿Por qué hay goto? ¿Por qué la gente lo usa? No lo usan (al menos espero): P
PeeHaa

A fines del año pasado (14 de diciembre), alguien rechazó esta pregunta. Me interesa mucho saber por qué, porque todos los puntos de vista, incluidos los negativos, son interesantes. ¡En este caso más que nunca! Estaré muy agradecido por cualquier pista al respecto.
Pascal Qyy

Respuestas:


158

Los globales son malvados

Esto es cierto para la globalpalabra clave, así como para todo lo demás que va desde un alcance local hasta el alcance global (estática, singletons, registros, constantes). No quieres usarlos. Una llamada a función no debería tener que depender de nada externo, por ejemplo

function fn()
{
    global $foo;              // never ever use that
    $a = SOME_CONSTANT        // do not use that
    $b = Foo::SOME_CONSTANT;  // do not use that unless self::
    $c = $GLOBALS['foo'];     // incl. any other superglobal ($_GET, …)
    $d = Foo::bar();          // any static call, incl. Singletons and Registries
}

Todo esto hará que su código dependa del exterior. Lo que significa que debe conocer el estado global completo en el que se encuentra su aplicación antes de poder llamar de manera confiable a cualquiera de estos. La función no puede existir sin ese entorno.

El uso de superglobales puede no ser un defecto obvio, pero si llama a su código desde una línea de comandos, no tiene $_GETo $_POST. Si su código se basa en la entrada de estos, se está limitando a un entorno web. Simplemente abstraiga la solicitud en un objeto y utilícelo en su lugar.

En caso de acoplar nombres de clases codificados de forma rígida (estáticos, constantes), su función tampoco puede existir sin que esa clase esté disponible. Eso es un problema menor cuando se trata de clases del mismo espacio de nombres, pero cuando comienzas a mezclar desde diferentes espacios de nombres, estás creando un lío enredado.

La reutilización se ve gravemente obstaculizada por todo lo anterior. También lo es la prueba unitaria .

Además, las firmas de sus funciones mienten cuando se acopla al alcance global

function fn()

es un mentiroso, porque afirma que puedo llamar a esa función sin pasarle nada. Es solo cuando miro el cuerpo de la función que aprendo que tengo que configurar el entorno en un cierto estado.

Si su función requiere argumentos para ejecutarse, explíquelos y páselos:

function fn($arg1, $arg2)
{
    // do sth with $arguments
}

transmite claramente de la firma lo que requiere para ser llamado. No depende del medio ambiente estar en un estado específico. No tienes que hacer

$arg1 = 'foo';
$arg2 = 'bar';
fn();

Es una cuestión de introducir (palabra clave global) frente a introducir (argumentos). Cuando empuja / inyecta dependencias, la función ya no depende del exterior. Cuando lo hace fn(1), no tiene que tener una variable que contenga 1 en algún lugar exterior. Pero cuando ingresa global $onedentro de la función, se acopla al alcance global y espera que tenga una variable de eso definida en algún lugar. Entonces, la función ya no es independiente.

Peor aún, cuando está cambiando globales dentro de su función, su código rápidamente será completamente incomprensible, porque sus funciones están teniendo efectos secundarios por todas partes.

A falta de un mejor ejemplo, considere

function fn()
{
    global $foo;
    echo $foo;     // side effect: echo'ing
    $foo = 'bar';  // side effect: changing
}

Y luego lo haces

$foo = 'foo';
fn(); // prints foo
fn(); // prints bar <-- WTF!!

No hay forma de ver que $foocambió de estas tres líneas. ¿Por qué llamar a la misma función con los mismos argumentos cambiaría repentinamente su salida o cambiaría un valor en el estado global? Una función debería hacer X para una entrada definida Y. Siempre.

Esto se vuelve aún más severo cuando se usa OOP, porque OOP se trata de encapsulación y al llegar al alcance global, está rompiendo la encapsulación. Todos estos Singletons y Registries que ve en los frameworks son olores de código que deben eliminarse a favor de la inyección de dependencia. Desacople su código.

Más recursos:


10
¿Por qué PHP implementa tales cosas? ¿Existe alguna utilidad? Siempre me sorprendieron las implementaciones peligrosas en PHP que mucha gente usa cada vez ... ¡Es difícil para mí creer que no hay razones lógicas!
Pascal Qyy

5
Ojalá pudieras hacer que los Globals sean malvados más grandes.
Kermit

3
Vaya, finalmente alguien me explicó bien por qué los globales son malvados ... Siempre escuché que lo eran y vi algunos ejemplos muy muy específicos de por qué, pero esta es realmente una buena y completa explicación de la razón general. +1
Wingblade

Llego muy tarde y entiendo lo que dices, pero ¿qué hay de las conexiones mysqli? ¿Deberían pasarse como un parámetro cada vez, o es un enlace $ global? permitido en tus ojos?
Mave

2
Tienes razón, excepto por las constantes. No representan un "estado" de la aplicación y está bien hacer referencia a ellos desde una función. La función no "miente" si usa una constante desde adentro. Estoy de acuerdo en que implica que el programador en un momento tuvo conocimiento del exterior, pero esa es una compensación muy aceptable por lo que es una constante. Además, en serio, no es un gran problema.
Sebas

35

La única razón importante en contra globales que significa que la función depende de otro alcance. Esto se complicará muy rápidamente.

$str1 = 'foo';
$str2 = 'bar';
$str3 = exampleConcat();

vs.

$str = exampleConcat('foo', 'bar');

Requerir $str1y $str2estar configurado en el alcance de llamada para que la función funcione significa que introduce dependencias innecesarias. Ya no puede cambiar el nombre de estas variables en este ámbito sin renombrarlas también en la función y, por lo tanto, también en todos los demás ámbitos que esté utilizando esta función. Esto pronto se convierte en un caos cuando intentas realizar un seguimiento de los nombres de las variables.

globales un mal patrón incluso para incluir elementos globales como los $dbrecursos. No habrá llegado el día en el que desea cambiar el nombre $db, pero no puede, porque toda su aplicación depende del nombre.

Limitar y separar el alcance de las variables es esencial para escribir cualquier aplicación medianamente compleja.


1
Lo siento, pero ¿por qué definitivamente querría cambiar el nombre $db? Es la DOP, que se transmite por todas partes. ¿Por qué se cambiaría cuando puedo actualizar la información de conexión por separado?
Casey Dwayne

3
@kcd ¿Porque un día te das cuenta de lo grande que es la inyección de dependencias y quieres reestructurar tu aplicación? ¿Porque algún día necesitarás integrar tus cosas con otras cosas que también usan una $dbvariable global ? ¿Porque algún día descubrirá las pruebas unitarias y necesitará administrar más de una conexión de base de datos a la vez para eso? Muchas, muchas razones.
diciembre

35

Los globales son inevitables.

Es una discusión antigua, pero aún me gustaría agregar algunos pensamientos porque los extraño en las respuestas mencionadas anteriormente. Esas respuestas simplifican demasiado lo que es global y presentan soluciones que no son en absoluto soluciones al problema. El problema es: ¿cuál es la forma correcta de tratar una variable global y el uso de la palabra clave global? Para eso, primero tenemos que examinar y describir qué es un global.

Eche un vistazo a este código de Zend y comprenda que no sugiero que Zend esté mal escrito:

class DecoratorPluginManager extends AbstractPluginManager
{
/**
 * Default set of decorators
 *
 * @var array
 */
protected $invokableClasses = array(
    'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
    'htmltag'   => 'Zend\Tag\Cloud\Decorator\HtmlTag',
    'tag'       => 'Zend\Tag\Cloud\Decorator\HtmlTag',
   );

Aquí hay muchas dependencias invisibles. Esas constantes son en realidad clases. También puede ver require_once en algunas páginas de este marco. Require_once es una dependencia global, por lo que crea dependencias externas. Eso es inevitable para un marco. ¿Cómo se puede crear una clase como DecoratorPluginManager sin una gran cantidad de código externo del que depende? No puede funcionar sin muchos extras. Usando el framework Zend, ¿alguna vez ha cambiado la implementación de una interfaz? Una interfaz es, de hecho, global.

Otra aplicación utilizada a nivel mundial es Drupal. Están muy preocupados por el diseño adecuado, pero al igual que cualquier gran marco, tienen muchas dependencias externas. Eche un vistazo a los globales en esta página:

/**
 * @file
 * Initiates a browser-based installation of Drupal.
 */

/**
 * Root directory of Drupal installation.
 */
define('DRUPAL_ROOT', getcwd());

/**
 * Global flag to indicate that site is in installation mode.
 */
define('MAINTENANCE_MODE', 'install');

// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
  print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the     <a     href="http://drupal.org/requirements">system requirements</a> page for more     information.';
  exit;
}

// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();

¿Alguna vez ha escrito una redirección a la página de inicio de sesión? Eso está cambiando un valor global. (Y luego no está diciendo 'WTF', que considero una buena reacción a la mala documentación de su aplicación). El problema con los globales no es que sean globales, los necesita para tener una aplicación significativa. El problema es la complejidad de la aplicación general, lo que puede convertirla en una pesadilla de manejar. Las sesiones son globales, $ _POST es global, DRUPAL_ROOT es global, includes / install.core.inc 'es un global no modificable. Hay un gran mundo fuera de cualquier función que se requiera para que esa función haga su trabajo.

La respuesta de Gordon es incorrecta, porque sobrevalora la independencia de una función y llamar mentirosa a una función simplifica demasiado la situación. Las funciones no mienten y cuando echas un vistazo a su ejemplo, la función está diseñada incorrectamente; su ejemplo es un error. (Por cierto, estoy de acuerdo con esta conclusión de que se debe desacoplar el código). La respuesta de deceze no es realmente una definición adecuada de la situación. Las funciones siempre funcionan dentro de un ámbito más amplio y su ejemplo es demasiado simplista. Todos estaremos de acuerdo con él en que esa función es completamente inútil, porque devuelve una constante. Esa función es de todos modos un mal diseño. Si quiere demostrar que la práctica es mala, por favor venga con un ejemplo relevante. Cambiar el nombre de las variables a lo largo de una aplicación no es gran cosa teniendo un buen IDE (o una herramienta). La pregunta es sobre el alcance de la variable, no la diferencia de alcance con la función. Hay un momento adecuado para que una función desempeñe su papel en el proceso (por eso se crea en primer lugar) y en ese momento adecuado puede influir en el funcionamiento de la aplicación en su conjunto, por lo que también se trabaja en variables globales. . La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas: de ahí que también trabajemos en variables globales. La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas: de ahí que también trabajemos en variables globales. La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas:

function xzy($var){
 global $z;
 $z = $var;
}

function setZ($var){
 $this->z = $var;
}

En ambos casos, el valor de $ z cambia dentro de una función específica. En ambas formas de programación, puede realizar esos cambios en muchos otros lugares del código. Se podría decir que usando global podrías llamar a $ z en cualquier lugar y cambiar allí. Sí tu puedes. ¿Pero lo harás? Y cuando se hace en lugares inapropiados, ¿no debería llamarse error?

Bob Fanger comenta sobre xzyfer.

¿Alguien debería usar algo y especialmente la palabra clave 'global'? No, pero como cualquier tipo de diseño, intenta analizar de qué depende y qué depende de él. Intente averiguar cuándo cambia y cómo cambia. El cambio de valores globales solo debería ocurrir con aquellas variables que pueden cambiar con cada solicitud / respuesta. Es decir, solo a aquellas variables que pertenecen al flujo funcional de un proceso, no a su implementación técnica. El redireccionamiento de una URL a la página de inicio de sesión pertenece al flujo funcional de un proceso, la clase de implementación utilizada para una interfaz para la implementación técnica. Puede cambiar este último durante las diferentes versiones de la aplicación, pero no debe cambiarlas con cada solicitud / respuesta.

Para comprender mejor cuándo es un problema trabajar con globales y la palabra clave global y cuándo no, presentaré la siguiente oración, que proviene de Wim de Bie cuando escribo sobre blogs: 'Personal sí, privado no'. Cuando una función está cambiando el valor de una variable global en aras de su propio funcionamiento, entonces llamaré a ese uso privado de una variable global y un error. Pero cuando el cambio de la variable global se realiza para el correcto procesamiento de la aplicación en su conjunto, como la redirección del usuario a la página de inicio de sesión, entonces es que en mi opinión posiblemente sea un buen diseño, no por definición malo y ciertamente no una anti-patrón.

En retrospectiva a las respuestas de Gordon, deceze y xzyfer: todos tienen 'sí privados' (y errores) como ejemplos. Por eso se oponen al uso de globales. Yo también lo haría. Sin embargo, no vienen con ejemplos de 'sí personal, no privado' como lo he hecho en esta respuesta varias veces.


La muestra de código de Drupal no usa globales, usa constantes. Una diferencia muy importante es que una constante no se puede redefinir una vez definida. Además, no puede simplemente comparar las funciones xyzy setZ. El primero cambia el estado global, el segundo es un método de clase y solo cambia el estado de la instancia a la que se llamó.
Arjan

@Arjen: si busca la palabra clave global en Drupal 7.14, obtendrá cientos de resultados. Es un viejo problema con los montadores públicos: no controlas el lugar donde se cambian una vez que los has hecho públicos. Se ha aconsejado no utilizarlos en absoluto o declararlos privados, por lo que no se puede añadir más tarde.
Loek Bergman

@Arjan: debido a mi error con la ortografía de su nombre, ¿no recibió ninguna notificación de mi respuesta? Ahora lo harás. :-)
Loek Bergman

@LoekBergman: Hay alrededor de 400 accesos para la palabra globalen drupal 7.26 (que es la última versión), algunos de esos accesos están en los comentarios y varios otros parecen estar en un código que no se ha tocado durante años. Espero que no usen globals en drupal 8.
Arjan

@LoekBergman Utilice setters y getters. No toma mucho tiempo configurarlo y permite que otros que están usando su código y quizás extendiendo sus clases tengan más control. Una vez que haces público un parámetro, eso es todo. no tiene la opción de ocultarlo más adelante.
mAsT3RpEE

15

En pocas palabras, rara vez hay una razón para hacerlo globaly nunca una buena en el código PHP moderno en mi humilde opinión. Especialmente si está usando PHP 5. Y más especialmente si está desarrollando código orientado a objetos.

Los globales afectan negativamente la capacidad de mantenimiento, la legibilidad y la capacidad de prueba del código. Muchos usos de globalcan y deben reemplazarse con Dependency Injection o simplemente pasando el objeto global como parámetro.

function getCustomer($db, $id) {
    $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
    return $row;
}

10

No dude en utilizar palabras clave globales dentro de funciones en PHP. Especialmente no tome a las personas que están predicando / gritando de manera extravagante cómo los globales son 'malvados' y todo eso.

En primer lugar, porque lo que usa depende totalmente de la situación y el problema, y ​​NO hay una única solución / forma de hacer nada en la codificación. Dejando totalmente a un lado la falacia de los adjetivos religiosos indefinibles, subjetivos como "maldad" en la ecuación.

Caso en punto :

Wordpress y su ecosistema utilizan palabras clave globales en sus funciones. Sea el código OOP o no OOP.

Y a partir de ahora Wordpress es básicamente el 18,9% de Internet, y está ejecutando los mega sitios / aplicaciones masivos de innumerables gigantes que van desde Reuters a Sony, a NYT, a CNN.

Y lo hace bien.

El uso de palabras clave globales dentro de las funciones libera a Wordpress de la hinchazón MASIVA que sucedería dado su enorme ecosistema. Imagine que cada función pregunta / pasa cualquier variable que se necesita de otro complemento, núcleo y regresa. Agregado con interdependencias de complementos, eso terminaría en una pesadilla de variables o una pesadilla de matrices pasadas como variables. Un infierno que rastrear, un infierno que depurar, un infierno que desarrollar. Huella de memoria increíblemente masiva debido a la hinchazón del código y la hinchazón variable también. Más difícil de escribir también.

Puede que haya personas que se acerquen y critiquen Wordpress, su ecosistema, sus prácticas y lo que sucede en esos lugares.

No tiene sentido, ya que este ecosistema es casi el 20% de Internet. Aparentemente, sí funciona, hace su trabajo y más. Lo que significa que es lo mismo para la palabra clave global.

Otro buen ejemplo es el fundamentalismo de "los iframes son malos". Hace una década era una herejía utilizar iframes. Y había miles de personas predicando contra ellos en Internet. Luego viene Facebook, luego vienen las redes sociales, ahora los iframes están en todas partes, desde los cuadros de 'me gusta' hasta la autenticación, y listo, todos cállate. Hay quienes todavía no se callaron, con razón o sin ella. Pero sabes qué, la vida continúa a pesar de esas opiniones, e incluso los que predicaban contra los iframes hace una década ahora tienen que usarlos para integrar varias aplicaciones sociales a las aplicaciones de su organización sin decir una palabra.

......

El fundamentalismo del codificador es algo muy, muy malo. Un pequeño porcentaje entre nosotros puede estar agraciado con el cómodo trabajo en una sólida empresa monolítica que tiene suficiente influencia para soportar el cambio constante en la tecnología de la información y las presiones que trae con respecto a la competencia, el tiempo, el presupuesto y otras consideraciones, y por lo tanto puede practicar. fundamentalismo y adhesión estricta a los "males" o "bienes" percibidos. Posiciones cómodas que recuerdan a la vejez, incluso si los ocupantes son jóvenes.

Sin embargo, para la mayoría, el mundo de las tecnologías de la información es un mundo en constante cambio en el que necesitan ser prácticos y de mente abierta. No hay lugar para el fundamentalismo, deje de lado palabras clave indignantes como "maldad" en las trincheras de primera línea de la tecnología de la información.

Simplemente use lo que tenga más sentido para el problema A MANO, con las consideraciones adecuadas para el futuro a corto, mediano y largo plazo. No evite usar ninguna función o enfoque porque tiene una animosidad ideológica desenfrenada en su contra, entre cualquier subconjunto de codificadores.

No harán tu trabajo. Vas a. Actúe de acuerdo a sus circunstancias.


3
+1 para anti-fundamentalismo y demás, pero decir simplemente "mucha gente lo usa / funciona / etc" es solo un "argumentum ad populum", un sofisma básico. ¡El hecho de que la mayoría de la gente piense o haga algo no prueba que tengan razón! en una multitud, si aparece un peligro, la mayoría de la gente hará cosas estúpidas, y algunas personas morirán pisoteadas por otras. ¿Tienen razón al poner un pie en la cara de esta niña de cinco años solo porque piensan que deben empujar una puerta que solo se abre si se tira para escapar del fuego? No lo creo…
Pascal Qyy

1
la mayoría haciendo algo, por supuesto, no valida nada por sí mismo. sin embargo, el caso es software. y si la mayoría lo está haciendo, y la mayoría de las aplicaciones y servicios creados por estas personas funcionan bien (wordpress para muchos otros), entonces significa que pueden usarse.
unity100

7

Creo que todo el mundo ha expuesto bastante sobre los aspectos negativos de los globales. Así que agregaré los aspectos positivos, así como las instrucciones para el uso adecuado de los globales:

  1. El objetivo principal de los globales era compartir información entre funciones. cuando no había nada como una clase, el código php consistía en un montón de funciones. A veces, necesitaría compartir información entre funciones. Por lo general, se utilizó el global para hacer esto con el riesgo de que los datos se corrompan al convertirlos en globales.

    Ahora, antes de que un simpleton feliz y afortunado comience un comentario sobre la inyección de dependencias, me gustaría preguntarle cómo el usuario de una función como ejemplo get_post(1)conocería todas las dependencias de la función. También considere que las dependencias pueden diferir de una
    versión a otra y de un servidor a otro. El principal problema con la inyección de dependencias es que las dependencias deben conocerse de antemano. En una situación en la que esto no es posible o las variables globales no deseadas eran la única forma de lograr este objetivo.

    Debido a la creación de la clase, ahora las funciones comunes se pueden agrupar fácilmente en una clase y compartir datos. A través de implementaciones como Mediators, incluso los objetos no relacionados pueden compartir información. Esto ya no es necesario.

  2. Otro uso de los globales es para fines de configuración. Principalmente al comienzo de un script antes de que se hayan cargado los cargadores automáticos, se hayan realizado las conexiones a la base de datos, etc.

    Durante la carga de recursos, los globales se pueden usar para configurar datos (es decir, qué base de datos usar donde se encuentran los archivos de la biblioteca, la URL del servidor, etc.). La mejor forma de hacerlo es mediante el uso de la define()función, ya que estos valores no cambian con frecuencia y se pueden colocar fácilmente en un archivo de configuración.

  3. El uso final de los globales es contener datos comunes (es decir, CRLF, IMAGE_DIR, IMAGE_DIR_URL), indicadores de estado legibles por humanos (es decir, ITERATOR_IS_RECURSIVE). Aquí los globales se utilizan para almacenar información que está destinada a ser utilizada en toda la aplicación, lo que permite que se modifiquen y que esos cambios aparezcan en toda la aplicación.

  4. El patrón singleton se hizo popular en php durante php4 cuando cada instancia de un objeto ocupaba memoria. El singleton ayudó a ahorrar RAM al permitir que solo se creara una instancia de un objeto. Antes de las referencias, incluso la inyección de dependencia habría sido una mala idea.

    La nueva implementación php de objetos de PHP 5.4+ se encarga de la mayoría de estos problemas, ya que puede pasar objetos de forma segura con poca o ninguna penalización. Esto ya no es necesario.

    Otro uso para singletons es la instancia especial donde solo debe existir una instancia de un objeto a la vez, esa instancia puede existir antes / después de la ejecución del script y ese objeto se comparte entre diferentes scripts / servidores / lenguajes, etc.Aquí un patrón singleton resuelve el solución bastante bien.

Entonces, en conclusión, si está en la posición 1, 2 o 3, entonces usar un global sería razonable. Sin embargo, en otras situaciones se debe utilizar el método 1.

No dude en actualizar cualquier otra instancia en la que se deban utilizar globales.


6

No tiene sentido hacer una función concat usando la palabra clave global.

Se utiliza para acceder a variables globales como un objeto de base de datos.

Ejemplo:

function getCustomer($id) {
  global $db;
  $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
  return $row;
}

Se puede utilizar como una variación del patrón Singleton.


"no tiene sentido" - en realidad lo tiene: un ejemplo será la implementación de una tabla de búsqueda sin usar OOP.
Nir Alfasi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.