2010-05-01 6 views
2

L'utilisateur entre un code de produit, un prix et un nom en utilisant un formulaire. Le script l'ajoute ensuite à la base de données ou le supprime de la base de données. Si l'utilisateur tente de supprimer un produit qui ne se trouve pas dans la base de données, il reçoit un message d'erreur. Après l'ajout ou la suppression réussie, ils reçoivent également un message. Cependant, quand je l'ai testé, j'ai juste une page blanche. Perl ne propose aucun avertissement, aucune erreur de syntaxe ou quoi que ce soit; dit que tout va bien, mais je reçois toujours une page blanche.Pourquoi une page vierge est-elle générée par mon script Perl CGI?

Le script:

#!/usr/bin/perl 
#c09ex5.cgi - saves data to and removes data from a database 
print "Content-type: text/html\n\n"; 
use CGI qw(:standard); 
use SDBM_File; 
use Fcntl; 
use strict; 

#declare variables 
my ($code, $name, $price, $button, $codes, $names, $prices); 


#assign values to variables 
$code = param('Code'); 
$name = param('Name'); 
$price = param('Price'); 
$button = param('Button'); 

($code, $name, $price) = format_input(); 
($codes, $names, $prices) = ($code, $name, $price); 

if ($button eq "Save") { 
     add(); 
} 
elsif ($button eq "Delete") { 
     remove(); 
} 
exit; 


sub format_input { 
     $codes =~ s/^ +//; 
     $codes =~ s/ +$//; 
     $codes =~ tr/a-z/A-Z/; 
     $codes =~ tr/ //d; 
     $names =~ s/^ +//; 
     $names =~ s/ +$//; 
     $names =~ tr/ //d; 
     $names = uc($names); 
     $prices =~ s/^ +//; 
     $prices =~ s/ +$//;  
     $prices =~ tr/ //d; 
     $prices =~ tr/$//d; 
    } 


sub add { 
    #declare variable 
    my %candles; 

#open database, format and add record, close database 
    tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
      or die "Error opening candlelist. $!, stopped"; 

    format_vars(); 
    $candles{$codes} = "$names,$prices"; 
    untie(%candles); 

#create web page  
     print "<HTML>\n"; 
     print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
     print "<BODY>\n"; 
     print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
     print "Candle: $codes $names $prices</FONT>\n"; 
     print "</BODY></HTML>\n"; 
     } #end add 


sub remove { 
    #declare variables 
    my (%candles, $msg); 

tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
      or die "Error opening candlelist. $!, stopped"; 

    format_vars(); 

    #determine if the product is listed 
    if (exists($candles{$codes})) { 
      delete($candles{$codes}); 
      $msg = "The candle $codes $names $prices has been removed."; 
     } 
    else { 
    $msg = "The product you entered is not in the database"; 
    } 
    #close database 
    untie(%candles); 

#create web page 
print "<HTML>\n"; 
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
print "<BODY>\n"; 
print "<H1>Candles Unlimited</H1>\n"; 
print "$msg\n"; 
print "</BODY></HTML>\n"; 
} 
+1

http://perldoc.perl.org/perldebtut! .html – Ether

Répondre

1

Son exécution à la ligne de commande avec:

perl something.cgi Button=Save 

... me donne une erreur:

Undefined subroutine &main::format_vars called at something.pl line 55. 

Si je change les références de format_vars() à "format_input()", j'obtiens ce que je pense être la bonne sortie.

+0

Correction de cela, mais je reçois toujours une page vierge. – Jason

+0

Essayez d'ajouter une impression "$ button \ n"; après avoir obtenu les paramètres, ligne 19 ou plus. Assurez-vous de recevoir les informations que vous attendez. Rappelez-vous que la vérification de l'eq est sensible à la casse, donc si button = "save" cela ne fonctionnera pas. Faire une source de vue sur la sortie, jusqu'où va-t-elle? Pouvez-vous l'exécuter via la ligne de commande? – SqlACID

+0

