修改
这次我会尝试更好的解释,这是我的脚本中的确切代码(对不起他们所有的内容,他们是你的sugestions的结果,以及下面视频中的apear)。
#use warnings;
#use Data::Dumper;
open(my $tmp_file, ">>", "/tmp/some_bad.log") or die "Can not open log file: $!\n";
#if( $id_client != "")
@allowed_locations = ();
#print $tmp_file "Before the if: ". Data::Dumper->Dump([\@allowed_locations, $id_client]) . "";
if( $id_client )
{
# print $tmp_file "Start the if: ". Data::Dumper->Dump([\@allowed_locations, $id_client]) . "";
# my $q = "select distinct id_location from locations inner join address using (id_db5_address) inner join zona_rural_detaliat using (id_city) where id_client=$id_client";
# my $st = &sql_special_transaction($sql_local_host, $sql_local_database, $sql_local_root, $sql_local_root_password, $q);
# print $tmp_file "Before the while loop: ref(st)='". ref($st) . "\n";
# while((my $id)=$st->fetchrow())
# {
# print $tmp_file "Row the while loop: ". Data::Dumper->Dump([$id]) . "";
# my $id = 12121212;
# push(@allowed_locations, $id);
# }
# print $tmp_file "After the while loop: ref(st)='". ref($st) . "\n";
# my($a) = 1;
#} else {
# my($a) = 0;
}
#print $tmp_file "After the if: ". Data::Dumper->Dump([\@allowed_locations, $id_client]) . "";
close($tmp_file) or die "Can not close file: $!\n";
#&html_error(@allowed_locations);
首先,有人说我应该尝试在命令行中运行它,脚本在命令行中运行正常(没有警告,它当时没有注释),但是当triyng要在浏览器中通过apache加载它失败,请参阅this video我捕获脚本行为的位置,我试图在视频中显示的内容:
我打开了2个标签,第一个没有定义变量$ id_client,第二个定义了从GET读取的变量$ id_client:?id_client = 36124 => $ id_client = 36124; ,两者都包含视频“ locallib.pl ”中的库
我在命令行中运行脚本时复制了所有步骤,并且每个步骤后脚本都有效 我知道这听起来不像剧本的行为,但请观看视频(2分钟),也许你会注意到我在那里做错了。
使用perl版本:
[root@db]# perl -v
This is perl, v5.8.6 built for i386-linux-thread-mult
有人问我是否没有测试服务器,回答:不,我的公司有一个具有多种用途的生产服务器,不仅仅是Web界面,而且我无法冒险更新内核或perl版本,以及不能冒险安装任何debuger,因为公司老板说:“如果它有效,请不要管它”,对于他们来说我($ a); 的解决方案是完美的,因为它有效,我是在这里问我,了解更多有关perl的信息,了解出了什么问题以及下次我能做些什么。
谢谢。
P.S。希望这种新方法能够恢复我的一些-1:)
修改
我成功启动了错误日志记录,并在每个导致失败的步骤后在错误日志中找到了这个消息我得到了这个消息:
[2010年7月15日星期四14:29:19] [错误] locallib.pl未在/var/www/html/rdsdb4/cgi-bin/clients/quicksearch.cgi第2行返回真值。
[2010年7月15日星期四14:29:19] [错误]脚本标题过早结束:quicksearch.cgi
我发现这个代码位于locallib.pl主代码的末尾,之后有子定义,而locallib.pl是一个库而不是程序文件,所以它的最后一个语句必须返回true。,库末尾的一个简单的 1; 语句确保(我把它放在子定义之后,以确保没有人在1;之后在main中写代码)和问题得到解决 不知道为什么在CLI中没有问题...
也许我现在会得到很多票数(温柔:)),但我能做些什么......我希望有些新手会读到这些并从我的错误中学到一些东西。
谢谢大家的帮助。
答案 0 :(得分:4)
您需要明确检查定义。
如果要在定义$ client时进入循环,
使用if ( defined $client )
。
如果要在定义$ client和有效整数时进入循环,
使用if ( defined $client && $client =~ /^-?\d+$/ )
。
我假设它是来自上下文的整数,如果它可以是一个浮点数,则需要增强正则表达式 - 有一个标准的Perl库包含预先制作的正则表达式,包括匹配浮点数的正则表达式。如果您需要非负的int,请从正则表达式的开头删除-?
。
如果你想在定义$ client时输入循环并且非零(并假设它不应该是空字符串),
使用if ( $client )
。
如果要在定义$ client和有效的非零int时进入循环,
使用if ( $client && $client =~ /^-?\d+$/ )
。
当if
条件为false时,您的@ids为“undef”,如果它依赖于@ids为数组,则可能会在以后破坏代码。由于您没有实际指定如何脚本在没有else
的情况下中断,因此这是最可能的原因。
请查看这个版本是否有效(使用上面你需要的“if”条件,我选择了最后一个,因为它看起来与最接近的原始代码的意图匹配 - 只输入非零整数):
调试更新后的代码
use Data::Dumper;
open(my $tmp_file, ">", "/tmp/some_bad.log") or die "Can not open log file: $!\n";
@ids = (); # Do this first so @ids is always an array, even for non-client!
print $tmp_file "Before the if: ". Data::Dumper->Dump([\@ids, $client]) . "\n";
if ( $client && $client =~ /^-?\d+$/ ) # First expression catches undef and zero
{
print $tmp_file "Start the if: ". Data::Dumper->Dump([\@ids, $client]) . "\n";
my $st = &sql_query("select id from table where client=$client");
print $tmp_file "Before the while loop: ref(st)='". ref($st) . "'\n";
while(my $row = $st->fetchrow())
{
print $tmp_file "Row the while loop: ". Data::Dumper->Dump([row]) . "'\n";
push(@ids, $row->[0]);
}
print $tmp_file "After the while loop: ref(st)='". ref($st) . "'\n";
# No need to undef since both variables are lexically in this block only
}
print $tmp_file "After the if\n";
close($tmp_file) or die "Can not close file: $!\n";
答案 1 :(得分:3)
检查字符串时,==和!=应分别为'eq'或'ne'
if( $client != "" )
应该是
if( $client ne "" )
否则你没有得到你期望得到的东西。
答案 2 :(得分:2)
注意:此答案已删除,因为我认为这不是一个真正的问题。为了拯救其他人重复此事,我取消删除它。
而不是
if( $client != "" )
试
if ($client)
此外,如果您
,Perl调试会更容易 use warnings;
use strict;
答案 3 :(得分:2)
始终以:
开始您的脚本use warnings;
use strict;
这些将为您提供有用的信息。
然后你可以写:
my @ids;
if (defined $client) {
@ids = (); # not necessary if you run this part only once
my $st = sql_query("select id from table where client=$client");
while( my ($id) = $st->fetchrow ) {
push @ids, $id;
}
} else {
warn '$client not defined';
}
if (@ids) { # Your query returned something
# do stuff with @ids
} else {
warn "client '$client' does not exist in database";
}
答案 4 :(得分:0)
我发现这个代码位于locallib.pl主代码的末尾,之后有子定义,而locallib.pl是一个库而不是程序文件,所以它的最后一个语句必须返回true ,简单1;库末尾的语句确保(在子定义之后放置它以确保没有人在1之后在main中写代码)并且问题得到修复。
结论:
我了解到每次编写库或修改库时,请确保它的最后一个参数返回true;
答案 5 :(得分:-4)
哦,我的......试试这个例子......
# Move the logic into a subroutine
# Forward definition so perl knows func exists
sub getClientIds($);
# Call subroutine to find id's - defined later.
my @ids_from_database = &getClientIds("Joe Smith");
# If sub returned an empty list () then variable will be false.
# Otherwise, print each ID we found.
if (@ids_from_database) {
foreach my $i (@ids_from_database) {
print "Found ID $i \n";
}
} else {
print "Found nothing! \n";
}
# This is the end of the "main" code - now we define the logic.
# Here's the real work
sub getClientIds($) {
my $client = shift @_; # assign first parameter to var $client
my @ids = (); # what we will return
# ensure we weren't called with &getClientIds("") or something...
if (not $client) {
print "I really need you to give me a parameter...\n";
return @ids;
}
# I'm assuming the query is string based, so probably need to put it
# inside \"quotes\"
my $st = &sql_query("select id from table where client=\"$client\"");
# Did sql_query() fail?
if (not $st) {
print "Oops someone made a problem in the SQL...\n";
return @ids;
}
my @result;
# Returns a list, so putting it in a list and then pulling the first element
# in two steps instead of one.
while (@result = $st->fetchrow()) {
push @ids, $result[0];
}
# Always a good idea to clean up once you're done.
$st->finish();
return @ids;
}
针对您的具体问题:
我也回应Kinopiko建议你在程序开始时添加“use strict;”。这意味着你使用的任何$变量@that%必须预先定义为“我的$ varable;我的@that;我的%你;”这似乎更多的工作,但它的工作更少而不是尝试在代码中处理未定义的变量和定义的变量。这是一个很好的习惯。
请注意,我的变量只存在于定义它们的squiggliez中(整个文件周围存在隐含的squiggliez:
my $x = 1;
if ($x == 1)
{
my $x = 2;
print "$x \n"; # prints 2. This is NOT the same $x as was set to 1 above.
}
print "$x \n"; # prints 1, because the $x in the squiggliez is gone.