problems with (array) object

Asked

Viewed 128 times

2

I have a array of objects.

Ex.:

$array = array (1=$obj1, 2=$obj2...ect)

Turns out I’m converting these objects in arrays also to have a array of arrays instead of a object array for the purpose of transforming it into a array JSON.

  $todos = $produtosDao->pesquisaProdutos(); 

  foreach ($todos as $cada):

     $produto[] = (array) $cada;

  endforeach;

Well, when I do print_r($produto), I have on the screen the following: Note: I will put here only the first record not to be extended the post ok?

Array
(
    [0] => Array
        (
            [ProdutosidProduto] => 1
            [Produtostipo] => mp
            [Produtosmodelo] => F540 2 BAN.PNEU. 100 X 60
            [Produtosbandejas] => 2
            [Produtospeso] => 0
            [Produtosprensagem] => 0
            [ProdutosprecoUnitario] => 6500
            [Produtoscomprimento] => 100
            [Produtoslargura] => 60
            [Produtoscabo] => 0
            [Produtosligacao] => n
            [Produtospotencia] => 0
            [Produtosconsumo] => 0
            [Produtoscorrente] => 0
            [Produtosdisjuntor] => 0
            [Produtosdescricao] => 
Valor promocional limitado frete grátis ,para SP ,RJ ,MG ,ES. Os demais será cobrado apenas de SP para sua cidade ,valor de 500,00 ,a ser pago na entrega .



MAQUINA TOTALMENTE INDUSTRIAL E 100% NACIONAL .PRODUÇÃO DE ATÉ MIL PÇS POR DIA EM HORÁRIO NORMAL DE TRABALHO ,SISTEMA DIGITAL AUTOMATIZADO DE ÚLTIMA GERAÇÃO , SISTEMA PNEUMÁTICO COMPACTO E UNIFORME RECEBENDO A MESMA PRESSÃO EM TODA ÁREA DE ESTAMPAGEM, EVITANDO ASSIM OS SOMBREAMENTOS E EFEITOS FANTASMA NA ESTAMPA , SISTEMA DE RESISTÊNCIA DE ALTA QUALIDADE A MELHOR DO MERCADO AÇO INOX 304 , DANDO UMA VIDA ÚTIL MUITO SUPERIOR AS DEMAIS DO MERCADO , E FÁCIL TROCAS DAS RESISTÊNCIAS NÃO SENDO NECESSÁRIO TÉCNICO NO LOCAL , COM APENAS 4 PARAFUSOS O CLIENTE MESMO FAZ A TROCA, AS DEMAIS A RESISTÊNCIA É FUNDIDA NA CHAPA DE ALUMÍNIO SENDO IMPOSSÍVEL A TROCA APENAS DAS RESISTÊNCIAS , TEMOS TODAS AS PÇS DA PRENSA EM VALORES BEM ACESSÍVEIS. 
            [Produtosestoque] => 7
            [ProdutosfreteGratis] => s
            [Produtosbloqueado] => n
        )

When I see the source code, Ctrl+u, I have the following: inserir a descrição da imagem aqui I did not Ctr+C here because when I go to glue the spaces are disappearing. Note: Note that in printscream We have spaces in index names. But on the way out print_r there is no such space.

Well my question is this:.

I need to make one str_replace as a resource to exclude space in the names of the indexes below:

  var res1 =  Array(); 
  res1 = <?php echo str_replace("\u0000", "", json_encode($produto)); ?>;
  document.write(res1[0]["ProdutosidProduto"])

I would like to know if there is any recourse for such a manoeuvre not to be necessary.

Script output without the str_replace();

  var res1 =  Array(); 
  res1 = [{"\u0000Produtos\u0000idProduto":"1","\u0000Produtos\u0000tipo":"mp","\u0000Produtos\u0000modelo":"F540 2 BAN.PNEU. 100 X 60","\u0000P
  • You just want to take the spaces? a trim() doesn’t solve?

  • solve does not solve because technically there are NO spaces. Only in Ctr+u they exist. So what you have to remove is u000. But I believe that this should not be the most coherent way to proceed. I have tried to add headers, html and php, to UTF-8 and not solved.

  • Test this map: $keys = array_map('trim', array_keys($produto));$produto = array_combine($keys, $produto);

  • thanks @Edson Alves. The goal is to use only a charset header that gets me rid of these gabiarras. Understand? kkk. But since you don’t have it, I should continue with str_replace()

  • Strange that json_encode has threaded these spaces into its array. It seems that there is something modifying the Keys

  • that’s exactly what I intend to find out! As I already said, I’ve tried even using UTF-8 headers

  • This is the problem related to your previous question. These spaces are where the JSON parser is replacing the spaces with u0000. They are not visible in print_r, but in the source code yes.

Show 2 more comments

1 answer

2


The problem seems to be in the conversion to array, in the code:

$produto[] = (array) $cada

If you read the PHP documentation where you talk about arrays, more specifically in the session "Converting to Array" will notice that PHP has a different behavior when converting an object derived from a class that is not stdClass.

What happens is that PHP creates, for each object property, a key in the new converted array. But this key is prefixed with the null character (\0), the serialized class name and the properties name. Where:

  • public: does not change the name of the property. ex.:

    public $teste = 'valor';
    

    Becomes:

    'teste' => 'valor'
    
  • protected: prefix the property name with \0*\0 (null + * + null). Ex.:

    protected $teste = 'valor';
    

    Becomes:

    "\0*\0teste" => "valor"
    
  • private: prefix the property name with \0NomeClasse\0. Ex.:

    class MinhaClasse {
        private $teste = 'valor';
    }
    

    Becomes:

    "\0MinhaClasse\0teste" => "valor"
    

I understand it makes it easy to formulate a test to see what’s going on with your code:

<?php

class Teste
{
    public $prop_public;
    protected $prop_protected;
    private $prop_private;

    public function __construct()
    {
        $this->prop_public = 'public';
        $this->prop_protected = 'protected';
        $this->prop_private = 'private';
    }
}

$obj = new Teste;
$arr = (array) $obj;

print_r($arr);

foreach ($arr as $key => $value) {
    // converte \0 para \\0 para ficar visível
    $key_null = str_replace("\0", '\0', $key);
    echo "[$key_null] => $value\n";
}

Code running on Repl.it

Exit from print_r:

Array
(
    [prop_public] => public
    [*prop_protected] => protected
    [Testeprop_private] => private
)

Exit from echo:

[prop_public] => public
[\0*\0prop_protected] => protected
[\0Teste\0prop_private] => private

That way I know the properties of your class Produto sane private, and as shown in the above code, you can remove these null characters using:

str_replace("\0", '', $chave);

Note that double quotes should be used in \0 otherwise PHP escapes the backslash

If you are having problems with Unicode this reply from Soen does so:

str_replace('\\u0000', '', json_encode($var));

You could still check the library documentation you are using to access the DB and look for some method toArray(), or create it so you don’t have to do tricks to fix PHP’s tricks.

  • so I’m accessing with mysqli. I thought there was some resource to str_replace. Something like a utfg-8 header or something like that!

  • As the problem is in PHP, how PHP converts an object to an array. You could use mysqli_fetch_assoc to take as array instead of object.

  • But mysqli does not assign the result as private that I know of. You’re sure you don’t have a class of your own with these attributes like private?

  • I can not because I am not allowed to touch the source as it is only to meet the request of a mobile application! Even so, the entire site is done with objetc

  • yes, all my classes use private attributes and I make getAtributo() call to retrieve them

  • In the Repl.it I did I show how to replace the \0, just do it in your code if you can’t touch the rest.

  • is I know. But I was looking for some header myself. But since it doesn’t exist I’ll continue as I was just before the question

  • I don’t understand why you were looking for a header, it doesn’t make sense to me. No header can hide unwanted characters. Anyway, the answer answers the why of the strange characters and I ended up learning in the process of creating the answer as well. Good luck :D

  • header (, UTF-8) It’s not that it hides. But it fixes characters. But I’ll give your answer as accepted because it has a lot of useful content!

  • It "fixes" if you are having encoding problems. And your problem is another, so my question. But anyway, I’m glad I could help somehow.

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.