Pergunta

Tenho tentado usar SQLite com o wrapper PDO em PHP com sucesso misto.Posso ler bem o banco de dados, mas nenhuma das minhas atualizações está sendo confirmada no banco de dados quando visualizo a página no navegador.Curiosamente, executar o script no meu shell atualiza o banco de dados.Suspeitei que as permissões de arquivo fossem as culpadas, mas mesmo com o banco de dados fornecendo acesso total (chmod 777), o problema persiste.Devo tentar alterar o proprietário do arquivo?Se sim, o que fazer?

A propósito, minha máquina é a instalação padrão do Mac OS X Leopard com PHP ativado.

@Tom Martin

Obrigado por sua resposta.Acabei de executar seu código e parece que o PHP é executado como usuário _www.Tentei então alterar o banco de dados para pertencer a _www, mas também não funcionou.

Devo também observar que a função errorInfo do PDO não indica que ocorreu um erro.Isso poderia ser uma configuração com o PDO abrindo de alguma forma o banco de dados para somente leitura?Ouvi dizer que o SQLite executa bloqueios de gravação em todo o arquivo.É possível que o banco de dados esteja bloqueado por alguma outra coisa que impeça a gravação?

Decidi incluir o código em questão.Este será mais ou menos um porto de Roteiro de Grant para PHP.Até agora é apenas a seção de perguntas:

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

?>
Foi útil?

Solução

Kyle, para que o PDO/Sqlite funcione você precisa de permissão de gravação no diretório onde seu banco de dados reside.

Além disso, vejo que você executa várias seleções em loop.Isso pode ser bom se você estiver construindo algo pequeno e não muito carregado.Caso contrário, sugiro criar uma consulta única que retorne várias linhas e as processe em um loop separado.

Outras dicas

Encontrei a resposta no Manual PHP "A pasta que contém o arquivo do banco de dados deve ser gravável."

Acho que o PHP normalmente é executado como o usuário "nodody".Não tenho certeza sobre o Mac.Se o Mac tiver whoami, você poderia tentar echo exec('whoami'); descobrir.

Para aqueles que encontraram problemas somente leitura com SQLite no OS X:

1) Determine o Apache httpd usuário e grupo ao qual o usuário pertence:

grep "^User" /private/etc/apache2/httpd.conf
grupos _www

2) Crie um subdiretório em /Biblioteca/WebServer/Documentos para seu(s) banco(s) de dados e altere o grupo para o grupo do httpd:

sudo chgrp _www /Library/WebServer/Documents/db

Uma opção menos segura é abrir permissões em /Biblioteca/WebServer/Documentos:

sudo chmod a+w /Library/WebServer/Documents

@TOM depende de como a hospedagem é configurada, se o servidor executar o PHP como um módulo Apache, é provável que seja 'ninguém' (geralmente qualquer que seja o usuário do Usuário Apache é configurado como).Mas se o PHP estiver configurado como cgi (como fast-cgi) e o servidor executar o SuExec, o php será executado como o mesmo usuário proprietário dos arquivos.

De qualquer forma, a pasta que conterá o banco de dados deve ser gravável pelo script, seja por ser o mesmo usuário, ou por ter permissão de gravação definida para o usuário php.

@Michal isso de lado, pode -se usar o BeginTransaction ();execute todas as ações necessárias e então comit();para realmente cometê-los.

Bem, eu tive o mesmo problema agora e descobri por engano:basta colocar cada peça de inserção da instrução SQL dentro de um try...catch bloquear que vai.Faz você fazer do jeito certo, caso contrário não funciona.Bem, funciona agora.Boa sorte para qualquer pessoa com esse problema (pois eu mesmo usei esse tópico para tentar resolver meu problema).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top