ik heb een script geschreven die in princiepe gewoon netjes connect en data kan ophalen alleen wanneer ik mysql_free_results of mysql_close wilt gebruiken zegt die dat die unsuccesful is. ik ben nog nieuw in op en vraag me dan ook af wat het probleem is.ik hoop dat iemand mij hiermee kan helpen alvast bedankt.

hier de scripts:


<?php

class DatabaseFunctions
{
protected $_host = 'localhost';
protected $_user = 'root';
protected $_pass = 'okldfkcfn';
protected $_db;

private $_connection = null;
private $_query;

public function __construct()
{
}

public function connect()
{
if (!$this->_connection = mysql_connect($this->_host, $this->_user, $this->_pass))
{
throw new Exception("Connection failed!");
}
}

public function selectDB($db)
{
if (!mysql_select_db($db))
{
throw new Exception("DB not found!");
}
}

public function selectSQL($SQL)
{
if ($this->_connection === null)
{
$this->_connect();
}
$this->selectDB = $this->_db;
return $this->_query = mysql_query($SQL);
}

public function destroyConnection()
{
mysql_free_result($this->_query);
mysql_close($this->_connection);
}
}
?>


en hier de test pagina:


<?php

	require_once 'core_classes/DatabaseFunctions.php';
	
	$database = new DatabaseFunctions();
?>


<html>
<body>
	<?php $database->connect(); ?>
	<?php $database->selectDB('contapp'); ?>
	<?php $test = $database->selectSQL('SELECT * FROM test'); ?>
	<?php 
		while ($row = mysql_fetch_array($test))
		{		
			echo $row['id'] . " " . $row['text'] . " " . $row['date'] . "<br />";
		}
		
		if ($database->destroyConnection())
		{
			echo "destroyed";
		}
		else
		{
			echo "failed to destroy" . mysql_error();
		}
	?>
</body>
</html>



ik krijg nu in me browser: de data uit de db en "failed to destroy zonder enige errors
Je returnt ook niks in je functie, hè.
ik zou verder ook zo op deze manier werken:
public function __construct()
{
    $this->connect();    
}

public function __destruct()
{
    $this->destroyConnection();
}


daarnaast kan je ook gewoon de standaardclass gebruiken die [php]mysqli[/php] heet :)
Ik zou ook nog even naar je foutafhandeling kijken. Vanuit je klasse gooi je netjes Exceptions als er iets fout gaat, maar zorg dan dat je die in je procedurele code ook opvangt door middel van een try/catch blok...
Je voert de query ook gewoon uit zonder dat je exception gooit. Stel dat de query mislukt (bijv door een foutieve query) dan krijg je niks te zien en moet je in je code vervolgens nog eens een check doen of hij wel lukt. Terwijl je dat ook hogerop in je klasse kan afvangen.
Terence schreef op 12.04.2009 23:53
ik zou verder ook zo op deze manier werken:
public function __construct()
{
    $this->connect();    
}

public function __destruct()
{
    $this->destroyConnection();
}


daarnaast kan je ook gewoon de standaardclass gebruiken die [php]mysqli[/php] heet :)


ik had ook eerst de __destruct functie gebruikt maar ik ben er niet zeker van wanneer deze functie nou precies word uitgevoerd dus heb ik daarna een eigen class ervoor geschreven

verder thanks voor de info's vooral van de catch. dat werkt idd een stuk makkelijker en stom van mij dat ik daar niet aangedacht heb.

hier de ammended code:

<?php

class DatabaseFunctions
{
protected $_host = 'localhost';
protected $_user = 'root';
protected $_pass = 'school12';
protected $_db;

private $_connection = null;
private $_query;

public function __construct()
{
}

public function connect()
{
if (!$this->_connection = mysql_connect($this->_host, $this->_user, $this->_pass))
{
throw new Exception("Connection failed!");
}
}

public function selectDB($db)
{
if (!mysql_select_db($db))
{
throw new Exception("DB not found!");
}
}

public function selectSQL($SQL)
{
if ($this->_connection === null)
{
$this->_connect();
}
$this->selectDB = $this->_db;
return $this->_query = mysql_query($SQL);
}

public function destroyConnection()
{
if ($this->connection === null)
{
mysql_free_result($this->_query);
mysql_close($this->_connection);
}
else
{
throw new Exception("Could not close the database connection!");
}
return $this->connection;
}
}
?>


<?php

	require_once 'core_classes/DatabaseFunctions.php';
	
	$database = new DatabaseFunctions();
?>


<html>
<body>
	<?php $database->connect(); ?>
	<?php $database->selectDB('contapp'); ?>
	<?php $test = $database->selectSQL('SELECT * FROM test'); ?>
	<?php 
		while ($row = mysql_fetch_array($test))
		{		
			echo $row['id'] . " " . $row['text'] . " " . $row['date'] . "<br />";
		}
		
		try
		{
			$database->destroyConnection();	
		}
		catch(Exception $e)
		{
			echo $e;
		}
	?>
			
</body>
</html>

Even een voorbeeldje:
<?php
class test{
function __construct(){
echo 'constructor is aangeroepen'.PHP_EOL;
}

function __destruct(){
echo 'destructor is aangeroepen'.PHP_EOL;
}
}

$test = new test(); // aanmaken object, constructor wordt aangeroepen

echo 'doe iets'.PHP_EOL;

$test = null; // verwijderen object, destructor wordt aangeroepen

echo 'klaar.'.PHP_EOL;
?>

Mocht je niet zelf het object verwijderen, dan gebeurt dit bij het afsluiten van het script automatisch. Laat $test = null; maar eens weg uit de code en je ziet het vanzelf.
Maar je doet nu verder niets met de constructor? Waarom roep je daar niet je connect() method aan?