Si j'ajoute la ligne du bouton d'impression, il apparaît Enregistrer, comme il se doit. Autre que bien que ce soit encore juste une page vierge, la source de la page ne montre même rien, juste vide, pas de code du tout. – Jason

1

Vous n'imprimez aucune sortie en dehors de l'en-tête Content-Type sauf siou remove est appelé. Le problème est juste que vous avez oublié d'afficher un formulaire (probablement celui contenant les boutons) si aucun bouton n'a été cliqué.

Edit: Copier votre code affiché et faire un peu de nettoyage, puis appeler à l'adresse http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Save ou http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Delete, je reçois une bonne sortie HTML. La version nettoyée du code utilisé pour cela est:

#!/usr/bin/perl 

use strict; 
use warnings; 

print "Content-type: text/html\n\n"; 
use CGI qw(:standard); 
use SDBM_File; 
use Fcntl; 
use strict; 

#declare variables 
my ($code, $name, $price, $button, $codes, $names, $prices); 


#assign values to variables 
$code = param('Code'); 
$name = param('Name'); 
$price = param('Price'); 
$button = param('Button'); 

($code, $name, $price) = format_input(); 
($codes, $names, $prices) = ($code, $name, $price); 

if ($button eq "Save") { 
    add(); 
} 
elsif ($button eq "Delete") { 
    remove(); 
} 
exit; 


sub format_input { 
    $codes =~ s/^ +//; 
    $codes =~ s/ +$//; 
    $codes =~ tr/a-z/A-Z/; 
    $codes =~ tr/ //d; 
    $names =~ s/^ +//; 
    $names =~ s/ +$//; 
    $names =~ tr/ //d; 
    $names = uc($names); 
    $prices =~ s/^ +//; 
    $prices =~ s/ +$//; 
    $prices =~ tr/ //d; 
    $prices =~ tr/$//d; 
    } 

sub add { 
# #declare variable 
# my %candles; 
# 
# #open database, format and add record, close database 
#  tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
#   or die "Error opening candlelist. $!, stopped"; 
# 
#  format_vars(); 
#  $candles{$codes} = "$names,$prices"; 
#  untie(%candles); 

#create web page  
print "<HTML>\n"; 
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
print "<BODY>\n"; 
print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
print "Candle: $codes $names $prices</FONT>\n"; 
print "</BODY></HTML>\n"; 
} #end add 


sub remove { 
# #declare variables 
# my (%candles, $msg); 
# 
# tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
#   or die "Error opening candlelist. $!, stopped"; 
# 
#  format_vars(); 
# 
#  #determine if the product is listed 
#  if (exists($candles{$codes})) { 
#   delete($candles{$codes}); 
#   $msg = "The candle $codes $names $prices has been removed."; 
#  } 
#  else { 
#  $msg = "The product you entered is not in the database"; 
#  } 
#  #close database 
#  untie(%candles); 

    #create web page 
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<H1>Candles Unlimited</H1>\n"; 
# print "$msg\n"; 
    print "<p>Called remove</p>"; 
    print "</BODY></HTML>\n"; 
    } 

Notez que, avec warnings permis, ce SPEWS beaucoup d'avertissements « valeur non initialisée » parce que vous obtenez $code vs $codes, $name vs $names, et $price vs $prices confondus les uns avec les autres de mauvaises manières. (Astuce: Vous affectez ($code, $name, $price) = format_input();, mais format_input ne renvoie pas trois valeurs.)

Je suppose que, comme suggéré dans un commentaire précédent, vous rencontrez encore des problèmes de sensibilité à la casse. Ma première tentative de test a échoué car j'ai utilisé "button = Save" au lieu de "Button = Save" dans l'URL. Les noms de paramètre de requête HTTP sont généralement en minuscules par convention, et pour de bonnes raisons, car cela aide à éviter les problèmes de ce genre.

