Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Amigos, criei uma classe pra criar XML a partir de uma consulta ao banco de dados.
Acontece que pra modularizar a coisa eu faço 2 fetches em dois métodos diferentes, mas pra isso copio o resultado da consulta pra poder usar cada um em um método diferente.
public function criarXMLComMidiasDaPlaylist($id_playlist){
$resultado = $this->buscarMidiasPlaylist($id_playlist);
$this->armazenarIdPlaylist($resultado); // aqui acontece um FETCH em $resultado
$this->criarNosXML($resultado, 'midia'); // aqui acontece um FETCH em $resultado
$this->criarArquivoXml();
}
Bom, ele não deveria ter criado em memória duas variáveis diferentes? Uma para cada método?
O que acontece é que, quando eu faço esse armazenarIdPlaylist e dou um feth dentro dele, o PHP faz um pop nesse $resultado, ai quando passo pra outra função ele tem menos 1 posição (só acontece um fetch na primeira função, e acontecem N fetches na segunda onde N é o número de registros no resultado).
pelo menos é isso que parece que tá acontecendo. sabem dizer do que se trata?
Abraços
cara, eu até imaginava ser isso, como disse no meu post.
mas eu nao concordo que funcione assim. quando a gente joga pra uma outra função/método ele deveria criar uma nova varíavel na memória. ou isso ou to deixando passar algum detalhe de POO. tipo declarar algo como estático, por exemplo.
>
Bom, ele não deveria ter criado em memória duas variáveis diferentes? Uma para cada método?
não, a variavel foi passada por referência. Por isso é a mesma variavel, e não uma outra 'clone' como você supõe que deveria ser(e resolveria o teu problema).
>
cara, eu até imaginava ser isso, como disse no meu post.
mas eu nao concordo que funcione assim. quando a gente joga pra uma outra função/método ele deveria criar uma nova varíavel na memória. ou isso ou to deixando passar algum detalhe de POO. tipo declarar algo como estático, por exemplo.
Concordo com você. Mas há tempos já tive problema assim e para não me estressar fiz o que eu havia dito - e funcionou.
Abraço!
Montei um exemplinho aqui:
<?php
$mysqli = new mysqli('localhost','root','123','cms');
$sql = "SELECT * FROM usuario";
$query = $mysqli->query( $sql );
var_dump( $query );
//object(mysqli_result)#2 (0) { }
$query2 = clone $query;
var_dump( $query2 );
/*
Fatal error: Trying to clone an uncloneable object of class mysqli_result
in D:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\index.php on line 10
*/
echo '<br />Loop 1:';
$i = 0;
while( $dados = $query->fetch_object() ){
echo $dados->nome,'<br />';
}
$query->data_seek( 0 );// http://www.php.net/manual/pt_BR/mysqli-result.data-seek.php
echo '<br />Loop 2:';
$i = 0;
while( $dados = $query->fetch_object() ){
echo $dados->nome,'<br />';
}
já que você quer fazer OO, então considere parar de usar a extensão mysql_, migre para mysqli
Não entendi William. É como se você clonasse o "fetch" dizendo pra não tirar o último registro feito? (Falando isso na prática).
Não, o clone não funciona, só quis demostrar isso. Tentei clonar o resource da consulta. O fetch só fiz depois.
a solução verdadeira é o data_seek()
Tem algo equivalente em PDO, WB? Procurei aqui mas fiquei perdido nos links.
Abraços!
Pra fazer um rewind no resultado do PDO eu acho que só com iterator.
Então, vejamos, vocês já devem ter visto alguns outros parâmetros no fetch ..
andrey@andrey:~$ cd ~
andrey@andrey:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.1.49-1ubuntu8.1 (Ubuntu)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create schema exemplo;
Query OK, 1 row affected (0.00 sec)
mysql> use exemplo;
Database changed
mysql> create table tbl(
-> id int( 11 ) not null
-> )engine = memory;mysql> insert into tbl values( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 );
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from tbl;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
6 rows in set (0.00 sec)
PHP:
<?php
$PDO = new PDO( 'mysql:host=localhost;dbname=exemplo', 'root', '...' );
$query = $PDO->prepare( 'SELECT * FROM `tbl`' );
$query->execute();
print_r( $query->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, -1 ) );
Saída:
andrey@andrey:~$ php -f /var/www/index.php
Array
(
[id] => 1
)Dessa forma, não tem iteração, então ...
andrey@andrey:~$ cat /var/www/index.php
<?php
$PDO = new PDO( 'mysql:host=localhost;dbname=exemplo', 'root', '...' );
$PDO->setAttribute( PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL );
$query = $PDO->prepare( 'SELECT * FROM `tbl`' );
$query->execute();
$Data = $query->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST );
do{
print_r( $Data );
}while( $Data = $query->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR ) );
andrey@andrey:~$ php -f /var/www/index.php
Array
(
[id] => 1
) [id] => 2
) [id] => 3
) [id] => 4
) [id] => 5
) [id] => 6
);)
Cara, isso é um problema muito comum na programação. Já passei MUIIIIITA dor de cabeça por isso.
O que acontece é que, o que elimina esse seu um registro, são os "dois" fetches. Você eliminando um deles, tudo ocorre normalmente.
Uma solução - desagradável, mas simples - para se resolver isso é criando duas querys com o mesmo conteúdo e fazendo dois fetches paralelos com as querys diferentes.
Tente.
Abraços! ;)