Jump to content


Bruno Augusto's Content

There have been 19 items by Bruno Augusto (Search limited from 17/04/2023)


Ordernar por                Order  

#994832 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 21/02/2010, 15:13 in 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.

[]’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.



#994694 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 18/02/2010, 17:19 in PHP

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



#994681 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 18/02/2010, 12:04 in PHP

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



#994584 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 17/02/2010, 12:23 in PHP

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



#994452 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 15/02/2010, 08:43 in PHP

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.



#994372 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 13/02/2010, 11:52 in PHP

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.



#994330 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 12/02/2010, 16:22 in PHP

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',
                                                       ),
                                                )
                           );



#994087 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 11/02/2010, 12:33 in PHP

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



#994032 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 09/02/2010, 17:13 in PHP

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



#994012 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 09/02/2010, 12:12 in PHP

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



#993807 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 06/02/2010, 14:12 in PHP

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?



#993593 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 05/02/2010, 16:17 in PHP

Opa, esse $this -> teste() foi falha minha.

Queria limpar um pedacinho de filepath sem ter de recriar o cache. Vou testar o modo como fez porque, visualmente está igualzinho o que eu estava fazendo.

Funcionou... Ou quase...

Estritamente do jeito que você postou, porém, dentro da minha classe ao invés de uma nova,
retornou o mesmo que você obteve.

Mas, como isso é um parte de um sistema de atualização, em linha de produção, o hash enviado
(que você populou no construtor) seria um completamente diferente, ao invés de mudar um único caractere.

Em paralelo, mantenho outro script de testes que me informa o hash real dos arquivos, isto é, a mesma
informação que o serviço receberá via POST para comparar.

Esse hash, nesse momento, é 949b6dc2061907b0fd5af3a7ed088bf9.

Oras, o que strcmp() faz na realidade?

Pergunto isso porque, depurando com var_dump(), obtive:

var_dump( strcmp( '28cbf3c60752631a3fa87e427e35afb5', '28cbf3c60752631a3fa87e427e35afb6' ) ); // int(-1)
var_dump( strcmp( '28cbf3c60752631a3fa87e427e35afb6', '28cbf3c60752631a3fa87e427e35afb5' ) ); // int(1)
var_dump( strcmp( '28cbf3c60752631a3fa87e427e35afb6', '949b6dc2061907b0fd5af3a7ed088bf9' ) ); // int(-1)
Pelo que entendi, no primeiro e terceiro caso a primeira string é menor que a segunda, enquanto no segundo é maior.

Mas menor e maior em quê? Me parece que strcmp() está comparando caractere a caractere e, quando encontra uma diferença,
determina se é maior ou menor (quando números) ou "vem antes ou depois" (quando letras). Acompanhe o esquema:

2  8  c  b  f  3  c  6  0  7  5  2  6  3  1  a  3  f  a  8  7  e  4  2  7  e  3  5  a  f  b  5

2  8  c  b  f  3  c  6  0  7  5  2  6  3  1  a  3  f  a  8  7  e  4  2  7  e  3  5  a  f  b  6

=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  <

// Resultado: Menor, logo -1
O esquema está ilustrado pelos sinais de comparação ;)

Como dá para perceber, o teste foi se desenrolou até que alguma diferença ocorreu e só então determinou como sendo
um hash diferente.

Já no terceiro caso, o primeiro caractere da primeira string é 2 e na segunda 9. Só a partir
desse caractere já deu diferença, sendo caracterizado como menor.

Eu não acredito que estou tão errado nessa afirmação pois, nos comentários do manual, um tal de Colin expõe
um exemplo que também usa strcmp() para comparar strings e, quando elas são exatamente iguais, ele também
obteve um array vazio.

Isso não é certo para esse caso.

Com tudi isso, fica a pergunta: Se para funcionar, array_udiff() requer que a função ou método de callback retorne
-1, 0 ou 1 e, para comparar essas strings essa exigência acaba se tornando uma impossibilidade, array_udiff() é a melhor
função para a tarefa?

Se o problema não for com array_udiff() e sim com a escolha de strcmp() (que não só eu achei problemática) para a
tarefa, há como fazer outra função retorna o esquema requerido poe array_udiff() ?

