Domanda

Ho provato a utilizzare SQLite con il wrapper PDO in PHP con alterne fortune.Riesco a leggere bene dal database, ma nessuno dei miei aggiornamenti viene inserito nel database quando visualizzo la pagina nel browser.Curiosamente, l'esecuzione dello script dalla mia shell aggiorna il database.Sospettavo che il colpevole fossero i permessi dei file, ma anche con il database che fornisce l'accesso completo (chmod 777) il problema persiste.Dovrei provare a cambiare il proprietario del file?Se sì, cosa fare?

A proposito, la mia macchina è l'installazione standard di Mac OS X Leopard con PHP attivato.

@Tom Martin

Grazie per la risposta.Ho appena eseguito il tuo codice e sembra che PHP venga eseguito come utente _www.Ho quindi provato a far sì che il database fosse di proprietà di _www, ma neanche questo ha funzionato.

Dovrei anche notare che la funzione errorInfo di PDO non indica che si è verificato un errore.Potrebbe trattarsi di un'impostazione con PDO che in qualche modo apre il database in sola lettura?Ho sentito che SQLite esegue blocchi di scrittura sull'intero file.È possibile che il database sia bloccato da qualcos'altro che impedisce la scrittura?

Ho deciso di includere il codice in questione.Questo sarà più o meno un porto di La sceneggiatura di Grant a PHP.Per ora è solo la sezione Domande:

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

?>
È stato utile?

Soluzione

Kyle, affinché PDO/Sqlite funzioni è necessaria l'autorizzazione di scrittura nella directory in cui risiede il database.

Inoltre, vedo che esegui più selezioni in loop.Questo potrebbe andare bene se stai costruendo qualcosa di piccolo e non pesante.Altrimenti suggerirei di creare una singola query che restituisca più righe e di elaborarle in un ciclo separato.

Altri suggerimenti

Ho trovato la risposta su Manuale PHP "La cartella che contiene il file del database deve essere scrivibile."

Penso che PHP venga comunemente eseguito come utente "nodody".Non sono sicuro però su Mac.Se il Mac ha whoami potresti provare echo exec('whoami'); per scoprirlo.

Per coloro che hanno riscontrato problemi di sola lettura con SQLite su OS X:

1) Determinare l'Apache httpd utente e gruppo a cui appartiene l'utente:

grep "^Utente" /private/etc/apache2/httpd.conf
gruppi _www

2) Crea una sottodirectory in /Libreria/WebServer/Documenti per i tuoi database e cambia il gruppo nel gruppo httpd:

sudo chgrp _www /Library/WebServer/Documents/db

Un'opzione meno sicura è aprire le autorizzazioni su /Libreria/WebServer/Documenti:

sudo chmod a+w /Libreria/WebServer/Documents

@Tom dipende da come viene configurato l'hosting, se il server esegue PHP come modulo Apache, è probabile che sia "nessuno" (di solito qualunque cosa l'utente Apache sia impostata).Ma se PHP è configurato come cgi (come fast-cgi) e il server esegue SuExec, php verrà eseguito come lo stesso utente proprietario dei file.

In ogni caso, la cartella che conterrà il database deve essere scrivibile dallo script, sia essendo lo stesso utente, sia avendo il permesso di scrittura impostato sull'utente php.

@Michal a parte, si potrebbe usare BeginTransaction ();eseguire tutte le azioni necessarie quindi comit();commetterli effettivamente.

Bene, ho avuto lo stesso problema ora e l'ho capito per errore:basta inserire ogni pezzo di istruzione SQL all'interno di un file try...catch blocca che vada.Ti fa fare le cose nel modo giusto altrimenti non funziona.Bene, ora funziona.Buona fortuna a chiunque altro abbia questo problema (poiché ho usato questo thread io stesso per cercare di risolvere il mio problema).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top