Autor Zpráva
Warp
Profil
Rád bych se zeptal někoho z vás zkušenějších. Navrhuji třídu, která má obstarávat vyhledávání v DB na základě různých vyhledávacích parametrů. Počet těchto parametrů může, být při každém hledání jiný. Jde mi teď o to jak to co nejlépe a nejefektivněji vyřešit předávání a i "odstranění" (při opětovném hledání) těchto parametrů třídě. Mimochodem tato třída má mít i potomky pro podrobnější jinak zaměřené vyhledávání. V podstatě jsou možné tyto přístupy:

1 atribut
class->name = 'test'
class->name = null nebo unset

2 asociativní pole
class->parameter['name'] = 'test'
class->parameter['name'] = null nebo unset

3 metoda pro každý parametr zvlášť
class->setName('test')
class->setName(null) nebo class->unsetName() ???

4 metoda
class->setParameter('name', 'test')
class->setParameter('name', null) nebo class->unsetParameter('name')

Osobně se mi nejvíc zamlouvá způsob 3 jako klasicý objektový návrh, jenže tohle není C++ ale PHP a možnost null a unset v tom dělají docela zmatek. Navíc každé má něco pro a něco proti. Snad jste mě pochopili, jsem v tomto strašný perfekcionalista takže na to berte ohled díky :)
Ještě doplním, že PHP není můj silný obor.
llook
Profil
Parametry bych jednoznačně uchovával v poli, aby nemohlo docházet ke konfliktům s ostatními vlastnostmi. Takže způsob 1 asi ne.

U toho zbytku záleží na vkusu. Někteří puritáni úplně odsuzují veřejné vlastnosti (způsob 2), já bych naopak zvolil nejspíš tento způsob.

Unset u způsobu 3 (a zp. 4 obdobně) by šel vylepšit:
class->setName('test')
class->setName()

Asi nějak takhle:
function setName() {

$args = func_get_args();
if (empty($args)) {
unset($this->parameter['name']);
} else {
$this->parameter['name'] = $args[0];
}
}
Warp
Profil
Vypadá to zajímavě, popřemýšlím díky. Jen si nejsem jistý co jsi myslel těmi konflikty. V momentě, když budu mít metodu setName() tak bych předpokládal i privátní vlastnost name.
llook
Profil
Tím jsem myslel to, že když objekt bude mít i jiné vlastnosti než tyto vyhledávací parametry, tak se bude muset dávat pozor, aby neměli stejný název jako některý vyhledávací parametr.

Někdy taky používám takovou fintu s __call. Vypadá to nějak takhle:
function __call($method, $args) {

$getOrSet = substr($method, 0, 3);
$name = substr($method, 3);
$name{0} = strtolower($name{0});

// set
if ($getOrSet === 'set') {
if (empty($args)) {
unset($this->parameter[$name]);
} else {
$this->parameter[$name] = $args[0];
}

// get
} elseif ($getOrSet === 'get') {
return isset($this->parameter[$name])
? $this->parameter[$name]
: null;
}
}
Pak si nadefinuju už jenom ty getter/setter metody, které se chovají nějak jinak.

A pokud chceš nabídnout všechny čtyři způsoby, můžeš ještě přidat tohle:
// 1. způsob: $objekt->$name = $value

function __get($name) {
$method = 'get' . ucfirst($name);
return $this->$method();
}
function __set($name, $value) {
$method = 'set' . ucfirst($name);
$this->$method($value);
}
// 4. způsob: $objekt->setParametr($name, $value)
function getParameter($name) {
$method = 'get' . ucfirst($name);
return $this->$method();
}
function setParameter($name) {
$method = 'set' . ucfirst($name);
$args = func_get_args();
array_shift($args);
call_user_func_array(array($this, $method), $args);
}

Pak by mělo jít používat všechny čtyři způsoby. Akorát u prvního způsobu nepůjde ten unset.

Například 1. způsob:
$object->name = 'test'; // vlastnost name neexistuje, takže se zavolá __set('name', 'test') a ta zavolá metodu setName('test'). Pokud ani setName() neexistuje, zavolá se __call('setName', array('test')).
llook
Profil
Vlastně unset může fungovat taky, ale až v PHP 5.1 (s metodou __unset).

To co jsem napsal je pro PHP >= 5.0. Metody __call a __get lze s menší úpravou použít i v PHP4.
Warp
Profil
Prvně díky moc za naprosto vyčerpávající odpověď. Co se týče toho přetěžování pomocí __set atd... Nelíbí se mi, že nebude fungovat doplňování kódu v editorech a ani automatická dokumentace. Navíc tyhle konstrukce mě v PHP naprosto děsí i když to šetří to spoustu kódu při psaní set/get metod. Asi použiji tu tvou první navrhovanou konstrukci, ale bez použití toho pole. Místo toho s prefixem. Prostě se mi pořád nelíbí přistupovat k poli na základě nějakého textu, který není nikde definován (definovat ho jako konstantu mi přijde ještě horsí). Možná je můj přístup z pohledu PHP zbytečný, ale přijde mi jako správný navyklý z jiných jazyků.


function setPrmName() {
$args = func_get_args();
if (empty($args)) {
unset($this->prmName);
} else {
$this->prmName = $args[0];
}
}
Toto téma je uzamčeno. Odpověď nelze zaslat.

0