ugrás a tartalomhoz

PHP OOP szemlélet - egyszerű példa

supi007 · 2010. Jan. 9. (Szo), 17.01
Hello,

Szeretnék áttérni objektumok használatára.
Sajnos még nem értettem meg, de talán egy jó példa segítségemre lenne.
Van-e értelme az adatbázishoz csatlakozást objektumba zárni?
Hogyan nézne ki? Hogyan tovább, ha megírtam ezt az objektumot?

supesz
 
1

Szerintem

supi007 · 2010. Jan. 9. (Szo), 17.07

<?php
class Kapcsolat
 {
  var $host="localhost";
  var $user="user";
  var $pswd="password";
  var $connection;
  $connection=mysql_query($host,$user,$pswd) or die(mysql_error());
 }
$obj1=new Kapcsolat();
?>
Na én idáig el tudom mondani, hogy mit csináltam, de nem tudom, hogy mi lesz a következménye és éppen ezért azt sem, hogyan tovább.
Megköszönném, ha valaki felvilágosítana.
Előre is köszönöm.

supesz
9

Nem fog lefutni

Thoer · 2010. Jan. 9. (Szo), 19.47
hiszen parancsot nem futtathatsz egy osztály deklarációs részében, azt mindenképpen egy függvénybe kell raknod és meghívnod. Valószínűleg egy úgynevezett konstruktor függvénybe tetted volna, aminek php5 alatt a neve __construct és magától lefut az osztály létrehozásakor.

Ráadásul a var egy php4-es, tehát elavult láthatóság. PHP5-ben var helyett valószínűleg private-ot írtál volna. (Vagy php4-ben pedig $obj1=& new Kapcsolat();-ot, de ezt vedd úgy hogy nem is mondtam!) Tehát amire te gondoltál az ez:

<?php
class Kapcsolat  
{
  private $host="localhost";
  private $user="user";
  private $pswd="password";
  private $connection;
  
  public function __construct()
  {
    $this->connection = mysql_query($host,$user,$pswd) or die(mysql_error());
  }
}
$obj1 = new Kapcsolat();
Ennek persze önmagában nincs sok értelme de 2 dolog már így is van:
1. Szépen össze vannak rendelve az összetartozó változók, nevezetesen az adatbázishoz tartozóak.
2. Ez már egy könnyen tesztelhető programkód. Bár neked még biztosan magas lenne egy SimpleTest vagy phpUnit kézikönyv, azért nem baj ha ezt rögtön észben tartod...

Amúgy igazán szép ott kezd lenni egy osztály, amikor már sokkal többet tud és amikor elkezded örököltetni. Csak hogy egyszerű példát mondjak, igen gyakori, hogy kiforrott rendszerekkel úgy tudsz adatbázis lekéréseket végrehajtani, hogy nem kell azzal foglalkoznod, hogy milyen adatbázist használsz éppen.

Például mutatok egy lekérést:
$query = "SELECT nev, tel "
       . "FROM felhasznalok "
       . "WHERE nev LIKE '%".$_POST['nev']."%' AND lekerheto=1 "
       . "LIMIT 5, 100";
$felh = mysql_query($query);
Na most ez a CodeIgniter vagy a Kohana keretrendszerek modelljeiben, így néz ki:
$felh = $this->db
             ->select('nev, tel')
             ->like('nev', $_POST['nev'])
             ->where('lekerheto', 1)
             ->get('felhasznalok')
A kettő ugyan formailag nem teljesen ugyanazt az eredményt adja, de majdnem, a különbség mégis óriási. Először is az első egy MySQL lekérdezés, ami valószínűleg más adatbázis rendszerekben hibát vagy nem várt működést eredményezne, az utóbbi viszont a beállított adatbázis típusának megfelelően fogja létrehozni a tényleges lekérést. (A LIMIT például úgy tudom PostgreSQL-ben pont fordítva várja a paramétereket.)

