2013-01-23 59 views
0

我的問題是:輸出不同,當我在linux機器上運行程序,並在另一臺機器的Web瀏覽器上。無法使用Perl CGI程序連接到SQLite數據庫文件

當我在Linux機器上運行程序,輸出:

Content-type: text/plain 
11 
22 
username password 

但是當我把一個Apache服務器上的程序,並使用另一臺機器上的瀏覽器訪問它,輸出是簡單:

11 

這可能是因爲程序無法連接到數據庫文件。由於我已將所有文件設置爲模式777,因此我沒有權限不太可能是原因。

任何人都知道問題是什麼以及如何解決它?

#!/usr/bin/perl -w 

use DBI; 

print ("Content-type: text/plain\n\n"); 

print "11\n"; 
my $dbh = DBI->connect("dbi:SQLite:dbname=4140.db","","",{RaiseError => 1},) or die $DBI::errstr; 
print "22\n"; 

my $sth = $dbh -> prepare("SELECT * FROM Credential"); 
$sth -> execute(); 

($usrname, $password) = $sth -> fetchrow(); 

$sth -> finish(); 
$dbh->disconnect(); 

print "$usrname $password\n"; 
+0

什麼是錯誤信息? – melpomene

+0

我剛剛拿到一個帶有「11」的頁面。沒有其他消息。 – ZHOU

+2

我不是在談論這個頁面。我的意思是錯誤日誌中的錯誤信息(同樣,你缺少'使用警告;嚴格使用')。 – melpomene

回答

1

die字符串發送到STDERR,因此不會出現在發送的HTTP消息中。您可以通過幾種方法解決這個問題,最簡單的方法是編寫一個將錯誤消息輸出到STDOUT的DBI錯誤的錯誤處理程序。

您還應該總是use strictuse warnings。這樣Perl會突出顯示很多簡單的錯誤,否則您可能會輕易忽略這些錯誤在命令行上,use warnings遠遠優於-w

以此代碼爲例。請注意,如果啓用RaiseError以及提供錯誤處理程序,那麼DBI僅在您的錯誤處理程序返回錯誤值時纔會引發異常。

#!/usr/bin/perl 

use strict; 
use warnings; 

use DBI; 

print ("Content-type: text/plain\n\n"); 

print "11\n"; 

my $dbh = DBI->connect('dbi:SQLite:dbname=4140.db','','', 
    {RaiseError => 1, PrintError => 0, HandleError => \&handle_error}); 

print "22\n"; 

my $sth = $dbh->prepare('SELECT * FROM Credential'); 
$sth->execute; 

my ($usrname, $password) = $sth -> fetchrow(); 

print "$usrname $password\n"; 

sub handle_error { 
    my ($msg, $dbh, $rv) = @_; 
    print "DB Error: $msg\n"; 
    0; 
} 
+0

你錯了。我寫了一個方法讓OP看到他的Web客戶端中的數據庫錯誤。它們仍然會被髮送到錯誤日誌以及由於使用嚴格違規或其他任何其他錯誤引起的任何其他錯誤。 – Borodin

+0

[好吧,我誤解了一個觀點。修復:]只處理數據庫錯誤的異常處理方案是無用的。有多諷刺的是,你推薦使用嚴格使用;會產生錯誤,您的解決方案不會顯示。 – ikegami

+0

@ikegami:這是針對查找DBI錯誤的調試代碼。堅持認爲任何錯誤處理程序都必須包含所有內容,這並不意味着必須在每行代碼中調試'print'語句。 – Borodin

1

檢查錯誤日誌。您一定會發現,由於權限錯誤,SQLite無法創建4140.db。你對當前目錄做了不正確的假設。

+2

如果嘗試打開一個句柄數據庫文件不存在,那麼'DBD :: SQLite'將爲您創建一個。據我所知,避免這種情況的唯一方法是做一個單獨的'-f'檢查來確保文件已經存在。當然,完全可能的是CGI目錄不可寫入,因此創建失敗。 – Borodin

+0

已更新。但是你錯過了這一點。 '4140.db'通常表示CGI腳本中的'/ 4140.db'。 – ikegami

1

喲應該指定數據庫文件的完整路徑,以避免這種問題。試試這個(如果你的數據庫與你的腳本處於同一路徑):

use FindBin '$Bin'; 

my $dbfile = "$Bin/4140.db"; 
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","",{RaiseError => 1},) or die $DBI::errstr; 

#... 
+0

'$ RealBin'比'$ Bin'要好,因爲它處理符號鏈接。 '$ RealBin'已經被計算出來了,所以它不需要花費額外的東西來使用它。 – ikegami

相關問題