Verder zou ik de database specifieke gegevens (gebruikersnaam, wachtwoord, database) niet binnen je klasse declareren maar juist laten opgeven bij het instantieren van de klasse. Op die manier kun je hem voor elke willekeurige database gebruiken, iets dat juist het doel is van OO programmeren.

Deze twee opmerkingen samen gevoegd:
<?php
public function __construct($host, $user, $pass, $db)
{
$this->_connect($host, $user, $pass);
$this->_selectDB($db);
}

protected function _connect($host, $user, $pass)
{
if (!$this->_connection = mysql_connect($host, $user, $pass))
{
throw new Exception("Connection failed!");
}
}

protected function _selectDB($db)
{
if (!mysql_select_db($db))
{
throw new Exception("DB not found!");
}
}
?>
In je procedurele code zou ik je try blok al veel eerder beginnen. Eigenlijk wil je elke method die een exception kan genereren in een try/catch combinatie hebben staan.
Blanche schreef op 13.04.2009 10:55
Maar je doet nu verder niets met de constructor? Waarom roep je daar niet je connect() method aan?

Verder zou ik de database specifieke gegevens (gebruikersnaam, wachtwoord, database) niet binnen je klasse declareren maar juist laten opgeven bij het instantieren van de klasse. Op die manier kun je hem voor elke willekeurige database gebruiken, iets dat juist het doel is van OO programmeren.

Deze twee opmerkingen samen gevoegd:
In je procedurele code zou ik je try blok al veel eerder beginnen. Eigenlijk wil je elke method die een exception kan genereren in een try/catch combinatie hebben staan.


Na het 1,5 uur testen van een aantal dingen die jullie me aangeraden hadden wil ik jullie echt werkelijk harstikke bedanken voor de uitleg jongens. Ik heb nu door hoe de __destruct werkt en heb hem nu volledig OOP gemaakt.

ammended code:

<?php

class DatabaseFunctions
{
private $_connection = null;
private $_query;

public function __construct($host, $user, $pass, $db)
{
echo "constructor started <br />";
$this->_connect($host, $user, $pass);
$this->_selectDB($db);
}

public function __destruct()
{
echo "destructor started";
}

protected function _connect($host, $user, $pass)
{
if (!$this->_connection = mysql_connect($host, $user, $pass))
{
throw new Exception("Connection failed!");
}
}

protected function _selectDB($db)
{
if (!mysql_select_db($db))
{
throw new Exception("DB not found!");
}
}

public function selectSQL($SQL)
{
if ($this->_connection === null)
{
$this->_connect();
$this->_selectDB();
}

try {
$this->_query = mysql_query($SQL);
}
catch (Exception $e) {
echo $e;
}

return $this->_query;
}
}
?>

<?php
require_once 'core_classes/DatabaseFunctions.php';
try {
$database = new DatabaseFunctions('localhost', 'root', 'school12', 'contapp');
}
catch (Exception $e) {
echo $e;
}
?>


<?php
	require_once 'core_classes/ConnectionInfo.php';
?>

<html>
<body>
	<?php $test = $database->selectSQL('SELECT * FROM test');

		while ($row = mysql_fetch_array($test))
		{		
			echo $row['id'] . " " . $row['text'] . " " . $row['date'] . "<br />";
		}
	?>		
	<br />
	<p> dit is wat text </p>
	<?php $test2 = $database->selectSQL('SELECT * FROM test');

		while ($row = mysql_fetch_array($test2))
		{		
			echo $row['text'] . " " . $row['date'] . "<br />";
		}
	?>			
</body>
</html>


OUTPUT:

constructor started 
1 wsdfs 2009-04-10
2 sfdxfdf bfdv dm 2009-04-25


dit is wat text 

wsdfs 2009-04-10
sfdxfdf bfdv dm 2009-04-25
destructor started


ik heb echter nog steeds 2 kleine vraagjes:
1: ik heb ik de functie "selectSQL" en "de construct in een try/catch functie staan maar is het nu ook nog mogelijk om een custom 'throw new Exception' te geven? zoja waar kan ik dat doen? ik dacht dat ik die op $e kon zetten maar dan krijg ik errors.

2: Zoals je kan zien in de output worden alle query's eerst uitgevoerd en daarna pas word de connectie gesloten met destruct. Kan ik dit zo maken dat die na iedere actie opent en sluit? $this->__destruct() bleek niet te werken.
1. Je hoeft niet voor elke method een aparte try/catch combinatie te gebruiken, je kunt het ook met een (of enkele) blokken af:
<?php
try
{
$database = new DatabaseFunctions($host, $user, $pass, $db);
$result = $database->selectSQL(...);
$result2 = $database->selectSQL(...);
$result3 = $database->selectSQL(...);
// etc...
}
catch(Exception $e)
{
echo $e;
}
?>
Alle opeenvolgende handelingen die van elkaar afhankelijk zijn, plaats je in hetzelfde try blok. Zodra er een van die handelingen mislukt, wordt de rest van de uitvoer van dat try blok gestopt en gaat het script over naar je catch blok. Als in bovenstaand voorbeeld de database connectie mislukt, zullen de queries nooit uitgevoerd worden. En dat is precies wat je wilt.

Het gooien van een nieuwe exception zul je binnen een try blok moeten doen dat opgevolgd wordt door een catch blok. Je zult die exception immers ergens moeten opvangen. Bijvoorbeeld:
<?php
try
{
if(true != false)
{
throw new Exception('true != false');
}
}
catch(Exception $e)
{
echo $e;
}
?>
Zie voor meer informatie ook deze handleiding over foutafhandeling in PHP.

2. Waarom zou je voor iedere query een nieuwe verbinding op willen zetten? Dat is nergens voor nodig en bovendien erg tijdrovend en belastend voor je database.

Reageren