Másodszor az első verziót egy egyszerű SQL befecskendezéssel rá lehet bírni, hogy a nem lekérhető elemeket is megjelenítse. Persze meg lehetne úgy írni a programot, hogy ez ne fordulhasson elő, de az osztály is figyelhet rá. Ilyenkor a későbbi munka nagyban egyszerűsödik. Ennek az az alapja, hogy van egy absztrakt adatbázis osztály, ami effektíve nem sokat csinál, hanem az a fő szerepe, hogy a beállításoknak megfelelő osztályt lehet elérni rajta kívül. Tehát van mondjuk egy DB nevű absztrakt osztály, és vannak mondjuk Mysql_DB és Postgre_DB osztályok, és mind a kettőnek ugyanolyan nevű eljárásai lesznek, ugyanolyan paramétereket várnak, csak az egyik mysql, a másik postgresql adatbázisokon fogja ugyanazt a műveletet elvégezni. A programozónak adott esetben nem is kell azzal foglalkozni, hogy ténylegesen most épp melyiket használja, csak kér egy adatbázis osztályt a rendszertől és kész.
12

A LIMIT például úgy tudom

Crystal · 2010. Jan. 10. (V), 01.05
A LIMIT például úgy tudom PostgreSQL-ben pont fordítva várja a paramétereket

Oracle-ben meg nincs is ;) rownum-ot kell buzerálni
2

Mi az oop programozás lényege.

CSI · 2010. Jan. 9. (Szo), 17.50
Szia!

Szakirodalom 3 dolgot mindig felsorol amikor OOP-ről beszél:

1. egységbe zárás:
------------------
Osztály definiálása mely az azonos osztályba tartozó elemek tulajdonságait műveleteit tartalmazza.
pl.: vannak Audi, Merci, Seat stb.. ezek ugye az auto osztályba tartoznak csak más a gyártójuk más az alakjuk stb... de az auto osztályal letudod írni őket.

class Auto {
    var $szin;
    var $gyarto;
    var $motorszam;  
 
    function Auto($gyarto) {
       $this->gyarto = $gyarto;
    }

    function setSzin($szin) {
     $this->szin = $szin;
    }

    function setMotorSzam($motorszam) {
      $this->motorszam = $motorszam;
    }

    function irdkiAutoJellemzo() {
       echo "Gyarto:".$this->gyarto."<br />";
       echo "Motor szám:".$this->motorszam;
       echo "Szín:".$this->szin;
       echo $this->szin."<br />";
    }
}

Itt van fent az auto osztály ami természetesen tovább bővíthető de alapvetően leírja egy autot.

Nézzük tovább a következőket.

$audi = new Auto('Audi');
$audi->setmotorszam('10');
$merci->setszin('Kek');

$merci = new Auto('Merci');
$merci->setmotorszam('12');
$merci->setszin('Piros');

$audi->irdkiAutoJellemzo();
//Eredmény: Gyarto:Audi Motor szám: 10 Szín: Kek
$merci->irdkiAutoJellemzo();
//Eredmény: Gyarto:Merci Motor szám: 12 Szín: Piros


Mos azt auto osztályból létrehoztam két autot egy Audi-t és egy Merci típusú autót. Majd ennek a két objektumnak beállítottam a motor számát. A keletkezett két auto objektum nem azonos hisz az egyik egy merci a másik egy auto valamint a motor számuk is eltér. Így ugye egy osztállyal rengeteg különböző objektumot előtudsz állítani úgy hogy ne kelljen újra implementálni. Ezáltal előjön az oop szemlélet 3. legfontosabb tulajdonsága az újra felhasználhatóság. Igen tudom kihagytam 2. fontos dolgot a polimorfizmust . Ez gyakorlatilag az jelenit, hogy ugyanak az osztály fgv.-nek lehet több alakja (JAVA ez fontosabb) valamint a viselkedésük is eltérhet valamint gyermek osztályokba felül definiálható. De ez már mélyebb oop-és ismeret.

Természetesen az oop programozási szemlélet ennél jóval mélyebb, ezért jobb ha a net-en Google segítségével utánna olvasol.