Enfim, por consideração a uma possível solução que não exija a desserialização do array de cache, vou postar as
estruturas correntes com seus respectivos hashes atualizados.

O registro com hash diferente, agora, fica para AdvertisementController, bem mais diferente que um único caractere
// $cache (regenerado)

Array
(
    [0] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/AdvertisementController.php
            [checksum] => 928c5e3bd0c5f8d3613fce7a3bdc9dac
            [filename] => AdvertisementController.php
        )

    [1] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/HomeController.php
            [checksum] => 28cbf3c60752631a3fa87e427e35afb6
            [filename] => HomeController.php
        )

    [2] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/library/Zend/Controller/Request/Exception.php
            [checksum] => ef458d8a75cc650d9cbf90ff89df9012
            [filename] => Exception.php
        )
)

// $POST

Array
(
    [0] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/AdvertisementController.php
            [checksum] => 42ab4fc2af91337be03ce1cb7f4fd837
            [filename] => AdvertisementController.php
        )

    [1] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/application/controllers/HomeController.php
            [checksum] => 28cbf3c60752631a3fa87e427e35afb6
            [filename] => HomeController.php
        )

    [2] => Array
        (
            [filepath] => C:/Program Files/Zend/Apache2/htdocs/repository/wordpress/themes/Corporative/admin/library/Zend/Controller/Request/Exception.php
            [checksum] => ef458d8a75cc650d9cbf90ff89df9012
            [filename] => Exception.php
        )

)



#993466 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 02/02/2010, 15:43 in PHP

Então tudo bem, se faz questão...

Para minha instalação local, que´é 5.3+
$diff2 = array_udiff( $a1, $a2, function( $a1, $a2 ) {
                                          return strcmp( $a1['checksum'], $a2['checksum'] );
                                      }
                          );

Para adequar aos servidores de quem vier a utilizar:
$diff = array_udiff( $a1, $a2, create_function( '$a1, $a2', 
                                         'return strcmp( $a1["checksum"], $a2["checksum"] );' ) );

Para ambas as situações:

$a1 = $this -> teste( $cache );
$a2 = $this -> teste( $this -> data['files'] );
E o modo "clássico":

$diff = array_udiff( $a1, $a2, array( $this, 'computeDiff' ) );

...

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



#993460 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 02/02/2010, 15:15 in PHP

Falei mais no desabafo ^^

Eu postei como estou faznedo, tanto é que você até citou perguntando o que tinha no método. Ea resposta para esse método é aquilo que você passou na primeira resposta.

A diferença é que, colocando como método próprio, as variáeis têm nome certo. E são acessadas como variáveis e não como propriedades, daí o erro de -> não ocorre.

Mas ainda assim não funciona.



#993456 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 02/02/2010, 14:46 in PHP

