PHP의 확장 클래스에서 부모 변수를 사용합니다
문제
메인과 확장 된 2 개의 수업이 있습니다. 확장 클래스에서 메인 VAR을 사용해야합니다.
<?php
class Main {
public $vars = array();
}
$main = new Main;
$main->vars['key'] = 'value';
class Extended extends Main { }
$other = new Extended;
var_dump($other->vars);
?>
내가 누구를 할 수 있습니까?
예를 들어 유효하지 않음 :
<?php
class Extended extends Main {
function __construct ($main) {
foreach ($main as $k => $v) {
$this->$k = $v;
}
}
}
?>
더 투명하고 효율적으로 해결책이 필요합니다. :)
해결책
편집하다: 이것은 훨씬 더 잘 해결 될 수 있습니다 제어의 역전 (IOC) 및 의존성 주입 (di). 자신의 프레임 워크를 사용하거나없는 프레임 워크를 사용하는 경우 의존성 주입 컨테이너 노력하다 리그/컨테이너
어리석은 대답의 역사로 왼쪽 아래에 답하십시오.
내가 생각하는 올바른 방법.
<?php
class Config {
protected $_vars = array();
protected static $_instance;
private function __construct() {}
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
public function &__get($name) {
return $this->_vars[$name];
}
public function __set ($name, $value) {
$this->_vars[$name] = $value;
}
}
$config = Config::getInstance();
$config->db = array('localhost', 'root', '');
$config->templates = array(
'main' => 'main',
'news' => 'news_list'
);
class DB {
public $db;
public function __construct($db)
{
$this->db = $db;
}
public function connect()
{
mysql_connect($this->db[0], $this->db[1], $this->db[2]);
}
}
$config = Config::getInstance();
$db = new DB($config->db);
$db->connect();
class Templates {
public $templates;
public function __construct($templates)
{
$this->templates = $templates;
}
public function load ($where) {
return $this->templates[$where];
}
}
$config = Config::getInstance();
$templates = new Templates($config->templates);
echo $templates->load('main') . "\n";
다른 팁
간단한 생성자로 쉽게 가능합니다
<?php
class One {
public static $string = "HELLO";
}
class Two extends One {
function __construct()
{
parent::$string = "WORLD";
$this->string = parent::$string;
}
}
$class = new Two;
echo $class->string; // WORLD
?>
나는 이것이 매우 늙었다는 것을 알고 있지만 다른 사람이 단서가 필요한 경우 ...
정적 변수 사용을 고려해 보셨습니까?
PHP OOP 설계 패턴은 정적으로 선언 된 변수가 부모의 클래스는 동일하게 유지됩니다 어린이 수업도.
예를 들어...
<?php
class A {
public static $test = 'a';
public function test() {
echo 'Test is: '.self::$test;
}
}
class B extends A {
public static $test = 'b';
}
$obj = new B;
$obj->test();
?>
이 코드 실행 (PHP 5.3- 다른 버전의 경우에도 동일하다는 것이 확실합니다)은 다음과 같은 결과를 제공합니다.
테스트는 다음과 같습니다. a
내가 당신의 OP에 모을 수있는 것에서, 당신은 부모 클래스 변수 연장 된 수업에서도 남아 있습니다. 이것은 그 문제를 해결합니다.
클래스 범위를 벗어난 변수를 공개적으로 호출하려면 (예 : 일반적으로 쓰는 곳 $ obj-> vars), 참조하는 부모 클래스에서 함수를 만들어야합니다. self::$variable_name
해당 변수를 해당 클래스 또는이를 확장하는 다른 클래스를 사용하는 코드에 다시 던질 수 있습니다.
예를 들어 :
public function get_variable() {
return self::$variable;
}
또한 인스턴스를 요구하는 내용을 기준으로 Self :: $ 변수를 동적으로 돌려주는 마법 방법을 만들 수 있습니다. 즉, 메소드 또는 변수. 어떤 경우에도 Self :: $ 변수 동등한 Self를 다시 버리기 위해 코드를 연결할 수 있습니다.
읽다 http://php.net/manual/en/language.oop5.magic.php 이런 종류의 작업을 수행 할 수있는 다양한 마법 방법에 대한 자세한 정보.
OP는 약간 비밀 스러웠으므로 그것이 당신이 원하는 것인지 확실하지 않았지만, 여기에 다른 사람이 정적 변수를 참조하지 못했기 때문에 내가 chime을 할 것이라고 생각했습니다. 도움이되기를 바랍니다!
나는 당신이 원하는 것에 대해 더 명확해야한다고 생각합니다. 메인과 확장 된 몇 가지 인스턴스가 있다고 상상해보십시오. 그들은 모두 동일한 데이터를 참조해야하므로 데이터 중 하나에서 데이터를 변경하면 모두 영향을받을 수 있습니까?
그렇다면 한 가지 방법은 개별 인스턴스가 아닌 클래스에 연결된 정적 변수를 사용하는 것입니다. 다른 하나는 다른 클래스의 별도 객체를 만들어 데이터를 저장하고 생성 될 때 메인 및 확장 클래스로 전달하는 것입니다. 그들은 각각에 대한 참조를 저장할 수 있습니다.
class Main {
public $data;
function __construct(Data $data) {
$this->data = $data;
}
}
class Extended extends Main {}
$ourData = new Data();
$ourData->vars = array(1,2,3);
$main = new Main($ourData);
$other = new Extended($ourData);
그렇지 않다면 동일한 데이터에 대한 참조 대신 데이터 사본을 원합니다. 이 경우 두 번째 예제는 더 가까이 있지만 모든 회원을 맹목적으로 복사하는 것은 아닙니다.
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ooooooooooooooooooooooooooooooooooooooo
당신은 이것을 원합니다 :
class Config
{
private $m_vars = array();
function __get($name)
{
return $this->m_vars[$name];
}
function & __set($name, $value) // << the & is important!
{
$this->m_vars[$name] = $value;
}
}
class Db
{
funciton __construct(Config $config)
{
$this->Connect($config->host, $config->user, $config->pass, $config->db);
}
}
$config = new Config();
$config->host = "localhost";
...
$db = new Db($config);
:)
편집하다:
또한이 작업을 수행 할 수 있습니다.
class Templator
{
private $m_config = null;
function __construct($config)
{
$this->m_config = $config;
}
function PrintTemplate($name)
{
echo file_get_contents($this->m_config->template_path . $name);
}
}
$config->template_path = "./templates/";
$temp = new Templator($config);
$temp->PrintTemplate("index.html");