SQLite / PHP только для чтения? - PullRequest
9 голосов
/ 14 сентября 2008

Я пытался использовать SQLite с оболочкой PDO в PHP с переменным успехом. Я могу читать из базы данных нормально, но ни одно из моих обновлений не фиксируется в базе данных при просмотре страницы в браузере. Любопытно, что запуск сценария из моей оболочки действительно обновляет базу данных. Я подозревал, что причиной является разрешение на доступ к файлам, но даже при наличии полной базы данных (chmod 777) проблема сохраняется. Стоит ли менять владельца файла? Если да, то что?

Кстати, на моей машине установлена ​​стандартная установка Mac OS X Leopard с активированным PHP.

@ Том Мартин

Спасибо за ваш ответ. Я только что запустил ваш код, и похоже, что PHP работает как пользователь _www. Затем я попытался уничтожить базу данных, принадлежащую _www, но это тоже не сработало.

Следует также отметить, что функция errorInfo в PDO не указывает на наличие ошибки. Может ли это быть настройка с PDO, как-то открывая базу данных только для чтения? Я слышал, что SQLite выполняет блокировки записи для всего файла. Возможно ли, что база данных заблокирована чем-то другим, препятствующим записи?

Я решил включить рассматриваемый код. Это будет более или менее порт скрипта Гранта для 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>";

?>

Ответы [ 6 ]

11 голосов
/ 14 сентября 2008

Кайл, для работы PDO / Sqlite необходимо разрешение на запись в каталог, в котором находится ваша база данных.

Кроме того, я вижу, что вы выполняете несколько циклов выбора. Это может быть хорошо, если вы строите что-то маленькое и не тяжелое. В противном случае я бы предложил создать один запрос, который возвращает несколько строк, и обрабатывать их в отдельном цикле.

2 голосов
/ 25 ноября 2010

Я нашел ответ в руководстве по PHP"Папка, в которой находится файл базы данных, должна быть доступна для записи."

1 голос
/ 12 сентября 2010

Для тех, кто столкнулся с проблемами только для чтения с SQLite в OS X:

1) Определите пользователя Apache httpd и группу, к которой принадлежит пользователь:

grep "^ Пользователь" /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

1 голос
/ 14 сентября 2008

Я думаю, что PHP обычно запускается как пользователь "nodody". Не уверен насчет Mac, хотя. Если у Mac есть whoami, вы можете попробовать echo exec('whoami');, чтобы узнать.

0 голосов
/ 12 августа 2010

Что ж, у меня возникла та же проблема, и я понял ее по ошибке: просто поместите каждый вставляемый фрагмент инструкции SQL внутри блока try...catch, в который она входит. Это заставляет вас делать это правильно, иначе это не сработает. Ну, это работает сейчас. Удачи всем, кто столкнулся с этой проблемой (поскольку я сам использовал эту ветку, чтобы попытаться решить свою проблему).

0 голосов
/ 29 августа 2009

@ Том Зависит от того, как настроен хостинг. Если сервер запускает PHP как модуль Apache, то вполне вероятно, что это «никто» (обычно независимо от того, как настроен пользователь apache). Но если PHP настроен как cgi (например, fast-cgi) и сервер запускает SuExec, тогда php запускается как тот же пользователь, которому принадлежат файлы.

В любом случае сценарий, в котором будет содержаться база данных, должен быть доступен для записи либо тем же пользователем, либо с помощью разрешения на запись, установленного для пользователя php.

@ Михал Помимо этого, можно использовать beginTransaction (); выполнить все необходимые действия, затем comit (); на самом деле доставить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...