Jump to content


Photo

Comparação De Arrays Multidimensionais


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

#16 Paulo Freitas

Paulo Freitas

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

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

Posted 06/02/2010, 15:06

Então porque não funciona? Fiz igualzinho o seu e funcionou porque eu troquei o último caractere do hash.

Mas quando eu troquei o hash inteiro deixou de ser incluído na listagem?

Tudo Ok aqui: http://codepad.org/ODMrgXVs (output no final da página)

[]’sAté mais

#17 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

Posted 09/02/2010, 12:12

Não compreendo. Copiei o seu exemplo funcionando, testei, troquei checksum e continuou funcionando.

Daí percebi que você inverteu as informações preenchidas. O array que você informou como cache é o enviado e vice-versa.

Achando que seria esse o motivo, devido a definição de array_udiff(), inverti-os e continuou funcionando.

Copiei para a classe definitiva (Zend Framework Controller), e deixou de funcionar, retornando um array vazio.

Continuei testando e resolvi copiar o array de cache manual, atribuindo à variável usada, substituindo a proveniente de unserialize() junto com file_get_contents(), que constroem o cache real.

E daí funcionou.

No print_r() mais abaixo, em várias abas do Firefox, executei uma exibição das três variáveis: $cache (real), $cache2 (copiado manualmente) e $updates (a diferença).

Visualmente, os dois primeiros são iguais, exceto, é claro, que o real têm muito mais índices que o falso e que, no real, em alguns índices, os "filepaths" possuem "um nível a menos", isto é, sem o /admin.

Não sei se você utiliza Zend Framework e se tem como testar, mas, em todo caso, estarei anexando os dois arquivos envolvidos: o Controller e o arquivo .MD5.

A parte com problema se encontra logo abaixo do grande comentário dentro do método themesAction().

Impossível...

[Anexos - MediaFire]

UpdateController.php
wordpress.themes.Corporative.md5

#18 Paulo Freitas

Paulo Freitas

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

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

Posted 09/02/2010, 15:17

Este arquivo .md5 não está desserializando:

var_dump(unserialize(file_get_contents('wordpress.themes.Corporative.md5')));

Notice: unserialize(): Error at offset 3346 of 119668 bytes in /home/paulo/Desktop/diff.php on line 70
bool(false)

É por isso que não funciona. Ainda acredito que seja melhor usar o JSON, é menos problemático. Tu pode usar a classe Zend_Json, já que está usando o ZF: http://framework.zen...son.basics.html ;-)

[]’sAté mais

#19 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

Posted 09/02/2010, 17:13

Oras, mas como pode isso. Se eu faço um print_r() nessa variável pós unserialize() e não dá erro algum.

#20 Paulo Freitas

Paulo Freitas

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

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

Posted 09/02/2010, 18:44

Esse código que usei com você funciona normal?

var_dump(unserialize(file_get_contents('wordpress.themes.Corporative.md5')));
Ao menos do arquivo .md5 que tu me enviou o PHP relata que o arquivo está "corrompido". :ponder:

É a única explicação plausível para retornar um array vazio nesta condição.

[]’sAté mais

#21 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

Posted 11/02/2010, 12:33

Testei o seu array, que copiei manualmente e funcionou, serializando ele e armazenando no arquivo de cache.

Deu certo também. Não sei ao certo se o erro que você reportou está no mesmo offset, mas eu tentei falsificar o conteúdo do cache envolvendo a string em aspas simples e gerou um erro de offset (obviamente) perto, se não igual, do número que você obteve.

E os conteúdo são os mesmos, nem uma aspa a mais ou a menos. O código de depuração citado funciona normal, a diferença é que testou com print_r para "ver melhor" (mas com var_dump() obtenho sucesso de todo modo).

O que pode ser?

[EDIT]

Segui sua sugestão a respeito do Zend_Json. Implementei, recriei o cache, agora de extensão .json e testei o sistema.

E o que aconteceu? Simplesmente TODO o array de cache passou a ser retornado, com excesão dos índices 4 e 232 que correspondem, respectivamente, às entradas do HomeController e do Exception.

O curioso é que eu não as modifiquei, elas continuam com o mesmo checksum (verificado por comparação manual simultânea), o que strcmp() deveria retornar zero.

O mesmo vale para os outro índices que, por não tiverem sido enviados via POST, nem entram na verificação. E ainda assim estão sendo incluídos na diferença.

Dessa vez, vou linkar esse arquivo .json e a classe que o gera.

Esta classe,por sua vez, não requer a estrutura Zend Framework, mas,desde agora, requer o Zend_Json.

A linha do unserialize() agora, em JSON, ficou:

$cache = Zend_Json::decode( file_get_contents( $cacheFile ) );
Acredito que não haja necessidade, mas em todo caso, para usar a classe Checksum (que gera o cache), basta obter a instância Singleton com getInstance() e invocar o método renewChecksum(), passando um nome de arquivo como parâmetro.

P.S.: Você disse anteriormente que para array_udiff(), o que interessa é o zero. Por quê? Zero não siginifica que já está presente nos outros arrays?

[Anexo - MediaFire]

Checksum
wordpress.themes.Corporative.json

Edição feita por: Bruno Augusto, 11/02/2010, 12:34.


#22 Paulo Freitas

Paulo Freitas

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

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

Posted 12/02/2010, 07:47

Testei o seu array, que copiei manualmente e funcionou, serializando ele e armazenando no arquivo de cache.

Deu certo também. Não sei ao certo se o erro que você reportou está no mesmo offset, mas eu tentei falsificar o conteúdo do cache envolvendo a string em aspas simples e gerou um erro de offset (obviamente) perto, se não igual, do número que você obteve.

E os conteúdo são os mesmos, nem uma aspa a mais ou a menos. O código de depuração citado funciona normal, a diferença é que testou com print_r para "ver melhor" (mas com var_dump() obtenho sucesso de todo modo).

O que pode ser?

Não tenho a mínima idéia, o unserialize() do PHP 5.3.1 aqui não funcionou. :wacko:

Segui sua sugestão a respeito do Zend_Json. Implementei, recriei o cache, agora de extensão .json e testei o sistema.

E o que aconteceu? Simplesmente TODO o array de cache passou a ser retornado, com excesão dos índices 4 e 232 que correspondem, respectivamente, às entradas do HomeController e do Exception.

O curioso é que eu não as modifiquei, elas continuam com o mesmo checksum (verificado por comparação manual simultânea), o que strcmp() deveria retornar zero.

O mesmo vale para os outro índices que, por não tiverem sido enviados via POST, nem entram na verificação. E ainda assim estão sendo incluídos na diferença.

Dessa vez, vou linkar esse arquivo .json e a classe que o gera.

Esta classe,por sua vez, não requer a estrutura Zend Framework, mas,desde agora, requer o Zend_Json.

A linha do unserialize() agora, em JSON, ficou:

$cache = Zend_Json::decode( file_get_contents( $cacheFile ) );
Acredito que não haja necessidade, mas em todo caso, para usar a classe Checksum (que gera o cache), basta obter a instância Singleton com getInstance() e invocar o método renewChecksum(), passando um nome de arquivo como parâmetro.

Putz! Facilite as coisas :P, me apresente só o var_export() do $this->data['files'] e do $cache retornado pelo método Json_Json::decode(). Nessa altura do campeonato eu já estou mais perdido que cego em tiroteio. :assobio:

P.S.: Você disse anteriormente que para array_udiff(), o que interessa é o zero. Por quê? Zero não siginifica que já está presente nos outros arrays?

Yeap, zero significa que é igual, e para função o que importa é o que é diferente. Entendeu? :P A função strcmp() tem 3 retornos diferentes e para a array_udiff() você só tem duas condições: incluir ou não. O retorno maior que e menor que da strcmp() não importa, o que importa é ter algo diferente de zero - por isso que ele é o que importa. :P

[]’sAté mais

#23 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

Posted 12/02/2010, 16:22

Bom, o retornado por Zend_Json já anexei na resposta anterior e o $this -> data['files'], apesar de ter sido postado um bom tanto de vezes, vai abaixo de novo. Só não vou portar o var_dump() dele porque na LAN não tenho servidor local e nem acesso ao remoto.

Como ele é um índice com pouca coisa antes dele, vai inteiro.

$this -> data = array( 'service' => 'WordPress',
                             'product' => 'Corporative',
                             'uType'   => 'fixes',
                             'files'   =>  array( array( 'filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/AdvertisementController.php',
                                                         'checksum' => '42ab4fc2af91337be03ce1cb7f4fd837',
                                                         'filename' => 'AdvertisementController.php'
                                                       ),

                                                  array( 'filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/HomeController.php',
                                                         'checksum' => '28cbf3c60752631a3fa87e427e35afb6',
                                                         // Original => 28cbf3c60752631a3fa87e427e35afb6
                                                         // Alterado => 949b6dc2061907b0fd5af3a7ed088bf9
                                                         'filename' => 'HomeController.php'
                                                       ),

                                                   array( 'filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/library/Zend/Controller/Request/Exception.php',
                                                          'checksum' => 'ef458d8a75cc650d9cbf90ff89df9012',
                                                          // Original => ef458d8a75cc650d9cbf90ff89df9012
                                                          // Alterado => b0ec0145458109efb260ea59ba12516e
                                                          'filename' => 'Exception.php',
                                                       ),
                                                )
                           );


#24 Paulo Freitas

Paulo Freitas

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

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

Posted 12/02/2010, 16:52

Oh ya, o retorno do JSON eu já tenho aqui, comi bola. O $this->data['files'] eu pedi pois achei que você havia modificado algo. Aqui continua funcionando normalmente, um array vazio é retornado, o que é o esperado. Tem certeza de que você não está fazendo nada errado? :huh:

[]’sAté mais

#25 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

Posted 13/02/2010, 11:52

Para decodificar você usou a json_decode() ou o Zend_Json::decode() (havia me esquecido que o anexado era em JSON não em array - resultado da decodificação, como pediu).

Muito estranho duas pessoas fazerem a mesma coisa e terem resultados diferentes.

#26 Paulo Freitas

Paulo Freitas

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

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

Posted 13/02/2010, 17:38

Para decodificar você usou a json_decode() ou o Zend_Json::decode() (havia me esquecido que o anexado era em JSON não em array - resultado da decodificação, como pediu).

Muito estranho duas pessoas fazerem a mesma coisa e terem resultados diferentes.

Usei json_decode() pra ser mais rápido e por ser a mesma coisa. Veja que no próprio método Zend_Json::decode() eles usam a função json_decode() se ela existir, o que quer dizer que tanto faz uma outra, a implementação da Zend_Json é a mesma: http://www.google.co...cd=4&ct=rc&l=61

Só precisei passar o segundo parâmetro como true para ter o mesmo efeito da classe Zend_Json. Eu tentei postar no CodePad, mas está dando timeout no código por causa da variável que contém os dados JSON. Mas tenho certeza de que lá funciona do mesmo jeito.

Meu código de debug é o mesmo do início mas adaptado ao uso do JSON:

<?php

class foo
{
    public function __construct()
    {
        $this->data = array('service' => 'WordPress',
                            'product' => 'Corporative',
                            'uType'   => 'fixes',
                            'files'   => array(array('filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/
AdvertisementController.php',
                                                     'checksum' => '42ab4fc2af91337be03ce1cb7f4fd837',
                                                     'filename' => 'AdvertisementController.php'
                                                     ),
                                               array('filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/
HomeController.php',
                                                     'checksum' => '28cbf3c60752631a3fa87e427e35afb6',
                                                     // Original => 28cbf3c60752631a3fa87e427e35afb6
                                                     // Alterado => 949b6dc2061907b0fd5af3a7ed088bf9
                                                     'filename' => 'HomeController.php'
                                                    ),
                                               array('filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/library/Zend/Controller/
Request/Exception.php',
                                                     'checksum' => 'ef458d8a75cc650d9cbf90ff89df9012',
                                                     // Original => ef458d8a75cc650d9cbf90ff89df9012
                                                     // Alterado => b0ec0145458109efb260ea59ba12516e
                                                     'filename' => 'Exception.php',
                                                    ),
                                               )
                           );
    }

    public function diff($cache)
    {
        return array_udiff($this->data['files'], $cache, array($this, 'computeDiff'));
    }

    private function computeDiff(array $cache, array $sent)
    {
        return strcmp($cache['checksum'], $sent['checksum']);
    }
}

$cache = json_decode(file_get_contents('wordpress.themes.Corporative.json'), true);

$foo = new foo;
var_dump($foo->diff($cache));

/*
array (0) {
}
*/
Veja que o retorno é um array vazio. Teste aí. Se retornar a mesma coisa, o problema é em alguma outra parte do código que eu ainda não tenho a menor idéia. :huh:

[]’sAté mais

#27 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

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

#28 Paulo Freitas

Paulo Freitas

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

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

Posted 15/02/2010, 11:34

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.

Uai, mas veja este exemplo do $this->data['files']:

array('filepath' => 'C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/
HomeController.php',
                                                     'checksum' => '28cbf3c60752631a3fa87e427e35afb6',
                                                     // Original => 28cbf3c60752631a3fa87e427e35afb6
                                                     // Alterado => 949b6dc2061907b0fd5af3a7ed088bf9
                                                     'filename' => 'HomeController.php'
                                                    ),
Tanto o hash 28cbf3c60752631a3fa87e427e35afb6 como o 949b6dc2061907b0fd5af3a7ed088bf9 existem no .json (para o mesmo arquivo inclusive, mas em locais diferentes). Por isso que não retorna como diferença. :huh:

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.

Porque está assim no arquivo .json... :assobio:

{"filepath":null,"checksum":"75046fc645ee76d1ba17250c32c60e1a","filename":null}
[]’sAté mais

#29 Bruno Augusto

Bruno Augusto

    ∙•● Restarting... ●•∙

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

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

#30 Paulo Freitas

Paulo Freitas

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

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

Posted 17/02/2010, 13:59

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?

Ya. (y)

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?

Olha, pode até ser possível de alguma outra forma, mas eu particularmente não sei. Uma saída seria verificar antes de executar se o diretório está Ok, algo do tipo. :ponder:

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?

Não vejo comparação 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).

Estranho. Pode ser o acento, mas aí já é coisa do ZF... A função json_encode() do PHP 5.3 transforma o ó em Unicode, ficando "\u00f3". Teria que ver se ocorre o mesmo com o método Zend_Json::encode():

var_dump(Zend_Json::encode('ó'));
Aqui não tenho como testar. :(

[]’sAté mais




1 user(s) are reading this topic

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

IPB Skin By Virteq