Autres commentaires au hasard:

  • Vous pouvez déclarer vos variables en même temps que vous devez d'abord les assigner, par exemple, my $code = param('Code');. Ceci est généralement considéré comme la meilleure pratique/préférée, car faire votre déclaration le plus tard possible permet de minimiser la portée de la variable.

  • En format_input, il est redondant à la fois s/^ +//; s/ +$//; et tr/ //d;, comme tr supprimerons également les espaces de fuite. Lors de l'obtention des valeurs de vos paramètres, vous devez soit fournir les valeurs par défaut pour si le paramètre est vide/manquant ou vérifier vide/manquant et afficher une erreur à l'utilisateur.

  • Vous devez également avoir une clause else finale après l'elsif ($button eq "Delete") pour afficher une erreur si $button est invalide ou manquante. Oui, je sais que ce script est destiné à être appelé à partir d'un formulaire spécifique, il devrait donc toujours avoir un $button valide, mais il est trivial de contourner le formulaire et de soumettre tout ensemble de valeurs (valide ou non) au script directement, Vous devez donc tout vérifier et tout valider du côté serveur car vous ne savez pas d'où il proviendra ni si le client l'a validé correctement.

+0

Cela n'a aucun sens. Je peux ajouter une ligne de bouton d'impression et vérifier que la valeur du bouton est transmise, ce qui signifie que l'ajout ou le retrait d'IS est appelé et que je reçois toujours une page vierge. Le formulaire appelle le script une fois que le bouton a été pressé, et non l'inverse. – Jason

0

Voici comment j'ai exécuté le script et il a donné les bons résultats. Assurez-vous que les modules PERL installés sont installés partout où vous hébergez le site.

Note: Le service d'hébergement J'utilise (BlueHost) me demande d'appeler mes modules Perl via le #/usr/bin/perlml

#!/usr/bin/perlml 

    use strict; 
    use warnings; 

    print "Content-type: text/html\n\n"; 
    use CGI qw(:standard); 
    use SDBM_File; 
    use Fcntl; 
    use strict; 

    #declare variables 
    my ($code, $name, $price, $button, $codes, $names, $prices); 


    #assign values to variables 
    $code = param('Code'); 
    $name = param('Name'); 
    $price = param('Price'); 
    $button = param('Button'); 

    ($codes, $names, $prices) = format_input(); 
    ($codes, $names, $prices) = ($code, $name, $price); 

    if ($button eq "Save") { 
    add(); 
    } 
    elsif ($button eq "Delete") { 
    remove(); 
    } 
    exit; 


    sub format_input { 
    $codes =~ s/^ +//; 
    $codes =~ s/ +$//; 
    $codes =~ tr/a-z/A-Z/; 
    $codes =~ tr/ //d; 
    $names =~ s/^ +//; 
    $names =~ s/ +$//; 
    $names =~ tr/ //d; 
    $names = uc($names); 
    $prices =~ s/^ +//; 
    $prices =~ s/ +$//; 
    $prices =~ tr/ //d; 
    $prices =~ tr/$//d; 
    } 

    sub add { 
    #declare variable 
    my %candles; 

    #open database, format and add record, close database 
    tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
    or die "Error opening candlelist. $!, stopped"; 

    format_input(); 
    $candles{$code} = "$name,$price"; 
    untie(%candles); 

    #create web page  
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
    print "Candle: $codes, $names, $prices</FONT>\n"; 
    print "</BODY></HTML>\n"; 
    } #end add 

    sub remove { 
    #declare variables 
    my (%candles, $msg); 

    tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
    or die "Error opening candlelist. $!, stopped"; 
    format_input(); 

    #determine if the product is listed 
    if (exists($candles{$code})) { 
    delete($candles{$code}); 
    $msg = "The candle $code, $name, $price has been removed."; 
    } 
    else { 
    $msg = "The product you entered is not in the database"; 
    } 
    #close database 
    untie(%candles); 

    #create web page 
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<H1>Candles Unlimited</H1>\n"; 
    print "$msg\n"; 
    print "</BODY></HTML>\n"; 
    } 
Questions connexes