Jump to content


Bruno Augusto

Member Since 09/03/2004
Offline Last Active 24/08/2012, 10:16
-----

Posts I've Made

In Topic: Comparação De Arrays Multidimensionais

21/02/2010, 15:13

Eu tinha comentado isso lá no início... :P

Atenção à ordem dos dois primeiros parâmetros da função array_udiff(). Se retornar o oposto do que você quer, basta invertê-los.

[]’s

Cacetada! Eu inverto e começa a me retornar o array de cache inteiro SEM os índices POST que são enviados. Vou tentar nesse "modo" disponível no PHP 5.3 para o terceiro parâmetro. De repente...

[EDIT]

Vamos ver...

$cache = array( array( 'filepath' => 'p/t/f/A.php',
        	           'checksum' => 'xyz123',
        	           'filename' => 'A.php' ), 
        	
        	    array( 'filepath' => 'p/t/f/B.php',
                       'checksum' => 'xyz456',
                       'filename' => 'B.php' ),
        	               
        	    array( 'filepath' => 'p/t/f/Anuncios.php',
                       'checksum' => 'xyz111',
                       'filename' => 'Anuncios.php' ),

        	    array( 'filepath' => 'p/t/f/C.php',
                       'checksum' => 'xyz222',
                       'filename' => 'CPXInteractive.php' )
              );

$files = array( array( 'filepath' => 'p/t/f/A.php',
                       'checksum' => 'xyz123',
                       'filename' => 'A.php' ), 
            
                array( 'filepath' => 'p/t/f/B.php',
                       'checksum' => 'xyz456',
                       'filename' => 'B.php' ),
                           
                array( 'filepath' => 'p/t/f/Anuncios.php',
                       'checksum' => 'xyz000',
                       'filename' => 'Anuncios.php' )
              );

$updates = array_udiff( $cache, $files,
                        function( array $cache, array $files ) {
                            return strcmp( $cache['checksum'], $files['checksum'] );
                        }
                      );

// Retorno:

Array
(
    [2] => Array
        (
            [filepath] => p/t/f/Anuncios.php
            [checksum] => xyz111
            [filename] => Anuncios.php
        )

    [3] => Array
        (
            [filepath] => p/t/f/CPXInteractive.php
            [checksum] => xyz222
            [filename] => CPXInteractive.php
        )

)

Perfeito :D

Mas quando implemento $cache como sendo o arquivo diversas vezes anexado e
o $files como sendo a propriedade $this -> data['files'], o resultado é:

Array
(
    // Esse apareceu, pois é diferente. Perfeito

    [0] => Array
        (
            [filepath] => admin/application/controllers/AdvertisementController.php
            [checksum] => 928c5e3bd0c5f8d3613fce7a3bdc9dac
            [filename] => AdvertisementController.php
        )

    [1] => Array
        (
            [filepath] => admin/application/controllers/BugsController.php
            [checksum] => 928ec3fb60a648aeeb62c98408af642c
            [filename] => BugsController.php
        )

    [2] => Array
        (
            [filepath] => admin/application/controllers/CreditsController.php
            [checksum] => c7e903ef55c0df721ffe03ef92fd9904
            [filename] => CreditsController.php
        )

    [3] => Array
        (
            [filepath] => admin/application/controllers/DatabaseController.php
            [checksum] => 4846aa17f662a8d65e4901d7597d5a37
            [filename] => DatabaseController.php
        )

    // Aqui, no índice nº.4, seria o HomeController cujo checksum é igual ao corrente do cache
    // Ele NÃO apareceu e isso é bom. Mas e os outros índices?
    // Não estão presentes no array de enviados e são listados

    [5] => Array
        (
            [filepath] => admin/application/controllers/IntegrationController.php
            [checksum] => 93cfd92a29f94608c7ad80a1ce440892
            [filename] => IntegrationController.php
        )

    // Cotinuando, no índice nº. 101 (não mostrado aqui), tenho o correspondente
    // ao CPXInteractive.php, recém adicionado para testes
    // Ele está sendo listado porque não existe no array enviado.
)

E, como sempre, o array dos arquivos enviados continua o mesmo:

