2010-01-22 3 views
0

PHP 응용 프로그램에서 설정을 처리하는 방법을 파악하려고합니다. 필자는 Confg 클래스 파일을 사용하여 장래에 자동로드되고 융통성있게 사용할 것을 결정했습니다. 아래는 내가 가지고 노는 물건들입니다.기존 변수에서 PHP 클래스 속성을 설정할 수 있습니까?

저는 Constant를 popluate하기 위해 변수를 설정할 수 없다는 것을 알고 있으므로 public static 속성을 사용하려고합니다.

왜 내가 설정할 수 없습니다 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; 

?> 

답변

2

는 질문 (jspcal 답변 올바르게), 당신의 필요 Singleton design pattern를 사용하는 것 맞는 수있는 빠른 해결책에 응답하지 않습니다. 업데이트

<?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; 

: 여기에 대안이 당신이 원하는 경우에 확실하지 상수/우선 순위의 종류와 옵션을 제공합니다. 그것은 단지 예일뿐입니다.

+0

그게 당신이 찾고있는 대안입니다, 나는 아마도 값을 저장하고 __get __set 및 PHP 마법의 변수를 사용하여 개인으로 설정된 배열을하는 것이 좋습니다 줄 그리고 배열의 값을 검색한다. – William

+0

실제로 이것은 내가 어떻게해야 할 것인가에 대해 어떻게 생각했는지에 대한 것입니다. 좋은 +1 예 : – JasonDavis

+0

더 좋은 예를 들어 업데이트했습니다. – William

3

멤버는 상수 표현식 (예 : 문자열 상수, 숫자 리터럴 등)으로 초기화해야합니다. 변수 또는 함수 호출 값과 같은 동적 표현식을 사용하여 멤버를 초기화하려고하면 php가 구문 분석 오류를 발생시킵니다.

이것은 파이썬 또는 다른 클래스와 달리 다른 클래스와는 다릅니다.

: 정의는 그래서 여기에 당신의 생각은 매우 기능적,하지만 PHP는 지금 적어도 ...

를 지원하지 않지만이 다루는 몇 가지 대안이있다 ... 실행 표정으로 어깨를 나란히 할 수 클래스 정의 다음에 초기화를 추가하십시오.

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

또는 init 함수가 : PHP 그냥하지 않기 때문에

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

C::init(); 

또는 일부 정적 초기화를 할 후크)합니다 (__autoload를 사용하여 새로운 PHP로

...

+0

비슷한 결과를 얻으려면 좋은 대안이 있습니까? – JasonDavis

+0

PHP4를 사용하는 사람들에게는'C :: init()'은 작동하지만'C :: $ var'는 작동하지 않습니다. – user535673

0

그것은 작동하지 않습니다를 그것을 허용하십시오. 더 나은 전역 배열에 넣어 정도 :

+0

배열 파일을 가져올 클래스를 만들려고합니다. 배열 파일의 파일 경로 나 그 라인을 따라 전달할 수 있습니다. – JasonDavis

0

PHP -

일반적으로 I 클래스 (적어도 PHP에서), 내 의견으로는 진짜 장점이없는로 앱의 설정을 넣어 제안하지 것이다 단순히 그것을 허용하지 않습니다. 생각해 보면 REMOTE_ADDR을 구성 데이터의 일부로 사용하는 것은 의미가 없습니다. 응용 프로그램 구성이 아닌 요청 데이터의 일부로 간주 할 수 있습니다.

구성에 대해서는 PHP에 내장 된 INI 파서 (parse_ini_file 함수 참조)가 있으므로 구성에 .ini 파일을 사용하는 것이 좋습니다. 이는 PHP가 자체 구성 (즉, php.ini)을 위해 INI 파일 형식을 선택하는 것과 일치합니다. 예를 들어이 질문에 밖으로

확인,이 비록 What's Is the Best File Format for Configuration Files

+0

적어도 왜 당신이 downvoted 말해. 나는 그의 질문에 대답하고 심지어 제안을했다 ... –

1

질문에 대한 직접적인 대답은 아니지만 하드 코딩되지 않은 접근 방식을 사용하지 않는 이유는 무엇입니까?당신이 당신의 응용 프로그램에서 다시 사용할 수있는 일반적인 구성 클래스는

// 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); 
     } 
    } 
} 

특정 응용 프로그램

// 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 
    ) 
); 

에 대한 배열에서 작성 후

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

올바르게 이해하면 config가 전역 범위에 있어야합니다. 그는 이것을 싱글 톤 (Singleton) 패턴으로 변경하거나 레지스트리 패턴을 사용하여 쉽게 해결할 수 있습니다. – William

+0

이것은 아마도 제가 갈 라우트이고, 네가 globally 접근 가능하게 할 필요가 있습니다. – JasonDavis

+0

저는 이것을 위해 Dependency Injection Service Container를 선호 할 것입니다. 그러나 Jason에게 이것을 여러 번 제안 했으므로, 그는 하나를 사용하지 않는 이유가 있습니다. 하나도 없으면 여러 개의 Config 객체를 가질 수 있도록 Singleton을 통해 레지스트리로 갈 것이고, 단지 내가 Config가 아닌 전역 적으로 사용할 수있는 다른 것을 가질 필요가 있기 때문에 가능할 것입니다. 레지스트리는이를 위해 더 헌신적입니다. – Gordon

1

이 같은 부트 스트랩에서 사용할 수 귀하의 질문에 대답하지 못하지만 제 의견으로는 구성을 다루는 더 좋은 방법은 실제로 구성 파일 (예 : INI 또는 XML)을 사용하는 것입니다. 파일.

예 : Zend Config 클래스는 읽기 및 쓰기와 같은 파일을 (이 클래스도 구성과 같은 일반 PHP 배열 처리 할 수 ​​있습니다.

을 결국이 유지 보수가 쉬운 코드를 만들 것입니다.

을 다른 답변과 의견을 읽은 후 당신은 또한 일반적으로

내가. 당신은 바퀴를 재발견 할 필요가 없습니다 이러한 물건을위한 프레임 워크 또는 기성 구성 요소를 사용하여 조언을 것입니다. Zend Registry 클래스에 관심이있을 수 있으며 당신의 다른 경험에서 이익을 수 있습니다.

+0

직접 빌드하는 가장 큰 이유는 실제로 지금 학습 경험을위한 것입니다. 나는 당신이 게시 한 것과 같은 것들로부터 코드를 공부하는 것을 좋아한다. – JasonDavis

2

define()을 사용해보십시오. 상수를주세요!) :

// 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; 
    } 
관련 문제