Newsgroup: it.comp.www.php
Titolo: trasformare variabili locali in variabili "generali"

$x=1;
$y=2;
 
function fun() {
     $a=11;
     $b=22;
 
     /*
      * adesso si vorrebbe che le variabili 'locali' appena dichiarate,
      * fossero accessibili anche dall'esterno di questa function
      * Si può fare?
      */
}
 
fun();
 
echo $x . $y;
echo $a . $b;//impossibile accedere...
 
C'è una soluzione (naturalmente senza usare $GLOBAL)?

 fun();
 
E questo lo cambi con
 
list($a, $b) = fun();
 
Messo così è abbastanza inutile, ma presuppongo che lì in mezzo venga 
fatto qualcosa a $a e $b prima di restituirle.
 
Bye.


Meglio ancora (IMHO)
class SomeClass{
	public $a;
	public $b;
	public function fun(){
		//fai qualcosa con a e b
	}
}
 
$sc = new SomeClass();
//assegni in qualche modo a e b di $sc
//fatto questo
$sc->fun();
$a = $sc->a;
$b = $sc->b;
 
Più lungo , prolisso, forse complesso, ma secondo me molto più 
riutilizzabile, disaccoppiato e mantenibile
-- 
I fatti mi cosano

 Il 28/12/2012 16:38, Alessandro Pellizzari ha scritto:
 
http://wikisend.com/download/330386/config-loading.rar
 
 
Come vedete riesco solo ad accedere alle costanti della classe 
'database', ma non alle variabili: $site_url e $public_url
 
A limite posso sostituire (rinunciando al loader)
 
config_loader::load('general');
 
con
 
require 'app/config/general.php';
 
Però bisogna specificare il percorso e aggiungere anche l'estensione,
Non mi sembra una soluzione ottimale, specialmente se i file di 
configurazione da caricare sono più di uno,
 
 


Premesso che quel turbinio di inclusioni lo vedo molto fragile che 
problema hai nel cambiare da
$site_url = '
www.io.it
';
$public_url = '
www.io.it/public
';
 
class database {
     const name='io', password='tu';
}
A
class database {
    const site_url = '
www.io.it
';
    const public_url = '
www.io.it/public
';
     const name='io', password='tu';
}
?
M


 ?
 
E cosa c'entrano 'site_url' e 'public_url' col database?
Io eviterei certi miscugli...
 
Semmai
 
class urls {
    const site_url = '
www.io.it
';
    const public_url = '
www.io.it/public
';
}
 
class database {
     const name='io', password='tu';
}
 
Ma devo proprio usare le classi anche per la configurazione... pazienza!!!

 Ma devo proprio usare le classi anche per la configurazione... pazienza!!!
 
Non devi per forza usarle e il modo con cui le usi è davvero forzato
 
L'uso di define() non lo conosci?
Se i valori sono davvero costanti e non devono adattarsi alla situazione 
ti conviene e di molto credo
Unico limite: non puoi definire array o oggetti tranite define()
 
http://php.net/manual/en/function.define.php
 


 
http://php.net/manual/en/function.define.php
 
 
Si, conosco bene la materia ;)
 
Comunque stavo anche pensando ad una soluzione di questo tipo:
 
<?php
 
class loader {
     static function load() {
         require'vars.php';
 
         foreach (get_defined_vars() as $name=>$value){
             define($name,$value);
         }
     }
}
 
loader::load();
echo x . y;
 
?>
 
<?php  //vars.php
$x=1;
$y=2;
?>
 
 
Non mi sembra malvagia...
 


 
Salvo avere un banale errore di sintassi in vars.php che fa saltare 
tutto, o il file vars.php in un posto dove non dovrebbe essere (o 
mancante) o $x che contiene un valore non scalare
 
Francamente il require nel corpo di una funzione mi fa rabbrividire
 
Prova a dire cosa vuoi fare, non come lo vuoi fare. Secondo me stai 
seguendo una strada intricata senza motivo
 
Tieni conto che tutti i vari cms e framework affrontano la cosa (quello 
che io credo sia la cosa che vuoi fare tu) con dei file di config, dai 
define di Wordpress all'yaml di symfony2


 define di Wordpress all'yaml di symfony2
 
C'è anche chi usa array e variabili (vedi CodeIgniter).
Cmq a limite, vada per i define ;)
 


 
È indubbio che la questione sia motlo legata al gusto dello sviluppatore
Io adoro certe scelte architetturali di symfony ma francamente odio YAML 
per la configurazione
Come config secondo me un bel file di properties è il meglio che si 
possa avere
Secondariamente un bel file zeppo di define (alla maniera di wordpress)
 
Potresti provare con una configurazione in json, te la carichi a runtime 
nel bootstrap tramite un oggetto di classe ConfigurazioneDinamica che 
crei come singleton e il gioco è fatto
 
In aggiunta, tramite gli automagici __get e __set credo tu possa 
abbozzare anche una parte di correzione d'errore se chiedi proprietà non 
esistenti
http://php.net/manual/en/language.oop5.overloading.php#object.get
 
 
M


 
http://php.net/manual/en/language.oop5.overloading.php#object.get
 
 
A questo punto non mi resta che decidere.
Quindi grazie di tutto e BUON ANNO!!!!!!!!!

 Usare direttamente include/require mi pare poco amichevole.
 
Non creare loader per la configurazione.
Crea un manager di configurazione.
 
Non ha senso sporcare il namespace globale con variabili prese da chi sa 
dove e che l'utente può (teoricamente) cambiare in qualsiasi momento 
spaccandoti la logica del programma.
 
class Config
{
 protected static $_config = null;
 
 protected static ensureLoaded()
 {
  if (is_null(self::$_config)) {
   self::$_config = json_decode(file_get_contents('config.json'));
  }
 }
 
 public static function get($k, $default=null)
 {
  self::ensureLoaded();
  if (array_key_exists($k, self::$_config)) {
   return self::$_config[$k];
  }
  return $default;
 }
 
}
 
Grezzo (non supporta i sub-array e cose del genere) e scritto di getto 
(quindi potrebbe avere bug), ma dovrebbe renderti l'idea.
 
Lo usi così:
 
$db = new PDO(Config::get('db_dsn'));
 
Hai un unico oggetto globale, con un nome sensato (ma puoi chiamarlo 
GlobalConfig, AppConfig, o usare un namespace \MyApp\Config per fare 
ulteriore ordine), non rischi di sovrascrivere per sbaglio una variabile 
di configurazione, legge automaticamente il file di configurazione la 
prima volta, è abbastanza facilmente testabile, è estendibile (puoi 
creare una nuova funzione da richiamare al boot per definire il path al 
file di config, per esempio) senza spaccare altre parti 
dell'applicazione, puoi espanderlo facilmente con diversi "driver" di 
lettura dei file di config, ecc.
 
Bye.