Mélyebb megértés véget ajánlom a következő pdf-eket:
Nagy Gusztáv oldalán:
http://nagygusztav.hu/java-programozas-13
Vagy
Angster Erzsébet - Objektumorientált tervezés és programozás 2.kötetes könyvét (Én anno abból tanultam meg az alapelveket elég szájba rágós)

Remélem tudtam valamennyit segíteni
8

javítás

ironwill · 2010. Jan. 9. (Szo), 19.44
Szia!

Nem kukacoskodás és valószínű, hogy copy-paste hiba:
$audi = new Auto('Audi');
$audi->setmotorszam('10');
$merci->setszin('Kek'); //még nincs merci objektum, amikor hivatkozik rá.
                        //Nagy valószínűséggel zokon veszi.. :)

$merci = new Auto('Merci');
$merci->setmotorszam('12');
$merci->setszin('Piros');
üdv, Gábor
3

még

gphilip · 2010. Jan. 9. (Szo), 17.54
hali!

még ezeken a kulcsszavakon is érdemes elindulni, h megértsd, miért jó (ha egyáltanán) elrugaszkodni a procedurális programozási stílustól:

- design patterns
- mvc
- dry
4

wow

supi007 · 2010. Jan. 9. (Szo), 18.05
Kösz a segítséget, de...
Elméleti ismeretek megszerzéséhez van nálam ez a tanuljuk meg a php-t 24 óra alatt.
Tudom nem túl komoly, de vannak példák és elindulni segít.
A problémám az, hogy olyan példáim, vannak, hogy: Üdvözlöm a nevem Krisztián, meg hasonlóak.
Sajnos ebből nem értem meg, hogy hogyan zárjam objektumba az adatbázis csatlakozás részleteit illetve azt hogyan használjam fel később.
Mivel ti is ilyen példát adtatok be kell látnom, hogy ebből is meg kell értenem.

supesz
5

Pl. Adatbázis kezelésére

CSI · 2010. Jan. 9. (Szo), 18.38
Itt egy psql adatbázis kezelésre példa osztály. Természetesen az időm hiányában ezt lehet bővíteni stb....

<?php
define($DB_HOST,'localhost');
define($DB_PORT,'1220');
define($DB_USER,'asdasd');
define($DB_NAME,'asdasd');
define($DB_PASSWORD,'asdasd');

class DBConnect {
/**
* Adatbázis kapcsolatot tárolja
*
* @var unknown_type
*/
protected $_conn;

/**
* Konstruktór, alap adatok inicializálása
*
* @return DBConnect
*/
public function DBConnect(){
$this->_conn = null;
}
/**
*
* Adatbázis kapcsolat felépítése
* Adatbáizis kapcsolathoz lehet define értékeket megadni a következő neveken
*
* DB_HOST = A host neve ahova csatlakozni szeretnénk
* DB_PORT = A port amelyiken csatlakozunk
* DB_NAME = Adatbázis neve
* DB_USER = Felhasználó név
* DB_PASSWORD = Jelszó
*
* @param string $host => A host neve ahova csatlakozni szeretnénk
* @param string $port => A port amelyiken csatlakozunk
* @param string $db_name => Adatbázis neve
* @param string $db_user => Felhasználó név
* @param string $db_password => Jelszó
*/
public function startConnect($host = DB_HOST, $port = DB_PORT, $db_name = DB_NAME, $db_user = DB_USER, $db_password = DB_PASSWORD){
$connect_string="host= ".$host." port=".$port." dbname=".$db_name."
user=".$db_user." password=".$db_password;
   
$this->_conn=pg_pconnect($connect_string) or die("Adatbázis kapcsolat nem jöhet létre:".$connect_string);
}

       /**
* SQL query futtatása
*
* Vissza térés a lekérdezés eredményével
*
* @param string $query => sql query
* @param boolean $islog => kell e log hozzá
* @return array
*/
public function query($query,$islog = true){

  $res = pg_query($this->_conn,$query);
  return pg_fetch_all($res);
}

/**
* Adatbázis kapcsolat zárása
*
*/
public function stopConnect(){
pg_close($this->_conn);
$this->_conn=null;
}
}
?>


