簡體   English   中英

SQLite/PHP 只讀?

[英]SQLite/PHP read-only?

我一直在嘗試將 SQLite 與 PHP 中的 PDO 包裝器一起使用,但效果好壞參半。 我可以很好地從數據庫中讀取,但是當我在瀏覽器中查看頁面時,我的更新都沒有提交到數據庫中。 奇怪的是,從我的 shell 運行腳本確實會更新數據庫。 我懷疑文件權限是罪魁禍首,但即使數據庫提供完全訪問權限(chmod 777),問題仍然存在。 我應該嘗試更改文件所有者嗎? 如果是這樣,該怎么辦?

順便說一句,我的機器是標准的 Mac OS X Leopard 安裝並激活了 PHP。

@湯姆馬丁

感謝你的回復。 我剛剛運行了您的代碼,看起來 PHP 以用戶 _www 運行。 然后我嘗試將數據庫由_www擁有,但這也不起作用。

我還應該注意 PDO 的 errorInfo function 並不表示發生了錯誤。 這可能是 PDO 以某種方式打開數據庫以進行只讀的設置嗎? 我聽說 SQLite 對整個文件執行寫鎖定。 數據庫是否有可能被阻止寫入的其他東西鎖定?

我決定包含有問題的代碼。 這或多或少是格蘭特腳本到 PHP 的一個端口。 到目前為止,它只是問題部分:

<?php

$db = new PDO('sqlite:test.db');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://stackoverflow.com/users/658/kyle");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIE, "shhsecret=1293706652");
$page = curl_exec($ch);

preg_match('/summarycount">.*?([,\d]+)<\/div>.*?Reputation/s', $page, $rep);
$rep = preg_replace("/,/", "", $rep[1]);

preg_match('/iv class="summarycount".{10,60} (\d+)<\/d.{10,140}Badges/s', $page, $badge);
$badge = $badge[1];

$qreg = '/question-summary narrow.*?vote-count-post"><strong.*?>(-?\d*).*?\/questions\/(\d*).*?>(.*?)<\/a>/s';
preg_match_all($qreg, $page, $questions, PREG_SET_ORDER);

$areg = '/(answer-summary"><a href="\/questions\/(\d*).*?votes.*?>(-?\d+).*?href.*?>(.*?)<.a)/s';
preg_match_all($areg, $page, $answers, PREG_SET_ORDER);

echo "<h3>Questions:</h3>\n";
echo "<table cellpadding=\"3\">\n";

foreach ($questions as $q)
{
    $query = 'SELECT count(id), votes FROM Questions WHERE id = '.$q[2].' AND type=0;';
    $dbitem = $db->query($query)->fetch(PDO::FETCH_ASSOC);
    if ($dbitem['count(id)'] > 0)
    {
        $lastQ = $q[1] - $dbitem['votes'];
        if ($lastQ == 0)
        {
            $lastQ = "";
        }
        $query = "UPDATE Questions SET votes = '$q[1]' WHERE id = '$q[2]'";
        $db->exec($query);
    }
    else
    {
        $query = "INSERT INTO Questions VALUES('$q[3]', '$q[1]', 0, '$q[2]')";
        echo "$query\n";
        $db->exec($query);
        $lastQ = "(NEW)";
    }
    echo "<tr><td>$lastQ</td><td align=\"right\">$q[1]</td><td>$q[3]</td></tr>\n";
}

echo "</table>";

?>

Kyle,為了使 PDO/Sqlite 工作,您需要對數據庫所在目錄的寫入權限。

另外,我看到您在循環中執行多項選擇。 如果您正在構建小型而不是重載的東西,這可能沒問題。 否則,我建議構建返回多行並在單獨的循環中處理它們的單個查詢。

我在PHP 手冊“存放數據庫文件的文件夾必須是可寫的”中找到了答案。

對於那些在 OS X 上遇到 SQLite 只讀問題的人:

1)確定Apache httpd用戶和用戶所屬的組:

grep "^User" /private/etc/apache2/httpd.conf
組_www

2) 在/Library/WebServer/Documents中為您的數據庫創建一個子目錄,並將組更改為 httpd 的組:

sudo chgrp _www /Library/WebServer/Documents/db

一個不太安全的選項是在/Library/WebServer/Documents上打開權限:

sudo chmod a+w /Library/WebServer/Documents

我認為 PHP 通常以用戶“nodody”的身份運行。 雖然不確定在Mac上。 如果 Mac 有 whoami 你可以試試echo exec('whoami'); 找出答案。

@Tom 取決於主機的設置方式,如果服務器將 PHP 作為 Apache 模塊運行,那么它很可能是“無人”(通常是任何用戶 ZB6EFD606D118D0F62066E31419FF04 設置)。 但是,如果 PHP 設置為 cgi(例如 fast-cgi)並且服務器運行 SuExec,則 php 以擁有文件的同一用戶身份運行。

無論哪種方式,包含數據庫的文件夾都必須可由腳本寫入,要么是同一用戶,要么將寫入權限設置為 php 用戶。

@Michal 除此之外,可以使用 beginTransaction(); 執行所有需要的操作然后 commit(); 去實際提交它們。

好吧,我現在遇到了同樣的問題,並且錯誤地解決了這個問題:只需將 SQL 指令的每個插入片段都放在它所在的try...catch塊中。 它使您以正確的方式做事,否則將無法正常工作。 好吧,它現在可以工作了。 祝其他有這個問題的人好運(因為我自己使用這個線程來嘗試解決我的問題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM