9

私はPHPのPDOラッパーでSQLiteを使用しようとしましたが、成功はまちまちでした。データベースからは正常に読み取ることができますが、ブラウザでページを表示すると、更新がデータベースにコミットされません。興味深いことに、シェルからスクリプトを実行すると、データベースが更新されます。ファイルのアクセス許可が原因ではないかと疑っていましたが、データベースがフル アクセス (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>";

?>
4

6 に答える 6

12

Kyle さん、PDO/Sqlite が機能するには、データベースが存在するディレクトリへの書き込み権限が必要です。

また、ループで複数の選択を実行しているようです。これは、小さくて負荷の少ないものを構築している場合は問題ありません。それ以外の場合は、複数の行を返す単一のクエリを作成し、それらを別のループで処理することをお勧めします。

于 2008-09-14T10:04:25.077 に答える
2

PHP のマニュアルで「データベース ファイルを格納するフォルダーは書き込み可能でなければならない」という回答を見つけました。

于 2010-11-25T19:14:58.197 に答える
1

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

于 2010-09-12T15:11:55.647 に答える
1

PHP は通常、ユーザー「nodody」として実行されると思います。ただし、Macについてはわかりません。Mac に whoami がある場合はecho exec('whoami');、調べてみてください。

于 2008-09-14T03:30:45.540 に答える
0

@Tomホスティングの設定方法によって異なりますが、サーバーがPHPをApacheモジュールとして実行している場合は、「nobody」(通常はユーザーapacheが設定されているもの)である可能性があります。ただし、PHPがcgi(fast-cgiなど)としてセットアップされ、サーバーがSuExecを実行している場合、phpはファイルを所有しているのと同じユーザーとして実行されます。

いずれにせよ、データベースを含むフォルダーは、同じユーザーであるか、phpユーザーに書き込み権限を設定することにより、スクリプトによって書き込み可能である必要があります。

@Michalそれはさておき、beginTransaction();を使用できます。必要なすべてのアクションを実行してからcomit(); 実際にそれらをcomitします。

于 2009-08-29T19:58:26.093 に答える
0

try...catchさて、私は今同じ問題を抱えていて、間違いでそれを理解しました.SQL命令のすべての挿入部分をブロック内に置くだけです. そうしないとうまくいきません。さて、それは今動作します。この問題を抱えている他の人には幸運を祈ります(私はこのスレッドを使用して問題を解決しようとしました)。

于 2010-08-12T17:27:51.183 に答える