Acho que nã importa como estou fazendo, porque não deu certo mesmo :(

Já que uma propriedade, com $this, não possa entrar como parte de um create_function() (aparentemente), criei duas variáveis para armazenar os valores delas para "passar".

Vou postar exatamente o código que estou usando para preencher essa propriedade manualmente (meu Modo Debug), juntamente com meu ahe serialziado.

$this -> data = array( 'service' => 'WordPress',
			     'product' => 'Corporative',
			     'uType'   => 'fixes',
			     'files'   =>  array( array( 'filepath' => 'admin/application/controllers/AdvertisementController.php',
                                                         'checksum' => '42ab4fc2af91337be03ce1cb7f4fd837',
                                                         'filename' => 'AdvertisementController.php'
                                                       ),

                                                  array( 'filepath' => 'admin/application/controllers/HomeController.php',
                                                         'checksum' => '28cbf3c60752631a3fa87e427e35afb6',
                                                         'filename' => 'HomeController.php'
                                                       ),

                                                  array( 'filepath' => 'admin/library/Zend/Controller/Request/Exception.php',
                                                         'checksum' => 'ef458d8a75cc650d9cbf90ff89df9012',
                                                         'filename' => 'Exception.php',
                                                       ),
                                                )
                      );

Meu cache Serializado

O que não funcioou foi que, informando primeiro o cache e depois o POST, retornou todo o cache SEM alguns elementos (perceptíveis por "pular" alguns índices) e, o contrário, primeiro o POST, retornou vazio.

A tentatyiva do modelo clássico foi, informando como terceiro parâmetro para array_udiff():
array( $this, 'metodo_de_comparacao' )

Quem sabe assim melhore o entendimento.



#993304 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 01/02/2010, 11:38 in PHP

Entendido, vou exemplificar o último ponto.

Se eu desenvolver um arquivo a mais do que o release corrente do usuário, seja para adicionar um recurso ou complementar um recurso existente atualizado, no array pós unserialize() (o meu cache) eu terei uma entrada extra, (a exemplo, a de nº. 475).

Ao comparar com esse callback usando strcmp(), esse índice será incluído no array das diferenças? Pois ele não existe no outro array, vindo via HTTP POST / AJAX POST, sendo assim não tem com quem ser comparado.

Outra coisa. O modelo 5.3 não posso usar pois são poucos servidores no Brasil com essa versão do PHP instalado, então preciso usar a segunda.

Porém, a menos que eu tenho digitado algo errado, deu um erro de -> (esqueci o nome ^^), pois, o segundo arrayu é uma propriedade da classe.

Pensei em usar o modelo "clássico" de array_udiff(), mas deu erro de tipos.



#993232 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 31/01/2010, 13:54 in PHP

Pelo manual, strcmp() compara e retorna maior, menor ou igual a zero. Como que ela pode diferenciar MD5 (índice checksum)?

E mais: Quando comparando para obter a lista de arquivo novos, no array POST não haverá o índice checksum correspondente. Essa associação idéias que estou fazendo não compete, certo? Se não existir, vai ser incluindo de todo jeito?



#993229 Comparação De Arrays Multidimensionais

Posted by Bruno Augusto on 31/01/2010, 12:52 in PHP

Vejam a foto:

Posted Image
O primeiro array vêm via HTTP POST, o segundo é um cache de arquivo depois de desserializado.

Isso faz parte de um sistema de atualizações onde é enviado para o meu servidor a lista de arquivos que uma instalação do meu sistema tem e é comparada com outra lista, pré-existente.

Combinando em nomes de arquivo, mas sendo diferente em checksum, entra para lista final, siginificando que deve haver atualização daquele arquivo.

Eu fiz dois foreach's aninhados, cada um sobre um dos arrays, com if's aninhados que verificam o valor das chaves e incluem em outro array, para ser retornado, se houver diferença.

Mas são arrays bem grandes (475 itens para ser exato) e fazer loop dentro de loop acaba ficando muito lento. Ainda mais que é um serviço, se ficar lento minha banda vai pra cucuia. :P

Como eu faço para comparar? Anteriormente os índices filepaths eram diferentes a nível de 3 diretórios. Mexi daqui e mexi dali até fazer o filepath do cache ser igual ao vindo via HTTP POST, mas ainda não consigo comparar por ser multimensional.

A minha tentativa deu certo? Deu. Mas ficou inflexível e, além de comparar essas diferenças, preciso reutilizar o código para obter também os novos arquivos que eu crio os quais uma atualização possa depender. Assim evito a cada pequena correção, obrigar o usuário a baixar um release de mais ou menos 4MB.



#963365 Obter Instância Singleton Dinâmicamente...

Posted by Bruno Augusto on 08/04/2009, 15:06 in PHP

Pessoal,

Implementações de Singleton têm aos milhares por aí e uma das mais simples é essa:

public static function init()
{
	 if ( NULL === self :: $instance )
	 {
		  self :: $instance = new self();
	 }
		
	 return self :: $instance;
}
Perfeito.

Daí eu fui retomar um arquivo aqui só para não perder o costume e percebi que eu estava usando Singleton de um lado e instância"comuns" (com new) de outro.

Não que não funcionasse, mas que queria tentar de outro jeito.

Tirando as verificações eu fazia:

$var = new $_GET['var'];
Onde o nome da classe passa pela URL em querystring.

Daí, fui passar para Singleton por pura frescura vontade de aprender :lol:

Adicionei aquele bloco na classe (que o nome passou por GET) e troquei a linha acima por:

$var = $_GET['var'] :: init();
E resulta parse error. Se eu tiro a variável e passo a palavra que passa por GET diretamente, funciona.

Pergunta: Essa implementação de Singleton não permite usar variáveis para obter a instância?

Se não, como faço então?




IPB Skin By Virteq