Question

J'ai essayé d'utiliser SQLite avec le wrapper PDO en PHP avec un succès mitigé.Je peux bien lire dans la base de données, mais aucune de mes mises à jour n'est validée dans la base de données lorsque j'affiche la page dans le navigateur.Curieusement, l'exécution du script depuis mon shell met à jour la base de données.Je soupçonnais les autorisations de fichiers d'être responsables, mais même avec la base de données fournissant un accès complet (chmod 777), le problème persiste.Dois-je essayer de changer le propriétaire du fichier ?Si oui, que faire ?

À propos, ma machine est l'installation standard de Mac OS X Leopard avec PHP activé.

@Tom Martin

Merci pour votre réponse.Je viens d'exécuter votre code et il semble que PHP s'exécute en tant qu'utilisateur _www.J'ai ensuite essayé de faire en sorte que la base de données appartienne à _www, mais cela n'a pas fonctionné non plus.

Je dois également noter que la fonction errorInfo de PDO n'indique pas qu'une erreur s'est produite.Serait-ce un paramètre avec PDO ouvrant d'une manière ou d'une autre la base de données en lecture seule ?J'ai entendu dire que SQLite effectue des verrous en écriture sur l'ensemble du fichier.Est-il possible que la base de données soit verrouillée par quelque chose d'autre empêchant l'écriture ?

J'ai décidé d'inclure le code en question.Cela va être plus ou moins un port de Le scénario de Grant en PHP.Pour l'instant, il ne s'agit que de la section Questions :

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

?>
Était-ce utile?

La solution

Kyle, pour que PDO/Sqlite fonctionne, vous devez disposer d'une autorisation d'écriture dans le répertoire où réside votre base de données.

De plus, je vois que vous effectuez plusieurs sélections en boucle.Cela peut convenir si vous construisez quelque chose de petit et peu chargé.Sinon, je suggérerais de créer une seule requête qui renvoie plusieurs lignes et de les traiter dans une boucle séparée.

Autres conseils

J'ai trouvé la réponse sur Manuel PHP "Le dossier qui héberge le fichier de base de données doit être accessible en écriture."

Je pense que PHP fonctionne généralement en tant qu'utilisateur "nodody".Je ne suis pas sûr de ce qui se passe sur Mac.Si Mac a whoami, tu peux essayer echo exec('whoami'); découvrir.

Pour ceux qui ont rencontré des problèmes de lecture seule avec SQLite sous OS X :

1) Déterminez l'Apache httpd utilisateur et groupe auquel l'utilisateur appartient :

grep "^Utilisateur" /private/etc/apache2/httpd.conf
groupes _www

2) Créez un sous-répertoire dans /Bibliothèque/Serveur Web/Documents pour votre (vos) base de données et remplacez le groupe par le groupe httpd :

sudo chgrp _www /Bibliothèque/WebServer/Documents/db

Une option moins sécurisée consiste à ouvrir les autorisations sur /Bibliothèque/Serveur Web/Documents:

sudo chmod a+w /Bibliothèque/WebServer/Documents

@Tom dépend de la façon dont l'hébergement est configuré, si le serveur exécute PHP en tant que module Apache, il est probable qu'il soit `` personne '' (généralement tout ce que l'utilisateur est configuré comme).Mais si PHP est configuré en tant que cgi (comme fast-cgi) et que le serveur exécute SuExec, alors php s'exécute en tant que même utilisateur propriétaire des fichiers.

Dans tous les cas, le dossier qui contiendra la base de données doit être accessible en écriture par le script, soit en étant le même utilisateur, soit en ayant l'autorisation d'écriture définie sur l'utilisateur php.

@Michal qu'à part, on pourrait utiliser beginTransaction ();effectuez toutes les actions nécessaires puis comit();pour les commettre réellement.

Eh bien, j'ai eu le même problème maintenant et je l'ai compris par erreur :il suffit de mettre chaque morceau d'instruction SQL à insérer dans un try...catch bloquez que ça aille.Cela vous oblige à le faire correctement, sinon cela ne fonctionne pas.Eh bien, ça marche maintenant.Bonne chance à tous ceux qui ont ce problème (car j'ai moi-même utilisé ce fil pour essayer de résoudre mon problème).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top