Вопрос

Я пытался использовать 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>";

?>
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

grep "^User" /private/etc/apache2/httpd.conf
группы _wwww

2) Создайте подкаталог в /Библиотека/Веб-сервер/Документы для ваших баз данных и измените группу на группу httpd:

sudo chgrp _www /Библиотека/Веб-сервер/Документы/База данных

Менее безопасным вариантом является открытие разрешений на /Библиотека/Веб-сервер/Документы:

sudo chmod a+ w /Библиотека/Веб-сервер/Документы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top