Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    1,317

    __get e __set cosa sbaglio?

    Codice PHP:
    <?php
    namespace util;


    class 
    Environment {
      protected 
    $server_var = [];


        
    /**
         *
         */
        
    public function __get($key) {


          if (empty(
    $this->server_var[$key])) {
            if (isset(
    $_SERVER) && count($_SERVER) && !empty($_SERVER[$key]) && !is_array($_SERVER[$key])) {
              
    $this->server_var[$key] = $_SERVER[$key];
            }
            elseif (isset(
    $_ENV) && count($_ENV) && !empty($_ENV[$key]) && !is_array($_ENV[$key])) {
              
    $this->server_var[$key] = $_ENV[$key];
            }
            else {
              
    $this->server_var[$key] = @getenv($key);
            }
          }
          return 
    $this->server_var[$key];
        }


        
    /**
         *
         */
        
    public function __set($key$value) {
          
          
    $this->server_var[$key] = $value;
        }


    }
    Se faccio:
    self::$environmentObj = new Environment;
    echo self::$environmentObj->server_var['HTTP_HOST'];

    Non stampa niente, anzi mi da errore perchè non ho definito la variabile in __set, ovviamente se faccio:


    self::$environmentObj = new Environment;
    self::$environmentObj->server_var['HTTP_HOST'] = 'Prova';
    echo self::$environmentObj->server_var['HTTP_HOST'];

    Stampa "prova" ma così perde di utilità, a quanto pare non posso definire una array dentro al metodo __get, giusto? si può ovviare?

  2. #2
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    __get() e __set() vengono richiamante quando si tenta di accedere ad una proprietà della classe che non è definita.
    Nel tuo caso server_data esiste, quindi i magic method non vengono chiamati. Quindi il problema si sposta si $server_var, che è un array dove non è definito l'indice 'HTTP_HOST' (__get() e __set() di Environment non c'entrano più niente).

    Secondo me puoi fare due cose:

    1. Fai diventare server_var una classe con __get()/__set() come Environment. Quindi farai una cosa del genere
    Codice PHP:
       echo self::$environmentObj->server_var.HTTP_HOST// Server_var è una classe 
    2. Come su, ma invece che __get()/__set() puoi far implementare alla tua classe ArrayAccess che ti permette di definire il comportamento in caso di chiave non presente
    Codice PHP:
       echo self::$environmentObj->server_var['HTTP_HOST']; // $server_var implementa ArrayAccess 

  3. #3
    perchè sbagli ad usarli quei metodi:

    Codice PHP:

    <?php

    class Environment {
      protected 
    $server_var = [];


        
    /**
         *
         */
        
    public function __get($key) {


          if (empty(
    $this->server_var[$key])) {
            if (isset(
    $_SERVER) && count($_SERVER) && !empty($_SERVER[$key]) && !is_array($_SERVER[$key])) {
              
    $this->server_var[$key] = $_SERVER[$key];
            }
            elseif (isset(
    $_ENV) && count($_ENV) && !empty($_ENV[$key]) && !is_array($_ENV[$key])) {
              
    $this->server_var[$key] = $_ENV[$key];
            }
            else {
              
    $this->server_var[$key] = @getenv($key);
            }
          }
          return 
    $this->server_var[$key];
        }


        
    /**
         *
         */
        
    public function __set($key$value) {
          
          
    $this->server_var[$key] = $value;
        }


    }

    $environment = new Environment();

    echo 
    $environment->USERNAME//QUESTO RICHIAMA __get($key)

    echo "\n";

    $environment->USERNAME "New Username";

    echo 
    $environment->USERNAME//QUESTO RICHIAMA __set($key)


    //versione 2
    class Environment2{
        
        protected 
    $server_var = [];
        
        public function 
    __construct()
        {
            
    //ACCEDERE A $_ENV e $_SERVER dentro la classe è una pratica scorretta
            // sarebbe meglio passarli come argomento al costruttore o con setter specifici
            
    $this->server_var array_merge(
                isset(
    $_ENV) && count($_ENV) ? $_ENV : [],
                isset(
    $_SERVER) && count($_SERVER) ? $_SERVER : []
            );
            
            
    //l'ordine del merge è importante: le chiavi definite in $_SERVER sovrascrivono le chiavi definite da $_ENV
        
    }
        
        public function 
    __get($key)
        {        
            return 
    array_key_exists($key$this->server_var) ? $this->server_var[$key] : null;
            
        }
        
        public function 
    __set($key$value)
        {        
            
    $this->server_var[$key] = $value;
        }
        
        public function 
    debug()
        {
            
    var_dump($this->server_var);
        }
        
    }


    $env2 = new Environment2();

    echo 
    $env2->USERNAME;

    echo 
    "\n";

    $env2->USERNAME "New Username";
    echo 
    $env2->USERNAME;
    cmq visto che ci sono variabili tipo "SCRIPT_FILENAME" etc, ovvero con l'underscore, scrive $env->SCRIPT_FILENAME a me fa venire i brividi, per non parlare di dover scrivere tutto in maiuscolo. piuttosto quindi che usare __get e __set, userei __call e quindi farei tipo $env->getScriptFilename() ed $env->setScriptFilename($value) ovviamente andando a giocare con il primo paramentro che viene passato a __call (vedi manuale)
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.