Mensagem irrevogável php. Daemons - filas de mensagens

20.02.2024

    Ser obstinado, ser obstinado, ser obstinado, ser incompetente. (coloquial). Agir arbitrariamente, comportar-se arbitrariamente. Dicionário explicativo de Ushakov. D. N. Ushakov. 1935 1940… Dicionário Explicativo de Ushakov

    SEJA AUTO-OBRIGATÓRIO, oh, oh; imperfeito (coloquial). Aja arbitrariamente. Dicionário explicativo de Ozhegov. SI. Ozhegov, N.Yu. Shvedova. 1949 1992… Dicionário Explicativo de Ozhegov

    Nesov. nepereh. decomposição Faça como quiser, de acordo com seu capricho. Dicionário explicativo de Efraim. T. F. Efremova. 2000... Dicionário explicativo moderno da língua russa por Efremova

    Obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado, obstinado obstinado, obstinado, obstinado, ... ... Formas de palavras

    agir sem permissão- ser enganador, sim, sim... Dicionário ortográfico russo

    agir sem permissão- (Eu), estou descansando, estou tomando chá, estou tomando chá... Dicionário ortográfico da língua russa

    Sim, sim; nsv. Razg. Agir como quiser, ao seu bel-prazer, sem pedir permissão a ninguém. S. visitando. S. no trabalho. Faça suas próprias coisas em casa. ◁ Obstinação, eu; qua Sem obstinação, por favor, senão vou demitir você! ... Dicionário Enciclopédico

    agir sem permissão- ah, ah; nsv.; decomposição veja também vontade própria Agir de acordo com o próprio desejo, por capricho, sem pedir permissão a ninguém. Samovo / preguiça em festa. Samovo/preguiçoso no trabalho. Faça suas coisas em casa... Dicionário de muitas expressões

Olá a todos!

Nas edições anteriores já aprendemos como processar corretamente esses mesmos sinais recebidos. Agora chegamos perto do momento em que nosso demônio deverá aprender a se comunicar com outros programas, ou consigo mesmo, mas em cópias diferentes.

No mundo unix, há uma variedade incrível de maneiras de passar um comando ou mensagem de um daemon para um script web e vice-versa. Mas agora quero falar apenas sobre filas de mensagens - “System V IPC Messages Queues”.

Quando criança, sua mãe já deve ter lhe contado que filas podem ser encontradas tanto na implementação do System V IPC quanto na implementação do Posix. Quero abordar apenas o tópico do System V, pois ele é próximo de mim pessoalmente. E tentarei evitar o tópico posix, se possível.

Então vamos começar. As filas operam no nível de um sistema operacional “normal”, são armazenadas na memória e representam uma estrutura de dados acessível a todos os programas do sistema. Nas filas, assim como no sistema de arquivos, é possível configurar direitos de acesso e tamanho das mensagens. Normalmente, a mensagem na fila é definida para um tamanho pequeno, não superior a 8 kilobytes.

Isso conclui a parte introdutória, vamos passar à prática.

Enviando mensagens

fila-enviar.php

Aceitamos mensagens

fila-receive.php

Vamos executar o arquivo um por um primeiro fila-enviar.php e então fila-receive.php.

U% php queue-send.php envia 4 mensagens u% php queue-receive.php tipo: 1 tipo: 1, msgtype: 1, mensagem: s:15:"mensagem, tipo 1"; tipo: 1, tipo de mensagem: 1, mensagem: s:15:"mensagem, tipo 1"; tipo: 2 tipo: 2, tipo de mensagem: 2, mensagem: s:15:"mensagem, tipo 2"; tipo: 3 tipo: 3, tipo de mensagem: 3, mensagem: s:15:"mensagem, tipo 3";

Você pode ver que as mensagens foram agrupadas e 2 mensagens do primeiro tipo foram exibidas primeiro e depois todas as outras.
Se tivéssemos especificado o recebimento de mensagens do tipo 0, teríamos recebido todas as mensagens, independentemente do tipo.

