2010-12-07 21 views
5

Estoy trabajando en PHP.Variable estática en función establecida llamando a otra función

Tengo una función (F1) que se llama una cantidad variable de veces. Dentro de esa función, necesito cargar un conjunto de datos constante desde otra función (F2). Siempre es el mismo conjunto de datos cargado, sin embargo, cargar el conjunto implica algunas búsquedas y procesamiento de la base de datos. En lugar de llamar repetidamente a F2 y aumentar los requisitos de sobrecarga/redundancia/procesamiento, me gustaría poner el resultado en una variable estática en F1. Sin embargo, por cualquier razón, no me permitirá establecer la variable como estática utilizando la llamada a la función.

Un ejemplo de código:

function calledRepeatedly() { 
    static $dataset = loadDataset(); 
    // some minor processing here using the dataset 
    // and probably a loop 
    return "stuff"; 
} 
function loadDataset() { 
    //intensive dataset load code 
    //plus a database lookup or two 
    //whatever else 
    return array(
     "data1", 
     "data2" 
    ); 
} 

Lo anterior no funciona. Resulta en un error inesperado '(', expecting ',' o ';'.

Me doy cuenta de que funcionaría, y se aprobaría por referencia, eliminando así la sobrecarga, sin embargo, eso implica el trabajo adicional de asegurarse de que las llamadas a calledRepeatedly en realidad tienen el conjunto de datos en la lista de argumentos.

¿hay alguna manera de hacer esto?

+4

no puede almacenar expresiones en una variable estática. Se resuelven en tiempo de compilación, por lo que aún no se puede llamar a la función. No sé si php admite funciones estáticas. –

+0

¿Qué tal hacer una clase y guardarla en una propiedad? ;-) – thedom

+0

@Mark, solo dentro de las clases. –

Respuesta

11

me tiraría la declaración estática en loadDataset. Agregué un valor booleano para determinar si actualizar los datos de la base de datos. El proceso básico es el siguiente: defina la variable estática, en lugar de establecerla en algo. Luego, verifique si está configurado (o si $refresh se configuró en verdadero). Si no es así, cargue los datos intensivos de la base de datos.

function loadDataset($refresh = false) { 
    static $dataset; 
    if(!isset($dataset) || $refresh) 
    { 
     $dataset = array(); 
     //intensive dataset load code 
     //plus a database lookup or two 
     //whatever else 
    } 
    return $dataset; 
} 

Editar: Por supuesto, puede seguir utilizando el patrón static ... isset en su función original, pero parecía más limpio para ponerlo en loadDataset.

+0

Aunque puede ser más limpio, la función de carga de datos carga más de un solo conjunto de datos a lo largo del script, que es * parte * de la razón por la que está procesando intensamente (aunque la mitad más grande está cargando y procesando un resultado de base de datos), así lo haré estar usando static ... isset en la función original porque ambos datasets se usan dentro del mismo bucle. Esta es definitivamente la manera más limpia y lógica para una función que carga un único conjunto de datos a la vez, así que acepté su respuesta sobre pygorex1 simplemente porque usted señaló la manera más limpia :) – Nathaniel

+0

Gracias :) Además, 'isset' es (como Hasta donde yo sé) la forma mínima de verificar si se ha asignado '$ dataset'. 'empty' no funcionaría si, por ejemplo, espera que su conjunto de datos sea ocasionalmente una matriz vacía.Lamentablemente, no hay forma de distinguir entre variables indefinidas y variables que se establecen en nulo, o lo hubiera utilizado en su lugar. – theazureshadow

+0

Gracias @theazureshadow muy útil ... – atpatil11

3

Aunque no se puede asignar el resultado de una función directamente a una variable estática que pueda aún capturar el valor de retorno y asignar a la variable estática:

<?php 

function calledRepeatedly() { 
    static $dataset = false; 
    if (!$dataset) { 
     echo "dataset is empty, fetching data\n"; 
     $v = expensive(); 
     $dataset = $v; 
    } 
    echo "$dataset\n"; 
} 

function expensive() { 
    return 'complex data structure'; 
} 

calledRepeatedly(); 
calledRepeatedly(); 
calledRepeatedly(); 

Salida:

dataset is empty, fetching data 
complex data structure 
complex data structure 
complex data structure 
0

Como @Mark comentó, no puede asignar una expresión a una variable estática. En lugar de tratar de usar variables estáticas, una mejor solución es usar algún tipo de mecanismo de almacenamiento en caché como APC para almacenar el resultado.

Cuestiones relacionadas