Jump to content
Fórum Script Brasil
  • 0

Acesso único a classe


Bicicleta
 Share

Question

E ae galera, beleza?

Seguinte... Tenho uma classe que manipula um arquivo .XML e quando existem duas alterações simultâneas no mesmo, dá um erro... Por exemplo:

- Cliente 1 manda abrir o arquivo;

- Cliente 2 manda abrir o arquivo;

- Cliente 1 altera o arquivo;

- Cliente 1 salva e fecha o arquivo;

- Cliente 2 altera o arquivo;

- Cliente 2 "tenta" salvar o arquivo (ERRO)

O erro que dá é porque o "cliente 2" abriu o arquivo junto com o "cliente 1", quando o "cliente 1" salvou o arquivo ainda era o mesmo que ele abriu, porém o "cliente 2" altera o objeto e manda salvar um arquivo que já não é mais o mesmo que ele abriu...

Esse erro na verdade não atrapalha muito, porque se der erro, o cliente recebe a mensagem de que não foi possível alterar o arquivo e ele tenta novamente em seguida e consegue... Porém isso está me incomodando, andei pensando em uma alternativa e cheguei a algo:

1) Cliente 1 abre o arquivo;

2) Cliente 2 manda abrir o arquivo, porém o Cliente 1 já está conectado, então aguarda (sleep).

3) Cliente 1 altera o arquivo;

2) Cliente 2 manda abrir o arquivo, porém o Cliente 1 ainda está conectado, então aguarda (sleep).

4) Clietne 1 salva e fecha o arquivo;

5) Cliente 2 manda abrir o arquivo (o 1 já não está mais aqui, então pode abrir);

6) Cliente 2 altera o arquivo;

7) Cliente 2 salva e fecha o arquivo;

Algo assim, ou seja, pra instanciar uma classe, somente se não existir ninguém com ela já instanciada (conectado), fiz alguns testes com arquivos, sessões, (BD não é possível) e não consegui nada... Fiz e refiz a lógica e código e na verdade o sleep dá uma zuada no negócio...

Bom, pra resumir, alguém tem alguma idéia o que eu poderia implementar para conseguir que somente 1 pessoa use a classe por vez?

PS.: Como falei, isso não interfere muito, mais tá me deixando meio cabreiro, porque as vezes tem vários processos a serem feitos antes de gravar no XML e não que seja um problema refazer eles, mais acho que uma solução mais elegante pra isso seja muito mais "elegante" (rsrsrsrsrs)

Valeu!

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Caro Bicicleta

Eu desconheço a opção de bloquear acesso a classe em PHP. Porém, você pode utilizar a função flock do PHP para "travar" o arquivo enquanto estiver manipulando ele.

Neste caso, sempre antes de abrir o arquivo você deve verificar se o mesmo não está bloquaedo.

Edited by AndersonFachini
Link to comment
Share on other sites

  • 0

Bicicleta,

Já passei por uma situação parecida com a sua. Meu problema era garantir que somente um usuário (por vez) executaria algumas operações.

Vou colar o fonte da minha classe. No meu caso, implementei utilizando interfaces e classes abstratas.

Então simplifiquei o código, segue abaixo:

Faça um teste

class A {
    
    const STATUS_BLOQUEADO = 'BLOQUEADO';
    
    const STATUS_DESBLOQUEADO = 'DESBLOQUEADO';
    
    const STATUS_FILE = 'c:\StatusClasseA.txt';
    
    /**
     * Armazena o status 
     * @var string
     */
    private $_status;
    
    /**
     * Realiza uma leitura do arquivo
     * @return string
     */
    private function _fileRead() {
        return file_get_contents(self::STATUS_FILE);
    }
    
    /**
     * Escreve no arquivo
     * @param string $content
     */
    private function _fileWrite($content) {
        file_put_contents(self::STATUS_FILE,$content);
    }
    
    /**
     * Recupera o status 
     * @return void
     */
    private function _processStatus() {
        $this->_status = $this->_fileRead();
    }
    
    
    /**
     * Construtor
     * @uses A::_processStatus() Para recuperar o status
     * @uses A::_fileWrite() Para registrar o status de bloqueado
     * @return void
     */
    public function __construct() 
    {
        $this->_processStatus();
        
        if($this->_status == self::STATUS_BLOQUEADO){
            echo "A classe está sendo utilizada";
            exit();
        }

        echo 'Setando o arquivo para: ' . self::STATUS_BLOQUEADO . '<br>';
        $this->_fileWrite(self::STATUS_BLOQUEADO);
    }
    
    /**
     * Realiza as operações 
     * @return void
     */
    public function operacoes() 
    {
        echo 'Operações a serem realizadas no arquivo<br>';
        sleep(10);
        $this->_desbloquear();
    }
    
    /**
     * Registrar o status de desbloqueado
     * @return void
     */
    private function _desbloquear() 
    {
        echo 'setando o arquivo para:' . self::STATUS_DESBLOQUEADO . '<br>';
        
        /* Ao terminar de utilizar a classe, seta o status para desbloqueado */
        $this->_fileWrite(self::STATUS_DESBLOQUEADO);
    }
}

$a = new A;
$a->operacoes();

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Forum Statistics

    • Total Topics
      150.2k
    • Total Posts
      647.4k
×
×
  • Create New...