Varolan değişkeni bir PHP sınıfı özelliğini ayarlayabilir miyim?

7 Cevap php

Ben benim PHP uygulaması ayarları nasıl işlemek istediğinizi anlamaya çalışıyorum. Ben hemen hemen bu özdevinimli ve gelecekte esnek olacak bu yüzden bir Confg sınıf dosyası kullanmak istiyorum karar var. Aşağıda ile oynarken bazı şeyler.

Ben bunu o zaman bir ortak statik özelliğini kullanmayı deneyin bir sabit popluate için bir değişken olamaz biliyorum.

Neden ayarlanamaz public static $ip = $_SERVER['REMOTE_ADDR'];?

<?php
// config.class.php
class Config
{
    const URL = 'http://www.foo.com';
    const DB_User = 'dbname';

    public static $test = 'test string';
    public static $ip = $_SERVER['REMOTE_ADDR'];
}

///////////////////////////////////////////////////////
//index.php

// works
echo Config::URL;

// works
echo Config::$test;

// DOES NOT WORK
echo Config::$ip;

?>

7 Cevap

Bu soru (doğru jspcal cevaplar onu), ihtiyaçlarınızı Singleton design pattern kullanmak olur uyabilecek bir hızlı bir çözüm cevap vermez rağmen. İşte bir alternatif:

<?php

// config.class.php
class Config
{
    /**
     * Instance container
     * @var Config
     */
    private static $instance = null;

    /**
     * Constants container
     * @var array
     */
    private $constants = array(
        'url'     => 'http://www.foo.com/',
        'db_user' => 'dbname'
    );

    /**
     * Options container
     * @var array
     */
    private $options = array();

    /**
     * Don't allow outside initialization
     */
    private function __construct()
    {
        // Set options (could load from external source)
        $this->options = array(
            'test' => 'test string',
            'ip'   => $_SERVER['REMOTE_ADDR']
        );
    }

    /**
     * Disable cloning
     */
    private function __clone() { }

    /**
     * Get new instance of class
     */
    public function getInstance()
    {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Retrieve value with constants being a higher priority
     * @param $key Key to get
     */
    public function __get( $key )
    {
        if ( isset( $this->constants[$key] ) ) {
            return $this->constants[$key];
        } elseif ( isset( $this->options[$key] ) ) {
            return $this->options[$key];
        }
    }

    /**
     * Set a new or update a key / value pair
     * @param $key Key to set
     * @param $value Value to set
     */
    public function __set( $key, $value )
    {
        $this->options[$key] = $value;
    }
}

///////////////////////////////////////////////////////
//index.php

// works
$config = Config::getInstance();
echo $config->url;
echo $config->test;
echo $config->ip;

Updated: emin değil öncelik bu tür sabitler / seçenek istiyorsanız. Bu sadece bir örnek.

üyeleri (sayısal hazır bir dize sabiti gibi, vb) sabit bir ifade ile başlatılması gerekmektedir. Eğer (bir değişkenin değeri ya da bir işlev çağrısı gibi) dinamik bir ifade ile bir üye başlatmak için çalışırsanız php bir ayrıştırma hatası verecektir ...

Bu nedenle burada senin fikrin çok işlevsel olduğunu, ancak php en azından şimdi bunu desteklemiyor ... sınıf tanımları çalıştırılabilir ifadeler ile eşit olarak düşünün diğer bazı piton gibi DİLLER'de, ya da javascript benzemez ...

ama bu ile başa çıkmak için bazı alternatifler vardır:

sınıf tanımı sonra başlatma ekleyin:

class C {...}
C::$var = $_SERVER['REMOTE_ADDR'];

veya bir init fonksiyonu var:

function init()
{
  if (self::$init === false) {
    self::$var = $_SERVER['REMOTE_ADDR'];
    self::$init = true;
  }
}

C::init();

veya daha yeni php ile __ autoload kullanabilirsiniz () bazı statik baþlatma yapmak için kanca ...

Sorunuza doğrudan cevap, ama neden daha az kodlanmış yaklaşım kullanmak yok değil, örneğin Eğer apps yeniden bir genel yapılandırma sınıfı

// MyConfig.php
class MyConfig {
    protected $_data;

    public function __construct($path)
    {
        $config = include $path;
        $this->_data = $config;
    }

    public function __get($val)
    {
        if(array_key_exists($val, $this->_data)) {
            return $this->_data['val'];
        } else {
            trigger_error("Key $val does not exist", E_USER_NOTICE);
        }
    }
}

Belirli bir uygulama için bir dizi doldurabilirsiniz

// app-config.php
return array(
    'ip' => $_SERVER['REMOTE_ADDR'],
    'url' => 'http://www.foo.com';
    'db'  => array(
        'host' => 'foo.com',
        'port' =>  3306
    ),
    'caching' => array(
        'enabled' => false
    )
);

ve sonra bootstrap gibi kullanmak

$config = new MyConfig('/path/to/app-config.php');

Bu soruya cevap değil, ama benim görüşüme göre, yapılandırmaları ile başa çıkmak için daha iyi bir yolu, bir INI veya XML dosyası gibi, bir real yapılandırma dosyası kullanmak için aslında.

Sen mesela kullanabilirsiniz Bu tür dosyaları okumak ve yazmak için Zend Config sınıfı (ve bu sınıf, hatta yapılandırma gibi düz bir PHP dizi ile başa çıkabilirim.

Sonunda bu korumak için kod kolaylaştıracaktır.

Diğer cevaplar ve yorumları okuduktan sonra da Zend Registry sınıfına ilginizi çekebilir.

Genel olarak ben böyle şeyler için bir çerçeve veya hazır bileşenleri kullanmak için tavsiye ediyorum. Sen tekerleği yeniden icat etmeye gerek yok ve en diğer deneyimlerinden faydalanabilir.

(! sabit vermek) yapmak için () tanımlamak kullanmayı deneyin:

// config.class.php
define(REMOTE_ADDR, $_SERVER['REMOTE_ADDR']);

    class Config
    {
        const URL = 'http://www.foo.com';
        const DB_User = 'dbname';

        public static $test = 'test string';
        public static $ip = REMOTE_ADDR;
    }

PHP sadece izin vermez, çünkü çalışmaz.

Genellikle bir sınıfa, uygulamanın yapılandırma (en azından PHP) koyarak tavsiye etmem, hiçbir gerçek avantaj bence var - daha küresel bir dizi ya da öylesine koydu :)

PHP sadece buna izin vermez. Bu konuda düşünüyorsanız, zaten yapılandırma veri parçası olarak REMOTE_ADDR olması mantıklı değil. Bunu istek veri parçası ve uygulama yapılandırması olmamak için düşünebilirsiniz.

Yapılandırmanıza gelince, ben PHP yerleşik bir INI çözümleyici (parse_ini_file fonksiyonuna bakınız) vardır çünkü yapılandırması için bir. Ini dosyası kullanarak öneririm. Bu kendi konfigürasyonu (yani php.ini) INI dosya biçimi PHP'nin seçimi ile uyumlu olacaktır.

Örneğin, bu soruyu göz atın: http://stackoverflow.com/questions/476892/whats-is-the-best-file-format-for-configuration-files/476908#476908