While (msg_receive($queue, $i, $msgtype, 4096, $message, false, MSG_IPC_NOWAIT)) ( // ...

Além disso, aqui vale a pena observar mais uma característica da fila: se removermos a constante MSG_IPC_NOWAIT, removemos coisas desnecessárias do script e executamos o arquivo em um terminal fila-receive.php, e no outro iremos executar periodicamente o arquivo fila-enviar.php, veremos como o daemon pode usar efetivamente a fila aguardando uma tarefa dela.

fila-receber-espera.php

Na verdade, já contei para vocês todas as coisas mais interessantes sobre as filas. Existem também funções para obter estatísticas de filas, excluir e verificar a existência de uma fila.

Vamos agora tentar escrever um daemon que escute uma fila:
fila-daemon.php

3,3K

Exibir mensagens ao usuário é uma ação bastante comum que um aplicativo da web deve executar. Pode ocorrer durante o processamento de formulários, podem ser mensagens de erro, mensagens que solicitam o registro quando um usuário tenta acessar uma parte restrita do site e em muitos outros casos.

Muitas vezes, a criação e a saída de mensagens são separadas em diferentes solicitações HTTP. Via de regra, é conveniente utilizar o redirecionamento após o processamento dos formulários (para evitar problemas com os botões Voltar e Atualizar), mas ao mesmo tempo, o momento natural para a criação de uma mensagem é justamente o momento de processar os formulários e realizar as ações que acompanham isto. Por que? Imagine que o texto da mensagem deveria ser mais ou menos assim: “O número de unidades encomendadas do item ‘Mouse Pad’ foi alterado com sucesso de 7 para 12.” Após um redirecionamento, talvez para uma página completamente diferente em termos de funcionalidade, será uma dor de cabeça extra determinar o que foi feito antes.

Na maioria das vezes, as mensagens são exibidas na solicitação POST que processa o formulário - isso não é bom, as inscrições “esta página está desatualizada” arruinam a vida (quando o usuário decide tentar o botão Voltar).

Alguém usa um redirecionamento, desistindo de mensagens amigáveis.

Ao mesmo tempo, existe uma maneira simples e óbvia de tornar a vida melhor. Apesar da obviedade, por algum motivo nunca vi ninguém usá-lo - pelo menos quando olhei as fontes de outras pessoas.

Então, temos um problema - a mensagem deve “viver” em solicitações diferentes. Precisamos de um mecanismo para transferir o texto da mensagem para a página que deverá exibi-la. Você provavelmente já se lembrou das sessões.

Sim, em geral você está certo. Outros métodos, por exemplo através de uma variável global, não permitem salvar dados no caso de uso de redirecionamento (nota de Maxim Naumenko). Além disso, normalmente me certifico de que cada tela do aplicativo tenha a capacidade, junto com outras informações, de exibir mensagens que foram geradas em telas anteriores. Isso é conveniente porque não há necessidade de preparar telas separadas para exibição de mensagens e o usuário não precisa clicar novamente com o mouse. Mas, na verdade, o designer precisa pensar aqui – destacar a área em que as mensagens apareceriam.

A ideia é muito simples e pode ser implementada com algumas aulas.

A primeira coisa que vem à mente é criar uma classe Message, que representaria, de fato, uma mensagem em nosso diagrama de classes simples. A mensagem deve poder ser salva na sessão, bem como exibida na tela.

class Message ( /** * Message content. */ var $content; /** * Construtor para inicializar o texto da mensagem. * * @param content message content */ function Message($content) ( $this->content = $ content ; ) /** * Escreve uma mensagem para a sessão */ function send() ( $_SESSION["session_messages"] = $this->content; ) /** * Envia uma mensagem para a página */ function toPage () ( echo. " - " . $this->content .
"; } }

A variável $_SESSION é usada para acessar a sessão.

Observe que $_SESSION é um array, estamos usando apenas um elemento deste array com o índice ‘session_message’.

Neste caso, estamos lidando com um “array de arrays” - o que armazenamos no elemento ‘session_message’ é um array, esta é a lista de mensagens transmitidas (claro, pode haver várias delas).

Se você não conseguiu encontrar o tópico, é hora de revisar as seções do manual dedicadas a sessões e arrays.

Você pode ter uma pergunta. Por que as aulas são necessárias aqui? Seria possível sobreviver com duas funções. Mas vamos olhar mais além. Podemos precisar criar mensagens com diferentes tipos (informações, erros, avisos) e determinar os destinatários das mensagens.

Observe que no momento não é o objeto em si que é colocado na sessão, mas apenas o texto da mensagem. OOP nos permite alterar posteriormente o comportamento do método send() sem alterar o código do cliente que acessa esse método (por exemplo, no futuro podemos escrever todo o objeto Message na sessão se ela tiver muitos campos).

Vamos imaginar que faríamos isso usando funções. Provavelmente teríamos uma função message_send($txt) e também uma função message_to_page($txt). Agora precisamos adicionar a capacidade de ter comportamentos diferentes para diferentes tipos de mensagens. As chamadas de função mudam: message_send($txt, $kind), message_to_page($txt, $kind). Você terá que vasculhar todo o código da aplicação em busca de tais funções, fazendo correções.

Isso pode ser evitado antecipando a situação apresentando a mensagem como um array associativo: $msg['txt'], $msg['kind'], então haverá apenas um parâmetro nas chamadas de função. Você consegue sentir como isso está tentando se tornar uma aula?

Portanto, OOP lhe dá a oportunidade de se dar ao luxo de não pensar em tudo com antecedência.

A próxima aula - Inbox - foi projetada justamente para isso.

class Inbox ( /** * Array de mensagens recebidas. */ var $messages = array(); /** * No construtor, obtemos todas as mensagens recebidas * e as excluímos da sessão. */ function Inbox() ( if (is_array($ _SESSION["session_messages"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i< $co; $i++) { $this->mensagens = nova Mensagem($mensagens[$i]);
) ) /* limpa o array de mensagens */ $_SESSION["session_messages"] = array();< $co; $i++) { $this->) /** * Exibe o conteúdo da Caixa de entrada na página.

*/ function toPage() ( $co = sizeof($this->messages); if ($co > 0) ( echo "Mensagem do sistema:

"; ) para ($i = 0; $i

mensagens[$i]->ToPage();

) ) )

Vamos experimentar nosso sistema de mensagens.

Vamos criar um exemplo bem simples que responderá ao envio de um formulário informando o número de segundos do minuto atual.

enviar(); /* redireciona para você mesmo */ header("location:"); ) else ( $inbox = new Inbox(); $inbox->toPage(); ) ?>

Escondemos todo o trabalho com arrays e sessões dentro das classes, e o código final parece simples e bonito.
Crie um diretório em seu servidor web, crie esses três arquivos nele e experimente o script. Observe que não há problemas com os botões Voltar e Atualizar.
Agora imagine que você está criando um portal complexo, onde, via de regra, existem vários blocos nas páginas, e cada um pode conter uma aplicação separada.
Aqui encontramos duas dificuldades:

Para tentar resolver o primeiro problema, você pode criar um buffer que armazene o resultado da saída do Inbox.

Talvez ainda tenhamos várias coisas semelhantes (ao Inbox) e precisemos criar um sistema de buffer. Para não confundir de quem é a saída, provavelmente iremos nomear os buffers. Armazenaremos em algum lugar a sequência de acordo com a qual os buffers devem ser gerados - de preferência em um arquivo externo para facilitar as alterações.

Essa tentativa de solução já nos dá a ideia de utilizar XML como meio de armazenamento de dados intermediários. E usar estilos XSLT ajudará a resolver o segundo problema.

Não vou me alongar sobre o que é XML e o que é XSLT. Se você não está familiarizado com essas coisas, zvon.org é um bom lugar para começar a procurar.

A ideia é gerar não um código HTML, mas uma estrutura XML nos métodos toPage(). O documento da página será criado como uma string com código XML (servirá como “buffer”), e na última etapa do script utilizaremos uma transformação XSL.

Primeiro, vamos imaginar qual deve ser o resultado da parte principal do código.

minuto 57 segundo: 45

O que é é muito fácil de adivinhar - duas mensagens e um formulário. Observe que o script PHP só precisa preparar essa string - é muito simples. Além disso, a ordem das tags principais não é importante - Você pode colocar no início, por exemplo, pois será conveniente para o programador. Como implementá-lo. Você pode, sem alterar nada, usar buffer de saída, gerar XML em vez de código HTML e, no final, simplesmente capturar a saída em uma string. Mas então perderemos flexibilidade - por exemplo, às vezes você deseja enviar informações de depuração diretamente para a página (usando echo). Ao mesmo tempo, os desenvolvedores de PHP estão trabalhando em um módulo DOM que oferece uma maneira mais avançada de criar e passar documentos em árvore. Se quisermos implementar o DOM, teremos que redesenhar toda a aplicação, alterando a saída de strings para a criação de elementos DOM. Portanto, prefiro armazenar a representação XML dos objetos dentro dos próprios objetos, montando sequencialmente um documento XML comum. Não é tão difícil, só precisa de uma pequena modificação. Você verá que esta técnica não está estritamente ligada a uma forma específica de armazenar dados XML e isso permitirá que você faça a transição para o uso do DOM com pouco esforço. Em primeiro lugar, observe que cada um dos nossos objetos possui um método toPage(). Essa semelhança deve nos fazer pensar na introdução de uma nova classe pai comum. Deixe cada classe que pode criar partes de um documento XML para uma página herdar de uma classe que cuidará da representação XML do objeto. Vamos chamá-lo de saída.

class Outputable ( /** * contêiner XML (string). */ var $output = ""; /** * Fornece o conteúdo do contêiner e limpa o contêiner. * * @return uma string com dados XML */ function getOutput () ( $ out = $this->output; $this->output = ""; return $out; ->output .= $string . "n" ) /** * Método "Abstrato" */ function toPage( ) ( ) )

O método toPage() fica vazio - neste caso, é necessário como um indicador de como as classes “matryoshka” externas devem se comunicar com a classe interna. No entanto, poderíamos oferecer uma implementação padrão aqui se percebêssemos que existem muitos objetos que são exibidos na página da mesma maneira.

As classes Message e Inbox mudarão um pouco - agora ambas devem herdar de Outputable, e os métodos toPage() também mudarão
Mensagem.php

class Message extends Outputable ( /** * Message content. */ var $content; /** * Construtor para inicializar o texto da mensagem. * * @param content message content */ function Message($content) ( $this->content = $content; ) /** * Escreve uma mensagem para a sessão */ function send() ( $_SESSION["session_messages"] = $this->content; ) /** * Envia uma mensagem para a página. isto->appendOutput(" ".$este->conteúdo.""); } }

class Inbox extends Outputable ( /** * Array de mensagens recebidas. */ var $messages = array(); /** * No construtor, recebemos todas as mensagens recebidas * e as removemos da sessão. */ function Inbox( ) ( if (is_array ($_SESSION["session_messages"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i< $co; $i++) { $this->mensagens = nova Mensagem($mensagens[$i]); ) ) /* limpa o array de mensagens */ $_SESSION["session_messages"] = array();< $co; $i++) { $this->) /** * Exibe o conteúdo da Caixa de entrada na página."); } }

*/ function toPage() ( $co = sizeof($this->messages); $this->appendOutput("

"); para ($i = 0; $i
mensagens[$i]->toPage();

$this->appendOutput($this->messages[$i]->getOutput()); ) $this->appendOutput("O método de saída mudou - agora, em vez de enviar diretamente para a página, a representação externa é por enquanto armazenada em Outputable, que “fica” em cada um dos objetos. O método appendOutput() serve como um substituto para a construção echo(). Para obter a saída de um objeto, o método getOutput() é usado. Agora vamos ver qual é a parte cliente do código, o que resolverá o mesmo problema de antes. index.php


enviar();   /* segundo atual */ $msg_sec = new Message("second: " . date("s"));
"; ?>

A principal inovação está no objeto $global_content, cujo nome fala por si. Neste caso, pertence à classe Outputable; em tarefas da vida real, você provavelmente criaria uma classe separada para o conteúdo da página.

Se você olhar de perto, o conteúdo do script praticamente não mudou - a mesma caixa de entrada, o mesmo toPage(). Adicionada uma instrução que exibe o conteúdo da lista de mensagens no conteúdo da página. Para variar, duas mensagens são geradas agora.

Para ver o resultado, falta preparar o template XSL.
estilo.xsl

Exemplo XSLT

mensagem

O que conseguimos?

Em primeiro lugar, você pode assumir projetos complexos com mais confiança - a independência real dos módulos é garantida. A ordem em que os resultados são colocados na página agora é controlada por meio de um modelo XSL externo e não depende da ordem em que os módulos são executados.

Qualquer módulo que gere dados XML como resultado de seu trabalho pode ser utilizado em um projeto. Aliás, essa é uma das vantagens em relação aos templates templates, nos quais a criação de dados consiste em uma sequência de métodos de chamada (assign, etc.) de um motor específico, para o qual não existe um padrão comum.

Outra vantagem é a facilidade de depuração. Se você executar o script, notará que cada página contém saída de depuração - um protótipo XML que simplifica bastante a depuração de aplicativos.

Outra coisa que você precisa pensar é como criar objetos de mensagem. Nem sempre é conveniente usar new diretamente no código do cliente. Mas talvez este seja um tópico para um artigo separado.

Por fim, um galope sobre as perspectivas:

* janelas pop-up para uma lista de mensagens importantes
* "páginas do remetente" e "páginas de destino" nas mensagens
* registrar mensagens no banco de dados
* botão "mostrar histórico de minhas ações"
* análise estatística das ações do usuário nas sessões
* "assistentes inteligentes" em aplicações web