2008-09-14 14 views
9

私はPHPでPDOラッパーとSQLiteを混在させて使用しようとしています。私はデータベースから正常に読み取ることができますが、ブラウザでページを表示すると、データベースにコミットされている更新はありません。不思議なことに、シェルからスクリプトを実行すると、データベースが更新されます。私はファイルパーミッションを原因と考えていましたが、フルアクセス(chmod 777)を提供しているデータベースでも問題は解決しません。ファイルの所有者を変更する必要がありますか?もしそうなら、何に?SQLite/PHPは読み取り専用ですか?

ところで、私のマシンは、標準のMac OS X LeopardでPHPを有効にしてインストールします。

@トムマーティン

ありがとうございます。私はちょうどあなたのコードを実行し、PHPがユーザー_wwwとして実行されるように見えます。私はその後、_wwwによって所有されるデータベースをchowningしようとしましたが、それもうまくいきませんでした。

PDOのerrorInfo関数は、エラーが発生したことを示していないことにも注意してください。これは、PDOが読み取り専用のデータベースを開いているような設定ですか? SQLiteがファイル全体の書き込みロックを実行すると聞いたことがあります。書き込みを妨げる何かによってデータベースがロックされている可能性はありますか?

私は問題のコードを含めることに決めました。これは多かれ少なかれPHPのGrant's scriptのポートになるでしょう。これまでのところ、質問セクションです:

<?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>"; 

?> 
+0

申し訳ありませんが、もう助けません。あなたがシェルからそれを稼働させることができるなら、まだパーミッションの問題のように聞こえるかもしれません。とにかくありがとう。 –

+0

私にはパーミッションのように思えますが、ここでどのようにそれが可能かはわかりません。 –

+0

'$ db = new PDO( 'sqlite:test.db');'をフルパスに変更しようとしましたか? Like .. '$ db = new PDO( 'sqlite:/tmp/test.db');'? – dbr

答えて

10

カイル、PDO/Sqliteを動作させるには、データベースが存在するディレクトリへの書き込み権限が必要です。

また、ループ内で複数の選択を実行することがわかります。あなたが何か小さいものを積み重ねていて重いものを積んでいないのなら、これはいいかもしれないさもなければ、私は複数の行を返し、別のループでそれらを処理する単一のクエリを構築することをお勧めします。

+0

あなたはそれを修正しました!ありがとうございました!このスクリプトは、このようにしてSQL文を実行するGrantのスクリプトの行単位のコピーです。私はO(1)SELECTを実行し、UPDATESをキューに入れて最後に実行することを検討しています。 –

+0

私はちょうど私の感謝を表明したいと思う、私は答えであることを推測したことがないだろう。私はSQLite3(PDOなし)を使用しており、これは私を助けてくれました。 –

1

私はPHPが一般的にユーザー "nodody"として動作すると思います。しかしMacについてはわからない。 Macにうまいがある場合は、echo exec('whoami');を調べてみてください。

0

@Tom サーバーがApacheモジュールとしてPHPを実行している場合、そのサーバーは「nobody」(通常はユーザーのApacheがどのように設定されていても)です。しかし、PHPがcgi(例えば、fast-cgi)としてセットアップされ、サーバーがSuExecを実行すると、phpはファイルを所有する同じユーザーとして実行されます。

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

@Michal これ以外にも、beginTransaction()を使用できます。必要なすべてのアクションを実行し、comit();実際にそれらを迎えるために。

+0

PS:OSXに付属している「標準的な」Apache/PHPインストールを思い出して、10.5まで(デスクトップではなく、サーバーではない)はPHP4のみです。PHP5の利点を望むなら、PHPを再コンパイルする必要がありますApacheを再コンパイルして、Apache + PHP + MySQLセットアップで一般的に提供される機能の多くを取得します)。 –

0

まあ、私は今同じ問題があって間違いで分かりました。つまり、挿入するSQL命令のすべてを、それが行くブロックtry...catchに入れてください。それは正しい方法でそれ以外の場合は動作しません。さて、それは今動作します。この問題を抱えている誰にとっても(私の問題を解決しようとすると、このスレッドを自分で使ったので)幸いです。 OS X上のSQLiteと読み取り専用の問題が発生している人のために

1

1)ユーザーが所属しているApacheのHTTPDユーザーおよびグループを決定するには:

はgrep "^ユーザー"/private/etc/apache2/httpd。
グループは

2を_www CONF)■(データベースの/ライブラリ/ WebServer /書類にサブディレクトリを作成)し、HTTPDのグループにグループを変更します。

にsudo chgrpコマンド_www /ライブラリ/ WebServer /ドキュメント/ DB

安全性の低いオプションは、/ライブラリ/ WebServer /書類のパーミッションを開くことです:

はsudo chmodコマンドのA + W /ライブラリ/ WebServer /書類

1

私はPHP manual上で答えを見つけ、 "データベースファイルが書き込み可能でなければなりません収容するフォルダ。"

関連する問題