ugrás a tartalomhoz

OOP class para

Leki · 2011. Okt. 28. (P), 18.48
Adott ez a két osztály

class NewsClass extends MainClass{
	function __construct() {
		parent::_construct();
		$db=$this->db();
	}
	function test(){
		$result=$db->query("SELECT * FROM information_schema.TABLES");
		return $result->numRows();
	}
	function accessFilter(){
		parent::accessFilter();
		
	}
	function getIdByurl(){
	}


}
A másik:

class MainClass{
	function __construct(){
		$db=$this->db();
		$this->accessFilter();
	}
	function accessFilter(){
		
	}
	function db() {
		require_once(ROOT."/libs/pear/MDB2.php");
		$db=&MDB2::connect("mysql://".DBUSER.":".DBPASS."##kukac##".DBHOST."/".DBNAME);
		if (PEAR::isError($db)) die($db->getMessage());
		$db->setFetchMode("2");
		$db->setCharset("utf8");
		return $db;
	}
	function smarty() {
		require_once(ROOT."/libs/smarty/Smarty.class.php");
		$view=new Smarty();
		$smarty->force_compile=true;
		$smarty->caching=false;
		$view->template_dir=ROOT."/themes/templates/";
		$view->compile_dir=ROOT."/themes/templates_c/";
		$view->cache_dir=ROOT."/themes/cache/";
		$view->config_dir=ROOT."/themes/configs/";
		return $view;
	}
	function xml() {
		$parser=new myParser();
		$parser->setInputFile(_ROOT.'/lang/'._PAGE_LANGUAGE.'.xml');
		$parser->parse();
	}
}
Ha meghívom a teszt függvényt, akkor :

"Fatal error: Call to a member function query() on a non-object"...

Ezzel szemben ha a teszt() a gyermek osztályban így néz ki

class NewsClass extends MainClass{
	function __construct() {
		parent::__construct();
	}
	function test(){
                $db=$this->db();
		$result=$db->query("SELECT * FROM information_schema.TABLES");
		return $result->numRows();
	}
	function accessFilter(){
		parent::accessFilter();
		
	}
	function getIdByurl(){
	}


}
Így működik, miért így van ez? Nem régen kezdtem el foglalkozni a dologgal.

A másik kérdésem, hogy ebben az esetben, hogyan tudok még meghívni egyéb osztályokat úgy, hogy az nem gyermek osztály, hanem "segéd osztály". pl. CakePHP ban var $helpers=array("osztalynev");

Nem találtam sehol megoldást erre, még csak hasonlóra sem. Esetleg tudnátok segíteni, vagy csak linkeket dobni ahol meg tudnám tanulni?
 
1

Először azon gondolkodj el,

inf · 2011. Okt. 28. (P), 19.50
Először azon gondolkodj el, hogy mit csinál a kódod. Én mondjuk ránézek a test metódusra, na most ami lejön, hogy tesztel valamit, de az nincs benne a nevében, hogy mit tesztel...

A $db és a db() elnevezés megint csak érdekes, a metódusok csinálnak valamit, tehát igék, a változók meg főnevek. Szóval mondjuk db() helyett minimum getDb() kellene, vagy esetleg getConnection() vagy ilyesmi...

Szóval ilyen elnevezésekkel nem értem, hogy hogyan várhatod el, hogy valaki ránézésre átlássa a kódodat...

Egyébként meg a hibája az, hogy a $db lokális változó, tehát a konstruktorban megadott érték nem kerül át a test metódushoz. Helyette property-t kéne használnod, aminek $this->db-vel adsz értéket...
2

Üdv! Elnézést, hogy csak most

Leki · 2011. Okt. 31. (H), 09.44
Üdv! Elnézést, hogy csak most válaszolok, de nem voltam gép közelben. A test() függvényt csak tesztelésre használom, hogy hogyan is tudom összekapcsolni az osztályokat. Ez nem egy működő oldal része, ez csak próba kód.
3

Egy kis hibakeresés :) Csak

Kubi · 2011. Nov. 2. (Sze), 12.26
Egy kis hibakeresés :) Csak azért írom így, hogy ha hibába futsz, akkor hogy álj neki:

1, értelmezd, mit jelent ez a hibaüzenet: "Fatal error: Call to a member function query() on a non-object", azaz query() függvényt akartad meghívni egy olyan változón, ami nem objektum, azaz valószínüleg nincs jól megadva az értéke.
2, most már tudjuk mi a bibi, nézzük a teszt függvényed:
function test(){
$result=$db->query("SELECT * FROM information_schema.TABLES");
return $result->numRows();
}

itt a baj, a $db változó nincs inicializálva. Ha simán egy új változónak értéket adsz a constructorban, az nem lesz elérhető objektum szinten, csak és kizárólag a constructorban. Vegyél fel egy osztály szintű változót (kívülről ha nincs rá szükség protected, ha igen public előtaggal, olvass utánna), majd ehez $this->változónév el férsz hozzá.

Az hogy van egy db nevü változód, meg db nevü függvényed, nem fog bekavarni, mert egyik változó, másik függvény, bár téged megkavarhat, ezért kerülendő az ilyen elnevezések, használj mondjuk $_db nevet.

A helyes megoldás

class NewsClass extends MainClass{
protected $_db;

function __construct() {
parent::_construct();
$this->_db=$this->db();
}
function test(){
$result=$this->db->query("SELECT * FROM information_schema.TABLES");
return $result->numRows();
}
}
5

Itt is hiányzik egy alulvonás

prom3theus · 2011. Nov. 2. (Sze), 13.41
Itt is hiányzik egy alulvonás :)

$result=$this->_db->query("SELECT * FROM information_schema.TABLES");
4

Nem vagyok biztos benne, hogy

prom3theus · 2011. Nov. 2. (Sze), 13.40
Nem vagyok biztos benne, hogy ez megoldja a problémádat, de az biztos, hogy a bemásolt NewClass kódjának konstruktorában a parent konstruktorának hívásánál eggyel kevesebb _ (alulvonás) karakter van. Azaz így lenne helyes: parent::__construct - de így szerepel: parent::_construct