2008-09-14 16 views
9

Próbowałem użyć SQLite z otoką PDO w PHP z mieszanym sukcesem. Mogę odczytać z bazy danych dobrze, ale żadna z moich aktualizacji nie jest zatwierdzana do bazy danych, gdy przeglądam stronę w przeglądarce. Co ciekawe, uruchomienie skryptu z mojej powłoki powoduje aktualizację bazy danych. Podejrzewałem, że uprawnienie do pliku jest sprawcą, ale nawet z bazą zapewniającą pełny dostęp (chmod 777) problem nadal występuje. Czy powinienem spróbować zmienić właściciela pliku? Jeśli tak, to co?SQLite/PHP tylko do odczytu?

Przy okazji, mój komputer to standardowa instalacja Mac OS X Leopard z aktywowanym PHP.

@Tom Martin

Dziękuję za odpowiedź. Po prostu uruchomiłem twój kod i wygląda na to, że PHP uruchamia się jako użytkownik _www. Następnie próbowałem pomalować bazę danych na własność _www, ale to też nie działało.

Należy również zauważyć, że funkcja errorInfo PDO nie wskazuje na błąd. Czy to może być ustawienie z PDO w jakiś sposób otwierające bazę danych tylko do odczytu? Słyszałem, że SQLite wykonuje blokady zapisu w całym pliku. Czy jest możliwe, że baza danych jest zablokowana przez coś innego, co uniemożliwia zapis?

Postanowiłem uwzględnić dany kod. To będzie mniej więcej port Grant's script do PHP. Do tej pory jest to tylko sekcja Pytania:

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

Przykro mi, człowieku, nie mogę ci więcej pomóc. Wciąż brzmi to jak problem uprawnień, jeśli możesz go uruchomić z powłoki. –

+0

Dzięki i tak. Wydaje mi się, że to też jest kwestia uprawnień, ale nie rozumiem, jak to jest możliwe. –

+0

Próbowano zmienić '$ db = new PDO ('sqlite: test.db'); 'na pełną ścieżkę? Podobnie jak .. '$ db = new PDO ('sqlite: /tmp/test.db');'? – dbr

Odpowiedz

10

Kyle, aby PDO/Sqlite działały, potrzebujesz uprawnień do zapisu do katalogu, w którym znajduje się twoja baza danych.

Widzę również, że wykonujesz wiele wyborów w pętli. Może to być ok, jeśli budujesz coś małego, a nie ciężkiego. W przeciwnym razie proponuję zbudowanie pojedynczego zapytania, które zwróci wiele wierszy i przetworzy je w osobnej pętli.

+0

Naprawiłeś to! Dziękuję Ci! Skrypt był mniej więcej skrupulatną kopią skryptu Granta, który w ten sposób wykonuje swoje instrukcje SQL. Rozważam jednak wykonanie O (1) SELECT i kolejkowanie UPDATE'ów i ich wykonanie na końcu. –

+0

Chciałbym wyrazić moje podziękowania, nigdy bym nie zgadł, że to jest odpowiedź. Używam SQLite3 (bez PDO) i to mi bardzo pomogło. –

1

Myślę, że PHP zwykle działa jako użytkownik "Nodody". Nie wiem jednak na temat Maca. Jeśli Mac ma whoami, możesz spróbować dowiedzieć się, echo exec('whoami');.

0

@Tom Zależy jak hosting jest ustawiony, jeśli serwer PHP działa jako moduł Apache następnie jego prawdopodobne, że jest to „nikt” (zazwyczaj co użytkownik apache jest ustawiony jako). Ale jeśli PHP jest ustawione jako cgi (np. Fast-cgi), a serwer uruchamia SuExec, to php działa jako ten sam użytkownik, który jest właścicielem plików.

W każdym razie folder, który będzie zawierał bazę danych, musi być możliwy do zapisu przez skrypt, albo przez tego samego użytkownika, albo przez ustawienie uprawnień do zapisu dla użytkownika php.

@Michal Oprócz tego można użyć beginTransaction(); wykonaj wszystkie wymagane działania, a następnie uruchom komendę(); aby je połączyć.

+0

PS: Jak już pamiętam "standardowa" instalacja apache/php dostarczana z OSX nawet do 10.5 (desktop, nie serwer) jest tylko PHP4, to w rzeczywistości musisz przekompilować PHP, jeśli chcesz korzystać z PHP5 (i na tej notatce zrekompiluj Apache, aby uzyskać więcej funkcji, które zwykle są dostępne z instalacją Apache + PHP + MySQL). –

0

Cóż, miałem teraz ten sam problem i pomyślałem go przez pomyłkę: po prostu wstaw wszystkie wstawiane instrukcje SQL wewnątrz bloku try...catch. To sprawia, że ​​robisz to w prawidłowy sposób, inaczej nie zadziała. Cóż, teraz działa. Powodzenia dla każdego, kto ma ten problem (użyłem tego wątku, aby rozwiązać mój problem).

1

Dla tych, którzy napotkali tylko do odczytu problemy z SQLite na OS X:

1) Określić Apache httpd użytkownika i grupy do której należy użytkownik:

grep "^ Użytkownika"/private/etc/apache2/httpd.conf
grupy _www

2) Utwórz podkatalog w /Library/WebServer/Dokumenty dla bazy danych (S) i zmienić grupę do grupy kapitałowej httpd za:

sudo chgrp _www/Library/WebSerwer/Dokumenty/db

mniej bezpiecznym rozwiązaniem jest otwarcie uprawnienia /Library/WebServer/Dokumenty:

sudo chmod a + w/Library/WEBSERVER/Dokumenty

1

Znalazłem odpowiedź na PHP manual "folder, w którym mieści się plik bazy danych musi być zapisywalny."