SQLite / PHP只读?

时间:2020-03-05 18:52:54  来源:igfitidea点击:

我一直在尝试将SQLite与PHP中的PDO包装器一起使用,但取得了成功。我可以从数据库中正常读取,但是当我在浏览器中查看页面时,没有任何更新提交到数据库。奇怪的是,从我的shell运行脚本确实会更新数据库。我怀疑文件权限是罪魁祸首,但是即使数据库提供了完全访问权限(chmod 777),问题仍然存在。我应该尝试更改文件所有者吗?如果是这样,该怎么办?

顺便说一句,我的机器是标准的Mac OS X Leopard安装,并激活了PHP。

@汤姆·马丁

感谢你的回复。我只运行了代码,看起来PHP以用户_www的身份运行。然后,我尝试将数据库归于_www所有,但这也不起作用。

我还要注意,PDO的errorInfo函数并不表示发生了错误。这可能是PDO的设置,以某种方式打开了只读数据库吗?我听说SQLite对整个文件执行写锁定。数据库是否可能被阻止写入的其他方式锁定?

我决定包括相关代码。这将或者多或者少地将Grant的脚本移植到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>";

?>

解决方案

回答

我认为PHP通常以用户" nodody"的身份运行。不确定在Mac上。如果Mac有whoami,我们可以尝试使用echo exec('whoami');`来查找。

回答

凯尔(Kyle),为了使PDO / Sqlite工作,我们需要对数据库所在目录具有写许可权。

另外,我看到我们在循环中执行多个选择。如果我们要构建的东西很小而不是很重,那可能没问题。否则,我建议构建单个查询以返回多个行并在单独的循环中对其进行处理。

回答

汤姆
取决于托管的设置方式,如果服务器将PHP作为Apache模块运行,则它很可能是"没人"(通常将用户apache设置为)。但是,如果将PHP设置为cgi(例如fast-cgi)并且服务器运行SuExec,则php将以拥有文件的同一用户身份运行。

无论哪种方式,包含该数据库的文件夹都必须是脚本可写的,或者是同一用户,或者是将写权限设置为php用户。

@米哈尔
除此之外,可以使用beginTransaction();。执行所有需要的操作,然后comit();真正承认他们。

回答

好吧,我现在遇到了同样的问题,并通过一个错误解决了这个问题:只需将每条插入的SQL指令放在一个" try ... catch"块中即可。它使我们以正确的方式进行操作,否则将无法正常工作。好吧,现在可以了。对于遇到此问题的其他人,祝我们好运(因为我自己使用此线程来尝试解决我的问题)。

回答

对于那些在OS X上遇到SQLite只读问题的人:

1)确定Apache httpd用户和该用户所属的组:

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

   groups _www

2)在/ Library / WebServer / Documents中为数据库创建一个子目录,并将该组更改为httpd的组:

sudo chgrp _www /Library/WebServer/Documents/db

一个不太安全的选项是打开/ Library / WebServer / Documents上的权限:

sudo chmod a+w /Library/WebServer/Documents

回答

我在PHP手册"包含数据库文件的文件夹必须是可写的"中找到了答案。