mikor kell adatbázis kapcsolat csak kérek egy példányt a DBConnect osztályból
$db = new DBConnect('host','port','name','user','psw');
$res = $db->query($sql);
$db->stopConnect();

//és mondjuk kell egy masik adatbázis is

$db2 = new DBConnect('host1','port1','name1','user1','psw1');
$res2 = $db->query($sql);
$db2->stopConnect();


Itt van egy olyan osztály amiből létrehoztam két különböző adatbázis kapcsolatot és kéregetek tőle el dolgokat, majd ha nem kell lezárom. $db és $db2 két különböző objektum de mind a kettő ugyanazokkal a tulajdonságjellemzőkkel és függvényekkel rendelkezik csak más az értékük => azonos osztályba tartoznak de különböznek!!!.

Hülye kifejezes: de objektum az az egyed, egyedi példány amit használsz az osztály pedig egy általános leírás amiből a rendszer tudja, hogy az adott példány mivel rendelkezhet és mit lehet rajta csinálni.
6

Csináltam egy ilyet és működik

supi007 · 2010. Jan. 9. (Szo), 19.10

<?php
class Adatbazis
	{
	var $host="localhost";
	var $user="user";
	var $pswd="password";
	var $select;
	var $connid;
	var $result;
	var $array=array();
	
	function connect()
		{
		$this->connid=mysql_connect($this->host,$this->user,$this->pswd);
		}
	function query($select)
		{
		mysql_query("SET NAMES 'utf8'");
		$this->result=mysql_query($select,$this->connid);
		}
	function writeout()
		{
		while($this->array=mysql_fetch_array($this->result))
			print $this->array[0]."<br>";
		}
	function close()
		{
		mysql_close($this->connid);
		}
	}
$obj1=new Adatbazis();
$obj1->connect(); //kiirja a kapcsolatazonositot
$obj1->query("SELECT tartalom FROM practice.ezisazis"); //lekerdezek
$obj1->writeout(); //kiratok
$obj1->close(); //lezarom a kapcsolatot
?>
7

Grat. De olvas utánna az OOP szemléletnek

CSI · 2010. Jan. 9. (Szo), 19.31
De mondom az oop -itt még nem ált meg. PHP4-még nem teljesen oop-és nyelv a PHP5 már inkább. Javaslom olvasd el a PHP4 24 óra alatt, majd kezdj el ismerkedni a PHP5-el. Abban már sokkal több OOP-és alap van. A neten rengeteg segítséget találsz. Az oop szemlélet a legfontosabb amit meg kell érteni, utánna már ellehet vele lavírozni az oop-és nyelvek közt.

Sok sikert hozzá :-)

Amit nézzél meg:
Desing Pattern's (Tervezési metrikák)
OOP szemlélet
MVC model lényegét

és ha PHP5-ös MVC keretrendszerekkel akarsz értelmes dolgot összehozni javaslom a YII-t vagy Zend Framework vagy CodeIgnitert (de inkáb YII)
10

Kösz

supi007 · 2010. Jan. 9. (Szo), 20.03
Kössz a segítséget.
Nagyjából most értem mit is akar jelenteni.
Persze most jön a nehezebb része a gyakorlás.
A PHP 24 óra alatt megvan. Azt olvasom most.
Van CodeIgniter, de még nem találtam rajta fogást. Nem tudom mi is ez igazán.
Először ugyis simán texteditorba szerkesztem a kódjaimat, aztán valamilyen framework.
Mégegyszer kössz.

supesz
11

Text editor helyet.

CSI · 2010. Jan. 9. (Szo), 20.10
Text editor helyett, használj NetBeans-t vagy Eclipse PDT-ét. Sokkal jobbak mint az editorok. Osztály metódusokat mutatják és igen hasznosak. Mind a 2 fejlesztő eszköz ingyenes én most a NetBeans-t ajánlom, bár tény hogy a cégnél a PHP4 miatt az Eclipse PDT-vel dolgozom.

További jó és sikerekben gazdag tanulást.