J'ai une table de base de données appelée league
où la colonne mail
est l'identifiant unique:
|name |mail |
|Bryan|[email protected] |
J'ai un frontend où les utilisateurs peuvent s'inscrire et ensuite j'ai ceci pour le backend:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$jinput = JFactory::getApplication()->input;
$name = $jinput->getString('name');
$mail = $jinput->getString('mail');
$columns = array('name', 'mail');
$values = array($db->quote($name), $db->quote($mail));
$query
->insert($db->quoteName('league'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
$db->setQuery($query);
$db->execute();
Maintenant, si Bryan essaie de s'inscrire avec le même courrier, une erreur se produit. Comment puis-je écrire un message au lieu de la page d'erreur normale? Je veux quelque chose comme: "Merci pour votre inscription" si la requête aboutit et "vous êtes déjà inscrit" si la requête échoue.
Vous devrez effectuer une requête select
sur votre table de base de données, en recherchant l'adresse électronique. Si un résultat est renvoyé, vous pouvez envoyer un message d'alerte, sinon exécutez la requête insert
, comme ceci:
$jinput = JFactory::getApplication()->input;
$name = $jinput->getString('name');
$mail = $jinput->getString('mail');
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('mail'))
->from($db->quoteName('league'))
->where($db->quoteName('mail') . ' = '. $db->quote($mail));
$db->setQuery($query);
$result = $db->loadResult();
if (!$result)
{
$columns = array('name', 'mail');
$values = array($db->quote($name), $db->quote($mail));
$query = $db->getQuery(true);
$query->clear();
$query->insert($db->quoteName('league'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
$db->setQuery($query);
$db->execute();
}
else
{
JFactory::getApplication()->enqueueMessage('Email already exists', 'error');
}
Étant donné que mail
est une clé de table UNIQUE (PRIMARY fonctionne de la même manière), vous pouvez accomplir la logique que vous visez avec une seule requête. Conformément aux meilleures pratiques de codage, vous devez toujours effectuer le moins de requêtes possible.
Comme vous le verrez, il n’ya aucune raison d’appeler une requête SELECT. Si aucune erreur/exception n'est détectée, votre INSERT a réussi. Si une adresse électronique en double est soumise, une exception très informative sera générée. Il vous suffit d'écouter le code d'erreur potentiel: 1062
.
Code:
$jinput = JFactory::getApplication()->input;
$name = $jinput->getString('name');
$mail = $jinput->getString('mail');
if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
JFactory::getApplication()->enqueueMessage('Invalid Email. Please Check Email & Try Again.', 'notice');
} else {
$db = JFactory::getDBO();
try {
$query = $db->getQuery(true)
->insert($db->qn('league'))
->columns($db->qn(array('name', 'mail')))
->values($db->q($name) . ',' . $db->q($mail));
$db->setQuery($query);
$db->execute();
JFactory::getApplication()->enqueueMessage('Success!', 'message'); // is only reached if no errors
} catch (Exception $e) {
if ($e->getCode() == 1062) {
JFactory::getApplication()->enqueueMessage('Duplicate Email. Please Try Another Email.', 'notice');
} else {
JFactory::getApplication()->enqueueMessage('Syntax Error. Please Contact Developer.', 'error');
}
}
}
Quelques autres petites notes:
mail
en tant que suggestion auxiliaire.$columns
Et $values
Sont "à usage unique", j'ai décidé de ne pas les déclarer et j'ai simplement ajouté les données directement dans les méthodes de requête respectives.q()
comme raccourci pour quote()
et qn()
pour quoteName()
par souci de brièveté. Pour mémoire, votre requête sera tout aussi sûre/couronnée de succès sans aucun des appels qn()
, car vous utilisez des mots statiques uniques et aucun mot n'est réservé à la MYSQL RESERVED.