$this -> data = array (
  'service' => 'WordPress',
  'product' => 'Corporative',
  'uType' => 'fixes',
  'files' => 
  array (
    0 => 
    array (
      'filepath' => 'admin/application/controllers/AdvertisementController.php',
      'checksum' => '42ab4fc2af91337be03ce1cb7f4fd837',
      'filename' => 'AdvertisementController.php',
    ),
    1 => 
    array (
      'filepath' => 'admin/application/controllers/HomeController.php',
      'checksum' => '28cbf3c60752631a3fa87e427e35afb6',
      'filename' => 'HomeController.php',
    ),
    2 => 
    array (
      'filepath' => 'admin/library/Zend/Controller/Request/Exception.php',
      'checksum' => 'ef458d8a75cc650d9cbf90ff89df9012',
      'filename' => 'Exception.php',
    ),
  ),
)
Obviamente está havendo outro mal entendido, tal qual quando explicado sobre a impossibilidade de se haver
arquivos de mesmo checksum. Mas qual?

Canso de dar print_r() no meu $cache aparentemente defeituso e no improvisado funcional e vê-los estruturadamente iguais, exceto pela quantidade de índices.

Tal sentimento de frustração é ´recóproco para $this -> data['files] e o array de comparação final.

E pior que a única explicação que me vem à cabeça seria essa diferença na quantidade de índices. Mas logo que penso nisso, acabo desistindo da hipotese pois vejo o exemplo funcional onde os arrays posseum tamanhos diferentes de todo jeito.

Uma coisa que aparenta ser simples, tem provas de que funciona, mas em duas estruturas de três etapas visualmente iguais produzem resultados diferentes. Haja paciência.

In Topic: Comparação De Arrays Multidimensionais

18/02/2010, 17:19

Primitivo, mas bem explicado, certo?

Estou na Lan, então vamos ver "o que sai de cabeça":

Sem releases ou features nem nada, duas estruturas iguais, com os mesmos arquivos e diretórios.

$cache (pós unserialize):
array( array( 'filepath' => 'path/para/arquivo/X.php', 'checksum' => 'xyz123' => 'filename' => 'X.php' ),
             array( 'filepath' => 'path/para/arquivo/Y.php', 'checksum' => 'xyz456' => 'filename' => 'Y.php' ),
             array( 'filepath' => 'path/para/arquivo/Z.php', 'checksum' => 'xyz789' => 'filename' => 'Z.php' ), /*...*/ );

$this -> data['files'] (arquivos recebidos via POST, tratados e enviados via cURL [ou não]):
array( array( 'filepath' => 'path/para/arquivo/A.php', 'checksum' => 'xyz123' => 'filename' => 'A.php' ),
             array( 'filepath' => 'path/para/arquivo/B.php', 'checksum' => 'xyz456' => 'filename' => 'B.php' ),
             array( 'filepath' => 'path/para/arquivo/Z.php', 'checksum' => 'abc987' => 'filename' => 'Z.php' ), /*...*/ );

A comparação, nesse caso deveria retornar o índice referente à Z.php vindo de $cache, pois ele é o repositório, com a versão mais recente de Z.php.

Certo?

Cenário: Parte do sistema é um gerenciador de anúncios (Google AdSense, Yahoo! Publisher Network e etc.). Cada sistema de anúncios possui suas particularidades e, por isso, possuei sua própria classe que implementa uma interface comum.

Suponhamos que eu deseje adicionar suporte à detecção e manipulamento dos banners da... sei lá... CPX Interactive.

Crio uma classe para o sistema e MODIFICO a biblioteca principal, que recebe o código do anúncio, verifica "por cima" algumas coisas comuns àquele Sistema de Anúncios, inclui a classe Adaptadora e passa as informações para controlador que faz todo o resto das operações.

Com isso em mente ficamos:

$cache
array( array( 'filepath' => 'path/para/arquivo/X.php', 'checksum' => 'xyz123' => 'filename' => 'X.php' ),
             array( 'filepath' => 'path/para/arquivo/Y.php', 'checksum' => 'xyz456' => 'filename' => 'Y.php' ),
             array( 'filepath' => 'path/para/arquivo/Z.php', 'checksum' => 'xyz789' => 'filename' => 'Z.php' ),
             array( 'filepath' => 'path/para/biblioteca/gerenciadora/de/Anuncios.php', 'checksum' => 'xyz000' => 'filename' => 'Anuncios.php' ),
             array( 'filepath' => 'path/para/classe/CPXInteractive.php', 'checksum' => 'xyz222' => 'filename' => 'CPXInteractive.php' ), /*...*/ );

$this -> data['files']
array( array( 'filepath' => 'path/para/arquivo/A.php', 'checksum' => 'xyz123' => 'filename' => 'A.php' ),
             array( 'filepath' => 'path/para/arquivo/B.php', 'checksum' => 'xyz456' => 'filename' => 'B.php' ),
             array( 'filepath' => 'path/para/arquivo/Z.php', 'checksum' => 'xyz789' => 'filename' => 'Z.php' ),
             array( 'filepath' => 'path/para/biblioteca/gerenciadora/de/Anuncios.php', 'checksum' => 'xyz111' => 'filename' => 'Anuncios.php' ), /*...*/ );
A diferença, nesse caso, retornaria o Anuncios.php de $cache, que agora inclui suporte à CPX Interactive e também retornaria a própria classe da CPX Interactive, que, na instalação/versão corrente do usuário, ainda não existe.

Acredito que agora tenha ficado bem claro, tanto a necessidade como o porquê de eu bater tanto na tecla de usar a combinação de array_udiff() com strcmp().

In Topic: Comparação De Arrays Multidimensionais

18/02/2010, 12:04

Na traaaaave! :lol:

De fato, o erro que estava obtendo ao passo que você não se devia mesmo ao fato mencionado sobre dois arquivos com o mesmo checksum. Removido, passou a funcionar direitinho.

Direitinho em partes. Lembra que comentei que quando inverti os arrays de array_udiff() passou a retornar todos os itens do cache exceto os índices enviados por POST que não passaram pelo callback? Pois então, aconteceu de novo.

Mas isso não é um bug, é um problema pois, pela definição de array_udiff() o que me está acontecendo está correto, mas não é o que preciso. Preciso das entradas do cache, que será aquilo que atualizarei (bugfixes, novas releases...), mas que não constam no enviado por POST.

Ex: POST envia o AdvertisementController.php com hash XYZ. No cache tenho um misto de bugfix com release fazendo o arquivo citado possuir hash ABC. Porém, a parte release da coisa implementa um novo arquivo (que no caso seria suporte à um novo Sistema de Anúncios - onde cada um é uma classe própria). No cache aparecia essa entrada a mais, mas no POST não.

A comparação nesse caso me retornaria o arquivo de hash diferente mais essa entrada nova.

[OFF]

Esse problema do JSON é da prórpia json_encode(). Palavras acentuadas retornam NULL. Para suportar acentos, as strings acentuadas devem passar por utf8_encode(). ;)

