Jump to content


Photo

Comparação De Arrays Multidimensionais


  • Faça o login para participar
34 replies to this topic

#31 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

  • Usuários
  • 1968 posts
  • Sexo:Não informado
  • Localidade:Itajubá

Posted 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(). ;)

Edição feita por: Bruno Augusto, 18/02/2010, 12:05.


#32 Paulo Freitas

Paulo Freitas

    ××××××× LRU #456504 ××××××× ××××××× LRM #364686 ×××××××

  • Ex-Admins
  • 5612 posts
  • Sexo:Masculino
  • Localidade:Campinas - SP

Posted 18/02/2010, 13:46

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.

xxxxxx! Juro que já estou perdido nisso tudo. Já não sei mais o que tu quer e o que está acontecendo. :P

Tem como exemplificar o que tu quer e o que está acontecendo de uma forma mais primitiva? ^_^

Sei lá, o cenário atual é tão complexo que, com os meus problemas na cabeça, não consigo nem ligar os fatos mais. :P

Por forma primitiva entenda um simples exemplo da função array_udiff() com o que está ocorrendo e o que você gostaria que ocorresse.

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

Aqui não ocorre isso. :huh:

/opt/lampp/bin/php -r "var_dump(json_encode('ó'));" // string(8) ""\u00f3""
Mesma coisa no codepad.org: http://codepad.org/QJekwIxX

Pode ser sistema operacional, versão do PHP, configuração do PHP, whatever. Não sei. :blink:

[]’sAté mais

#33 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

  • Usuários
  • 1968 posts
  • Sexo:Não informado
  • Localidade:Itajubá

Posted 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().

#34 Paulo Freitas

Paulo Freitas

    ××××××× LRU #456504 ××××××× ××××××× LRM #364686 ×××××××

  • Ex-Admins
  • 5612 posts
  • Sexo:Masculino
  • Localidade:Campinas - SP

Posted 19/02/2010, 12:41

Ah, cacildes!

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

/*
array(1) {
  [3]=>
  array(3) {
    ["filepath"]=>
    string(49) "path/para/biblioteca/gerenciadora/de/Anuncios.php"
    ["checksum"]=>
    string(6) "xyz111"
    ["filename"]=>
    string(12) "Anuncios.php"
  }
}
*/

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

/*
array(2) {
  [3]=>
  array(3) {
    ["filepath"]=>
    string(49) "path/para/biblioteca/gerenciadora/de/Anuncios.php"
    ["checksum"]=>
    string(6) "xyz000"
    ["filename"]=>
    string(12) "Anuncios.php"
  }
  [4]=>
  array(3) {
    ["filepath"]=>
    string(35) "path/para/classe/CPXInteractive.php"
    ["checksum"]=>
    string(6) "xyz222"
    ["filename"]=>
    string(18) "CPXInteractive.php"
  }
}
*/
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.

[]’sAté mais

#35 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

  • Usuários
  • 1968 posts
  • Sexo:Não informado
  • Localidade:Itajubá

Posted 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.

Edição feita por: Bruno Augusto, 19/02/2010, 16:03.





1 user(s) are reading this topic

0 membro(s), 1 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq