Error afhandeling achteraf (foreign en unique keys)
ikki007 - 15/11/2009 21:54
PHP ver gevorderde
Hallo,
Ik heb nu een beter databaseontwerp, en wil op deze manier al die controles vooraf verkleinen tot achteraf (unique en foreign keys).
Nu doe ik dit als volgt:
<?php
$res = mysql_query("INSERT INTO pages (title, seo, category) VALUES ('".$this->title."', '".$this->seo."', ".$this->category.")");
if(!$res) {
if(mysql_errno() == 1062) {
$error = 'Seo tag already exists';
} elseif(mysql_errno() == 1452) {
$error = 'Invalid category selected.';
} else {
$error = 'Unknown error ('.mysql_error().')';
}
$this->error->set($error);
}
?>
<?php
$res = mysql_query ( "INSERT INTO pages (title, seo, category) VALUES ('" . $this -> title . "', '" . $this -> seo . "', " . $this -> category . ")" ) ; if ( ! $res ) {
$error = 'Seo tag already exists' ;
$error = 'Invalid category selected.' ;
} else {
}
$this -> error -> set ( $error ) ;
}
?>
Dit werkt (alleen vind ik het al een beetje rommelig).
Alleen hoe ga ik het doen als meerdere velden UNIQUE zijn, die krijgen dan allebei de errno 1062 terug.
Of is er misschien een compleet/betere manier dergelijke constraint errors af te handelen.
Mvg,
Jarno
19 antwoorden
Gesponsorde links
Richard - 16/11/2009 11:26
Crew algemeen
Die constraints kun je een naam geven (dat raad ik je ook aan)
Als je dan de mysql_error() bekijkt, zul je zien dat die constraintnaam ook wordt genoemd, als je die er dus uit haalt en bijhoudt welke constraints welke fouten geven, is dat makkelijk te doen :]
ikki007 - 16/11/2009 16:03 (laatste wijziging 16/11/2009 16:05)
PHP ver gevorderde
Hmm ja, heb het nu op de volgende manier gedaan:
<?php
define('Q_DUPLICATE', 1062);
define('Q_FOREIGN_KEY', 1452);
//////////////////////////////////////////
public function constraint($errno, $errkey) {
if($errno == Q_DUPLICATE) {
if(mysql_errno() == Q_DUPLICATE AND strpos(mysql_error(), 'key \''.$errkey.'\'') !== false) {
return true;
}
} elseif($errno == Q_FOREIGN_KEY) {
if(mysql_errno() == Q_FOREIGN_KEY AND strpos(mysql_error(), 'CONSTRAINT `'.$errkey.'` FOREIGN') !== false) {
return true;
}
}
return false;
}
//////////////////////////////////////////
$res = mysql_query("INSERT INTO pages (title, seo, category) VALUES ('".$this->title."', '".$this->seo."', ".$this->category.")");
if(!$res) {
if($this->error->constraint(Q_DUPLICATE, 'seo')) {
$error = 'Seo tag already exists.';
} elseif($this->error->constraint(Q_FOREIGN_KEY, 'category')) {
$error = 'Invalid category.';
} else {
$error = 'Unknown error ('.mysql_error().')';
}
$this->error->set($error);
}
?>
<?php
define ( 'Q_FOREIGN_KEY' , 1452 ) ;
//////////////////////////////////////////
public function constraint( $errno , $errkey ) {
if ( $errno == Q_DUPLICATE) {
return true ;
}
} elseif ( $errno == Q_FOREIGN_KEY) {
return true ;
}
}
return false ;
}
//////////////////////////////////////////
$res = mysql_query ( "INSERT INTO pages (title, seo, category) VALUES ('" . $this -> title . "', '" . $this -> seo . "', " . $this -> category . ")" ) ; if ( ! $res ) {
if ( $this -> error -> constraint ( Q_DUPLICATE, 'seo' ) ) {
$error = 'Seo tag already exists.' ;
} elseif ( $this -> error -> constraint ( Q_FOREIGN_KEY, 'category' ) ) {
$error = 'Invalid category.' ;
} else {
}
$this -> error -> set ( $error ) ;
}
?>
Dit werkt opzich goed, alleen vind het niet superrnetjes, maar volgens mij kan dit niet veel beter toch?
Richard - 17/11/2009 15:15
Crew algemeen
Het is op zich een best nette oplossing hoor! :-)
ArieMedia - 17/11/2009 15:41
PHP ver gevorderde
Richard schreef:
Het is op zich een best nette oplossing hoor! :-)
indeed, ziet er goed uit
Misschien dat je in je klasse nog met exceptions kan werken voor de finishing touch, maar misschien dat jij een andere error afhandeling hanteert (zoals ik in je code zie)
Abbas - 17/11/2009 16:47
Crew .NET
Hoeft niet per se waar te zijn, volgende C# voorbeeld:
int x = 13;
int y = 0;
double quotient = x / y;
//Dit levert [b]wel[/b] een Exception op, namelijk:
//DivideByZeroException
int x = 13 ;
int y = 0 ;
double quotient = x / y;
//Dit levert [b]wel[/b] een Exception op, namelijk:
//DivideByZeroException
Gemakkelijker is dan toch:
int x = 13;
int y = 0;
double quotient = 0;
try
{
quotient = x / y;
}
catch (DivideByZeroException divideEx)
{
MessageBox.Show(divideEx.Message);
}
catch (Exception ex)
{
MessageBox.Show("Andere exception: " + ex.Message);
}
finally
{
//Hier eventueel nog iets doen
}
int x = 13 ;
int y = 0 ;
double quotient = 0 ;
try
{
quotient = x / y;
}
catch ( DivideByZeroException divideEx)
{
MessageBox.Show ( divideEx.Message ) ;
}
catch ( Exception ex)
{
MessageBox.Show ( "Andere exception: " + ex.Message ) ;
}
finally
{
//Hier eventueel nog iets doen
}
Dit is in mijn ogen simpeler dan eerst te gaan liggen kijken of de invoer wel correct is met een if/else. Laat maar invoeren en alles wordt netjes opgevangen!
Richard - 17/11/2009 16:52
Crew algemeen
Ja, dat kan, er zijn alleen niet zoveel standaard exceptions omdat het pas later erbij kwam :]
<?php
function blaat() {
throw new BadFunctionCallException;
}
try {
blaat();
} catch(BadFunctionCallException $e) {
echo $e->getMessage();
} catch(Exception $e) {
echo 'Andere exceptie: ' . $e->getMessage();
}
<?php
function blaat( ) {
throw new BadFunctionCallException;
}
try {
blaat( ) ;
} catch( BadFunctionCallException $e ) {
} catch( Exception $e ) {
echo 'Andere exceptie: ' . $e -> getMessage ( ) ; }
ArieMedia - 17/11/2009 19:31
PHP ver gevorderde
titjes schreef:
Een quotient kan nooit gelijk zijn aan 0, tenzij je 0 deelt door eender welk getal buiten 0!
Edit:
En als je probeert te delen door 0 dan krijg je een Exception alvorens je kan gaan kijken of je quotient 0 zou zijn.
kreeg je maar een exception.. je krijgt een lelijke php division by zero melding .
Abbas - 17/11/2009 21:21
Crew .NET
Normaal bij .NET ook, daarom dat er dan ook Exception Handling is. Als je in PHP volgende doet:
$x = 12;
$y = 0;
try
{
$result = $x / $y;
}
catch (Exception $ex)
{
echo $ex->getMessage();
}
$x = 12 ;
$y = 0 ;
try
{
$result = $x / $y ;
}
catch ( Exception $ex )
{
}
Dan ga je mij niet vertellen dat je een lelijke melding krijgt..
Gesponsorde links
Dit onderwerp is gesloten .