In Topic: Comparação De Arrays Multidimensionais

17/02/2010, 12:23

Pois é essa "duplicidade" foi proposital, para testar até onde a computação de diferenças funciona.

Significa que eu NUNCA poderei esquecer, nem mesmo acidentalmente, um arquivo duplicado, de mesmo nome e outro path do meu repositório?

E se eu quiser "contornar" esse problema. Não sei, de repente eu esqueço de apagar o arquivo do servidor via FTP e começa a dar problema. Não posso antes de verificar os checksum's verificar os paths?

Outra coisa, testei também imprimir todas as comparações (tirando o IF) e notei que a função de retorno faz tipo de Liga de Futebol, todo mundo contra todo mundo. Isso não poderia acarretar uma perda de perforance e, a curto prazo, estouro de banda do servidor? Se sim, teria como alterar a forma como essa comparação é feita, para ficar mais ágil?

E, sobre o JSON, as entradas mencionadas estão NULL no arquivo JSON gerado. No array que serve como parâmetros está UpdateController - Cópia.php (outro teste auto imposto).

In Topic: Comparação De Arrays Multidimensionais

15/02/2010, 08:43

Exatamente. Finalmente você chegou no mesmo problema que eu estou presenciando.

Nesse array preenchido no construtor, altere o último caractere. Vai entrar no array da diferença. Altere todo ele, para um dos valores no comentário e ele deixa de entrar.

Eu adicionei alguns print's dentro do método computeDiff(), antes do return, para verificar:

if( strcmp( $cache["checksum"], $sent["checksum"] ) == 0 ) {
    print '================================<br /><br />$cache<br /><br />';
    print $cache['filepath'] . '<br />' . $cache['checksum'] . '<br />' . $cache['filename'];
    print '<br /><br />$sent<br /><br />';
    print $sent['filepath'] . '<br />' . $sent['checksum'] . '<br />' . $sent['filename'];
    print '<br /><br />';
}
Quando você troca um caractere, nesse debug da 25 de Março, ele não aparcee.
Quando você troca inteiro aparece, como se ambos os índices de ambas as variáveis fossem iguais, quando não são.

[OFF]

Porque json_encode() ignora as entradas do array que possuem espaço? Pergunto isso pois, o índice de número 12 possui e, na decodificação do JSON, os campos filepath e filename estão nulos.

IPB Skin By Virteq