Autor Zpráva
joe
Profil
Ahoj,

poradíte někdo, jak by měla vypadat metoda __get, abych si umožnil přístup k poli (ty mohou být libovolné, stejně tak zanoření):

<?php

class Test {
	
	private $arr = array(
		'foo' => 'bar',
		'foo2' => array(
			'bar1' => 'a',
			'bar2' => 'b',
			'bar3' => 'c',
		),
	);
	
	public function __get($name) {
		/* ... */
	}
	
}


$test = new Test();

echo($test->arr->foo); // vypsalo by 'bar'
echo($test->arr->foo2->bar3); // vypsalo by 'c'


Nemůžu se k tomu nějak dostat, půjde to vůbec? Díky
Majkl578
Profil
Když se nad tím logicky zamyslíš, dojdeš k tomu, že to nejde nijak jednoduše. Nejjednodušeji bys toho docílil tak, že bys:
a) neukládal do Test::$arr pole, ale stdClass,
b) v __get rekurzivně konvertoval na objekt (nejspíš stdClass),
c) používal ArrayObject.
joe
Profil
Majkl578:
Máš pravdu, ty dvě poslední možnosti mě taky napadly, já jenom jestli by to nešlo i nějak lépe, nechtěl jsem to pořád převádět (na objekty) a tak jsem si udělal pro to radši metodu get($key), kde mam zavedenou tečkovou notaci, díky :-)
Ugo
Profil *
napadla me jenom takovahle prasarna :D ... skoda ty funkce arr() , bez ni netusim vubec protoze napoprvy to __get nezavola :(
class Test {
    private $tmp;
    private $arr = array(
        'foo' => 'bar',
        'foo2' => array(
            'bar1' => 'a',
            'bar2' => 'b',
            'bar3' => 'c',
        ),
    );
    public function arr() {
    	$this->tmp=$this->arr;
    	return $this;
    }
    public function __get($name) {
    		if(empty($this->tmp)) {
    			$this->tmp=$this->{$name};
    		} else {
    			if(is_array($this->tmp[$name])) {
    				$this->tmp=$this->tmp[$name];
    				return $this;
    			} else {
    				$ret=$this->tmp[$name];
    				unset($this->tmp);
        		return $ret;
    			}
    		}
    }
    
}


$test = new Test();

echo($test->arr()->foo); // vypsalo by 'bar'
echo($test->arr()->foo2->bar3);
joe
Profil
Ugo:
Jestli jsem to správně pochopil, kde jsem psal, že nemůže být kód :-)
private $foo = array(
  'foo' => 'foo',
);
Ugo
Profil *
co? :D ted tě nechápu ... ten příklad je spíš taková zajímavost, teoreticky by se nechala třeba při set vytvořit funkce.. tim si teď nejsem jist - nikdy sme to nepotřeboval obdobná tomu názvu proměné..
...
btw. vypad mi tma jeden return

public function __get($name) {
	if(empty($this->tmp)) {
		$this->tmp=$this->{$name};
		if(!is_array($this->tmp)) {
			return $this->tmp;
		}
		return $this;
	} else {
		if(is_array($this->tmp[$name])) {
			$this->tmp=$this->tmp[$name];
			return $this;
		} else {
			$ret=$this->tmp[$name];
			unset($this->tmp);
  		return $ret;
		}
	}
}
Mike8748
Profil
joe:
hotové řešení je třeba třída Zend_Config, funguje přesně jak popisuješ

stačí aby třída Test obsahovala pouze jednu úroveň dat a to jako pole instancí třidy Test. pak __get nebude nijak extra složitá

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0