2017-09-08 11 views
0

J'ai une configuration compliquée pour une situation de magasin.PHP - utiliser sleep() après une redirection d'en-tête

Les gens peuvent acheter des produits uniques dans un court laps de temps et payer via PayPal. Je dois donc être sûr que les produits ne sont pas achetés plusieurs fois. À cette fin sur la caisse, j'utilise un fichier PHP personnalisé qui met à jour les éléments de la base de données à un état "réservé", puis envoie le formulaire à PayPal via header(). Tout cela fonctionne très bien. Étant donné que nous avons des articles à vendre et un délai si limité, je veux rendre les articles disponibles à nouveau si l'acheteur abandonne le processus de paiement. J'ai PDT mis en place et en cours d'exécution, mais le protocole de transaction vient parfois avec un délai prolongé. Donc, dix minutes après le paiement, je veux vérifier la base de données pour voir si la transaction est arrivée. Si l'article est vraiment vendu (le statut est modifié par le script PDT) tout va bien, s'il n'est pas vendu, je veux réinitialiser le statut de réservation et rendre l'article disponible pour d'autres acheteurs à nouveau.

Voici la configuration de mon code:

if ($resstatus == "0"){ 
    $result = mysqli_query($mysqli, "UPDATE `table` SET `Reserved`='1' WHERE `AID`='$AID' AND `itemID`='$itemD1'"); 
    header('Location: https://www.paypal.com/cgi-bin/webscr?'.$post_string); 
    sleep(600); //wait ten minutes before checking DB 
    if ($sold == "0"){ 
     $reset = mysqli_query($mysqli, "UPDATE `table` SET `Reserved`='0' WHERE `AID`='$AID' AND `itemID`='$itemD1'"); 
    } 
} 

Tout est exécuté, mais la redirection d'en-tête est également retardé le laps de temps défini dans sleep(). Cela n'a aucun sens pour moi. Si cela redirigeait et n'exécutait rien après, c'est une chose. Mais il exécute tout mais se comporte comme si l'ordre était d'abord sleep() puis header().

Je vais maintenant adopter une approche différente en enregistrant un horodatage à la caisse et en vérifiant si des unités avec des timestamps de réservation datant de plus de dix minutes sont chargées. Cela devrait fonctionner et est probablement plus élégant.

Mais je suis toujours intrigué par le comportement ci-dessus et je voudrais savoir où mon erreur de raisonnement est enterrée.

+1

[Petit Bobby] (http://bobby-tables.com/) dit ** [vous pouvez être à risque de Attaques d'injection SQL] (https://stackoverflow.com/q/60174/) **. En savoir plus sur [Prepared Statements] (https://en.wikipedia.org/wiki/Prepared_statement) avec [requêtes paramétrées] (https://stackoverflow.com/a/4712113/5827005). Je recommande 'PDO', que j'ai [a écrit une fonction pour] (http://paragoncds.com/grumpy/pdoquery/#function) pour le rendre extrêmement facile, propre et plus sûr que d'utiliser des requêtes non paramétrées. [Cela peut vous aider à choisir entre 'MySQLi' et' PDO'] (http://php.net/manual/fr/mysqlinfo.api.choosing.php). – GrumpyCrouton

Répondre

0

Cela dépend du SAPI que vous utilisez. Néanmoins, vous ne pouvez pas compter sur le code après le sommeil pour être exécuté et vous devriez vraiment utiliser un travail cron qui vérifie les horodatages et supprime les réservations.

D'autant plus que vous avez un tel délai, le serveur mettrait probablement fin au script long. En outre, votre script pendant le sommeil lie également l'un des processus qui pourrait être utilisé pour servir d'autres contenus.

BTW, ce serait probablement:

ob_start(); 
header('Location: https://www.paypal.com/cgi-bin/webscr?'.$post_string); 
ob_end_flush(); 
flush(); 
ob_end_clean(); 
sleep(600); 

Voir aussi here

+0

Je l'ai fait sans cronjob maintenant. Fondamentalement, je mets à jour la base de données chaque fois que quelqu'un charge la page de la boutique. Fonctionne bien. J'étais juste irrité que tout après l'en-tête() était en cours d'exécution mais en-tête() lui-même a été retardé. Merci d'avoir pris le temps d'expliquer! – berlinaise