我有一个Perl脚本,它从数据库中读取数据并在HTML表单/表格中打印出结果。每本书的形式还包含一个提交按钮。
我希望Perl创建一个文本文件(或读入已创建的文本文件)并打印提交表单中的书名。但我似乎无法让param()
抓住提交行动!
#!/usr/bin/perl -w
use warnings; # Allow for warnings to be sent if error's occur
use CGI; # Include CGI.pm module
use DBI;
use DBD::mysql; # Database data will come from mysql
my $dbh = DBI->connect('DBI:mysql:name?book_store', 'name', 'password')
or die("Could not make connection to database: $DBI::errstr"); # connect to the database with address and pass or return error
my $q = new CGI; # CGI object for basic stuff
my $ip = $q->remote_host(); # Get the user's ip
my $term = $q->param('searchterm'); # Set the search char to $term
$term =~ tr/A-Z/a-z/; # set all characters to lowercase for convenience of search
my $sql = '
SELECT *
FROM Books
WHERE Title LIKE ?
OR Description LIKE ?
OR Author LIKE ?
'; # Set the query string to search the database
my $sth = $dbh->prepare($sql); # Prepare to connect to the database
$sth->execute("%$term%", "%$term%", "%$term%")
or die "SQL Error: $DBI::errstr\n"; # Connect to the database or return an error
print $q->header;
print "<html>";
print "<body>";
print " <form name='book' action='bookcart.php' method=post> "; # Open a form for submitting the result of book selection
print "<table width=\"100%\" border=\"0\"> ";
my $title = $data[0];
my $desc = $data[1];
my $author = $data[2];
my $pub = $data[3];
my $isbn = $data[4];
my $photo = $data[5];
print "<tr> <td width=50%>Title: $title</td> <td width=50% rowspan=5><img src=$photo height=300px></td></tr><tr><td>Discreption Tags: $desc</td></tr><tr><td>Publication Date: $pub</td></tr><tr><td>Author: $author</td></tr><tr><td>ISBN: $isbn</td> </tr></table> <br>";
print "Add this to shopping cart:<input type='submit' name='submit' value='Add'>";
if ($q->param('submit')) {
open(FILE, ">>'$ip'.txt");
print FILE "$title\n";
close(FILE);
}
print "</form>"; # Close the form for submitting to shopping cart
答案 0 :(得分:3)
您还没有使用use strict
来强制您声明所有变量。这是坏主意
您使用了remote_host
,它是客户端主机系统的名称。您的服务器可能无法解析此值,在这种情况下它将保持未设置状态。如果您需要IP地址,请使用remote_addr
您已准备好并执行了SQL语句,但未从查询中获取任何数据。您似乎希望结果位于数组@data
中,但您尚未声明此数组。如果你有use strict
生效
您已使用字符串'$ip'.txt
作为文件名,因此,如果您正确使用IP地址而不是主机名,则文件看起来像'92.17.182.165'.txt
。你真的想要那里的单引号吗?
您没有检查open
来电的状态,因此您不知道开放是否成功,或者原因是否失败
我怀疑你是否真的花了最后48小时编码。我认为你更有可能在最后一分钟匆匆忙忙地扔东西,并使用Stack Overflow帮你摆脱你为自己挖的洞。
在请求帮助他人之前,您至少应该使用最少的良好实践编码方法,例如应用use strict
。您还应该尽力调试代码:如果$ip
的值不正确且@data
为空,则可能很少发现。
答案 1 :(得分:1)
使用 strict
和warnings
。出于多种原因,您希望使用strict
。关于perlmonks的一篇不错的文章结束了,你可以从这开始。 Using strict and warnings
您不一定需要以下行,您正在使用DBI并且可以使用DBI严格访问mysql。
use DBD::mysql;
CGI
提供了许多选项,我建议您根据用户偏好和所需的需求来阅读perldoc。
我不会使用以下内容:
my $q = new CGI;
# I would use as so..
my $q = CGI->new;
使用remote_addr
代替remote_host来检索您的IP地址。
以下是您要将全部大写转换为小写的行,除非需要使用全部小写从数据库中专门读取,否则我觉得这没用。
$term =~ tr/A-Z/a-z/;
接下来你的$ sql行,再次是用户首选项,但我会查看sprintf
或直接在你的调用中使用它。您还试图读取一个不存在的数据数组,在哪里调用以获取数据?我建议您阅读DBI
的文档,以及许多返回数据的方法。因此,您希望使用数组返回数据...
这是一个未经测试的示例和提示,可帮助您入门。
use strict;
use warnings;
use CGI qw( :standard );
use CGI::Carp qw( fatalsToBrowser ); # Track your syntax errors
use DBI;
# Get IP Address
my $ip = $ENV{'REMOTE_ADDR'};
# Get your query from param,
# I would also parse your data here
my $term = param('searchterm') || undef;
my $dbh = DBI->connect('DBI:mysql:db:host', 'user', 'pass',
{RaiseError => 1}) or die $DBI::errstr;
my $sql = sprintf ('SELECT * FROM Books WHERE Title LIKE %s
OR Description LIKE %s', $term, $term);
my $sth = $dbh->selectall_arrayref( $sql );
# Retrieve your result data from array ref and turn into
# a hash that has title for the key and a array ref to the data.
my %rows = ();
for my $i ( 0..$#{$sth} ) {
my ($title, $desc, $author, $pub, $isbn, $pic) = @{$sth->[$i]};
$rows{$title} = [ $desc, $author, $pub, $isbn, $pic ];
}
# Storing your table/column names
# in an array for mapping later.
my @cols;
$cols[0] = Tr(th('Title'), th('Desc'), th('Author'),
th('Published'), th('ISBN'), th('Photo'));
foreach (keys %rows) {
push @cols, Tr( td($_),
td($rows{$_}->[0]),
td($rows{$_}->[1]),
td($rows{$_}->[2]),
td($rows{$_}->[3]),
td(img({-src => $rows{$_}->[4]}));
}
print header,
start_html(-title => 'Example'),
start_form(-method => 'POST', -action => 'bookcart.php'), "\n",
table( {-border => undef, -width => '100%'}, @cols ),
submit(-name => 'Submit', -value => 'Add Entry'),
end_form,
end_html;
# Do something with if submit is clicked..
if ( param('Submit') ) {
......
}
答案 2 :(得分:-2)
这假设您正在使用OO方法来CGI.pm,并且$ q是相关对象。这应该有效,假设您的脚本中有$q = new CGI
。
你可以发布剩下的剧本吗?
我已经创建了一个模型来测试它,它按预期工作:
#!/usr/bin/perl
use CGI;
my $q = new CGI;
print $q->header;
print "<form><input type=submit name=submit value='add'></form>\n";
if ($q->param('submit')) {
print "submit is \"" . $q->param('submit') . "\"\n";
}
点击提交按钮后,页面显示submit is "add"
,表示评估按计划进行。
我猜你需要做的是确保$ q是你的CGI对象,并从那里继续前进。