Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde pessoal.
Aqui no forum já tem um mesmo post com este nome. Mas não resolveu o meu problema.
O que acontece é que estou tentando fazer o seguinte:
Tenho um objeto com nome Produto. Tenho uma sessão que grava todos os produto com o nome $_SESSION['produto'].
Gravo os ids dos produtos que estão na sessão no indice produto.
O que acontece é que quando tento verificar se a sessão produto já tem o indice com o id do produto é printado este erro: Fatal error: Cannot use object of type Produto as array in 'caminho do arquivo de manipulação'
O mais intrigante é que isso só acontece no servidor linux. Pois localmente utilizando o wamp está funcionando normalmente.
Em código o que estou tentando fazer é o seguinte: if(!$_SESSION["produto"][$produto->getId_produto()])
Onde $produto contem o objeto produto. E o metodo getId_produto me retorna a propriedade id_produto.
O que pode está havendo?
public function insert($carrinho) {
$return = array();
$mysql = new GDbMysql();
$mysql->execute("SELECT qtd_estoque FROM produto WHERE id_produto = " . $carrinho->getId_produto());
$mysql->fetch();
if($mysql->res["qtd_estoque"] >= $carrinho->getQtd()){
if(!$_SESSION["carrinho"][$carrinho->getId_produto()]){
$_SESSION["carrinho"][$carrinho->getId_produto()] = serialize($carrinho);
$return["status"] = true;
$return["msg"] = "Aguarde...";
}else{
$return["status"] = false;
$return["msg"] = "Estoque indisponível. Desculpe.";
}
return $return;
}Você pode postar a classe Produto para darmos uma olhada, porém esse você pode obter mais informações diretas sobre esse erro para, quem sabe, até solucionar sozinho, através das respostas dadas nesse tópico em particular os posts #10 e #12).
Se não entender alguma coisa que eu escrevi, avise.
Segue todo o codigo. Na verdade é um carrinho...
Gostaria de pedir aos moderadores exclusão do post ou pelo menos código após solução pois é um projeto com código e informações privadas.
GF::import(array("carrinho")); //Isso chama o objeto
$carrinho = new Carrinho();
$carrinho->setId_produto($_POST['id']);
$carrinho->setNome($_POST['nome']);
$carrinho->setValor($_POST['valor']);
$carrinho->setQtd(1);
$carrinho->setTotal($_POST['valor']);
$carrinhoDao = new CarrinhoDao();
$retorno = $carrinhoDao->insert($carrinho);
/** @param Carrinho $carrinho */
public function insert($carrinho) {
$return = array();
$mysql = new GDbMysql(); //Isso chama instancia de bano mysql
$mysql->execute("SELECT qtd_estoque FROM produto WHERE id_produto = " . $carrinho->getId_produto());
$mysql->fetch();
if($mysql->res["qtd_estoque"] >= $carrinho->getQtd()){
if(!$_SESSION["carrinho"][$carrinho->getId_produto()]){
$_SESSION["carrinho"][$carrinho->getId_produto()] = serialize($carrinho);
$return["status"] = true;
$return["msg"] = "Aguarde...";
}else{
$return["status"] = false;
$return["msg"] = "O produto que você selecionou já está em seu carrinho de compras.<br>Para adicionar outra unidade, altere a quantidade do produto.";
}
}else{
$return["status"] = false;
$return["msg"] = "Estoque indisponível. Desculpe.";
}
return $return;
}
Este é o objeto
<?php
class Produto{
private $id_produto;
/ @var $subcategoria_produto Subcategoria_produto /
private $subcategoria_produto;
/ @var $fabricante Fabricante /
private $fabricante;
/ @var $marca Marca /
private $marca;
/ @var $tamanho Tamanho /
private $tamanho;
/ @var $cor Cor /
private $cor;
private $nome;
private $codigo;
private $peso;
private $frete_gratis;
private $qtd_estoque;
private $garantia;
private $valor;
private $valor_promocao;
private $valor_estoque;
private $resumo;
private $descricao;
private $destaque;
private $ativo;
private $data_alteracao;
private $id_usuario_alteracao;
public function getId_produto() {
return $this->id_produto;
}
public function setId_produto($id_produto) {
$this->id_produto = $id_produto;
}
/** @return Subcategoria_produto */
public function getSubcategoria_produto() {
return $this->subcategoria_produto;
}
/** @param Subcategoria_produto $subcategoria_produto */
public function setSubcategoria_produto($subcategoria_produto) {
$this->subcategoria_produto = $subcategoria_produto;
}
/** @return Fabricante */
public function getFabricante() {
return $this->fabricante;
}
/** @param Fabricante $fabricante */
public function setFabricante($fabricante) {
$this->fabricante = $fabricante;
}
/** @return Marca */
public function getMarca() {
return $this->marca;
}
/** @param Marca $marca */
public function setMarca($marca) {
$this->marca = $marca;
}
/** @return Tamanho */
public function getTamanho() {
return $this->tamanho;
}
/** @param Tamanho $tamanho */
public function setTamanho($tamanho) {
$this->tamanho = $tamanho;
}
/** @return Cor */
public function getCor() {
return $this->cor;
}
/** @param Cor $cor */
public function setCor($cor) {
$this->cor = $cor;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function getCodigo() {
return $this->codigo;
}
public function setCodigo($codigo) {
$this->codigo = $codigo;
}
public function getPeso() {
return $this->peso;
}
public function setPeso($peso) {
$this->peso = $peso;
}
public function getFrete_gratis() {
return $this->frete_gratis;
}
public function setFrete_gratis($frete_gratis) {
$this->frete_gratis = $frete_gratis;
}
public function getQtd_estoque() {
return $this->qtd_estoque;
}
public function setQtd_estoque($qtd_estoque) {
$this->qtd_estoque = $qtd_estoque;
}
public function getGarantia() {
return $this->garantia;
}
public function setGarantia($garantia) {
$this->garantia = $garantia;
}
public function getValor() {
return $this->valor;
}
public function setValor($valor) {
$this->valor = $valor;
}
public function getValor_promocao() {
return $this->valor_promocao;
}
public function setValor_promocao($valor_promocao) {
$this->valor_promocao = $valor_promocao;
}
public function getValor_estoque() {
return $this->valor_estoque;
}
public function setValor_estoque($valor_estoque) {
$this->valor_estoque = $valor_estoque;
}
public function getResumo() {
return $this->resumo;
}
public function setResumo($resumo) {
$this->resumo = $resumo;
}
public function getDescricao() {
return $this->descricao;
}
public function setDescricao($descricao) {
$this->descricao = $descricao;
}
public function getDestaque() {
return $this->destaque;
}
public function setDestaque($destaque) {
$this->destaque = $destaque;
}
public function getAtivo() {
return $this->ativo;
}
public function setAtivo($ativo) {
$this->ativo = $ativo;
}
public function getData_alteracao() {
return $this->data_alteracao;
}
public function setData_alteracao($data_alteracao) {
$this->data_alteracao = $data_alteracao;
}
public function getId_usuario_alteracao() {
return $this->id_usuario_alteracao;
}
public function setId_usuario_alteracao($id_usuario_alteracao) {
$this->id_usuario_alteracao = $id_usuario_alteracao;
}
}Como eu imaginava, a resposta acima cabe perfeitamente ao seu problema.
Poxa cara não consegui entender. E na verdade postei o objeto errado. A classe que estou usando é essa:
<?php
class Carrinho{
public $id_produto;
public $nome;
public $valor;
public $qtd;
public $total;
public function getId_produto() {
return $this->id_produto;
}
public function setId_produto($id_produto) {
$this->id_produto = $id_produto;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function getValor() {
return $this->valor;
}
public function setValor($valor) {
$this->valor = $valor;
}
public function getQtd() {
return $this->qtd;
}
public function setQtd($qtd) {
$this->qtd = $qtd;
}
public function getTotal() {
return $this->total;
}
public function setTotal($total) {
$this->total = $total;
}
}
Esqueça a classe de produtos.
O que exatamente você não conseguiu entender?
O erro que você está recebendo ocorrer porque você não pode usar um objeto como array, principal, mas não exclusivamente, quanto ao uso da sintaxe de colchetes.
Os links postados demonstram que você pode forçar o cast para array como medida paliativa de acesso, não de manipulação.
E também apresenta a interface ArrayAccess que quando imlementa num objeto qualquer permite justamente que ele possa ser usado como array.
Você tem duas alternativas: Ou faz o cast em TODA classe que utilizar a classe Produtos ou implemente ArrayAccess nela e não mude mais nada.
Ok.
Porque em minha máquina funciona e no servidor não? Tem alguma configuração que posso colocar no servidor pra funcionar?
O servidor, 99% possui a configuração mais adequada e por isso códigos mal escritos ou que não atentaram para detalhes sutis, quando online deixam de funcionar.
Por isso que sempre recomendo iniciar o desenvolvimento com (e lá vou eu mais uma vez):
ini_set( 'display_errors', TRUE );
error_rerporting( E_ALL | E_STRICT ); // PHP 5.3
error_rerporting( E_ALL ); // Todas as outras versões
>
Como eu imaginava, a resposta acima cabe perfeitamente ao seu problema.
Apertei negativar sem querer. Desculpe!
Bom dia de domingo.
Bruno, o código abaixo continua dando o mesmo erro:
$carrinhoArray = (array) $carrinho;
if($mysql->res["qtd_estoque"] >= $carrinho->getQtd()){
if(!$_SESSION["carrinho"][$carrinhoArray['id_produto']]){
$_SESSION["carrinho"][$carrinhoArray['id_produto']] = serialize($carrinho);
$return["status"] = true;
$return["msg"] = "Aguarde...";
}else{
$return["status"] = false;
$return["msg"] = "O produto que você selecionou já está em seu carrinho de compras.<br>Para adicionar outra unidade, altere a quantidade do produto.";
}
}
Se eu der um var_dump em $carrrinhoArray ele informa que o elemento é um array. Só que o código que está vendo ai, continua apresentando o mesmo erro. Já tentei fazer o type cast apenas para a propriedade do objeto mas continua dando o mesmo erro.
Fatal error: Cannot use object of type Produto as array in 'caminho do arquivo de manipulação'
Leia novamente o erro que você recebeu.
Apesar de você achar que é (post #7), não é a classe Carrinho o problema. E sim a Produto.
Se observar uma observação minha vai ver que falei que na verdade não era produto. E sim carrinho. Segue erro novamente:
Fatal error: Cannot use object of type Carrinho as array in loja/painel/class/carrinhoDao.php on line 64
Esse fragmento de código acima é o código de carrinhoDao.php ou este é outro arquivo?
pergunto isso pois dada a simplicidade da classe Carrinho, convertê-la para array já seria suficiente. E se você fez isso e não deu certo, pode existir outra chamada à essa mesma classe em outro lugar.
Em todo caso, experimentou implementar ArrayAccess?
>
Se observar uma observação minha vai ver que falei que na verdade não era produto. E sim carrinho. Segue erro novamente:
Fatal error: Cannot use object of type Carrinho as array in loja/painel/class/carrinhoDao.php on line 64
Você disse que havia postado a classe errada. Assumi que se referia ao código.
Mas você não disse que a mensagem de erro também refletia essa outra classe. ;)
Este bloco é do carrinhoDao. E o erro é exatamente nesta linha:
if(!$_SESSION["carrinho"][$carrinhoArray['id_produto']]){
E o que fiz exatamente isso:
$carrinhoArray = (array) $carrinho;
Onde $carrinho contem o objeto carrinho.
Pelo visto você não quer mesmo mexer com ArrayAccess né? ^_^
Dê um var_dump() / print_r(0 em $carrinhoArray e poste o retorno, então.
Array
(
[id_produto] => 12
[nome] => VIDEO PORTEIRO COLORIDO 3,5
[valor] => 290.00
[qtd] => 1
[total] => 290.00
)
Como te falei. É um array. :)
Nossa que sinistro isso. Eu estou testando e tudo funciona normalmente.
Experimenta implementar a interface ArrayAccess na classe Carrinho. Se você não sabe fazer, eis uma implementação meio grosseira que fiz aqui rapidinho:
class Carrinho implements ArrayAccess {
// ...
public function offsetExists( $offset ) {
return ( property_exists( $this, $offset ) );
}
public function offsetGet( $offset ) {
return ( property_exists( $this, $offset ) ? $this -> {$offset} : NULL );
}
public function offsetSet( $offset, $value ) {
$this -> {$offset} = $value;
}
public function offsetUnset( $offset ) {
if( property_exists( $this, $offset ) ) {
unset( $this -> {$offset} );
}
}
// ...
}
$carrinho = new Carrinho;
$carrinho -> id_produto = 12;
$carrinho -> nome = 'Video Porteiro Colorido 3,5';
$carrinho -> valor = 290;
$carrinho -> qtd = 1;
$carrinho -> total = 290;
$cArray = (array) $carrinho;
print '<pre>';
print_r( $carrinho );
print_r( $cArray );
var_dump( $carrinho['id_produto'], $cArray['id_produto'] );
Sem implementar os quatro métodos, recebi o mesmo erro ao usar $carrinho['id_produto']. Porém, $cArray que está só com o cast funcionou tranquilamente, mostrando 12 na tela.
Assim que tais métodos são implementados, tanto usando a notação de propriedades quanto de colchetes, funciona.
Se com você não funcionar ainda assim, já que suas propriedades estão erroneamente definidas como públicas, acesse-as diretamente:
if( ! $_SESSION['carrinho'][ $carrinho -> id_produto ] ){
Ou através do getter desnecessário:
if( ! $_SESSION['carrinho'][ $carrinho -> getId_produto() ] ){
Cara este problema está consumindo minha vida!
Primeiro fiz a correção das propriedades. Já haviam me falado só que eu precisava ver funcionando primeiro pra mostrar pro cliente. Fiz na correria mas agora está ok. As propriedades estão privadas.
O interessante é que após alterar as propriedades o erro não mais aconteceu. Só que agora estou com o seguinte problema:
As informações do meu carrinho ficam numa session onde a chave é o id do produto e o valor são informações do produto serializadas. Fica da seguinte forma:
Array
(
[12] => O:8:"Carrinho":5:{s:20:"Carrinhoid_produto";s:2:"12";s:14:"Carrinhonome";s:27:"VIDEO PORTEIRO COLORIDO 3,5";s:15:"Carrinhovalor";s:6:"290.00";s:13:"Carrinhoqtd";i:1;s:15:"Carrinhototal";s:6:"290.00";}
)
Só que agora está acontecendo de quando eu entro no foreach acontece isso com minha session:
Carrinho Object
(
[id_produto:private] => 12
[nome:private] => VIDEO PORTEIRO COLORIDO 3,5
[valor:private] => 290.00
[qtd:private] => 1
[total:private] => 290.00
)
Ou estou com muito sono e desgasto fisico e mental, pois estou neste projeto desde sabado e o domingo o dia todo, ou, não estou prestando atenção a detalhes.
Não consegui trabalhar com essa representação serializada pois ela não de-serializa (erro de offset).
Mas conseguir reproduzir de outra forma. Essa definição contendo private:nome_da_propriedade está correta. É assim que as propriedades private e protected aparecem quando o objeto que as contém é visualizado com print_r() / var_dump()
Uma vez que você tenha esse objeto de-serializado numa variável, basta invocar os getters apropriados.
Sinceramente acho que vou escrever outro carrinho ou mudar a forma que estou gravando na array.
O que está acontecendo é que por algum motivo eu estou deixando de ter esse string serializada e ela está virando um objeto inteiro na session.
Dada a quantidade assombrosa de problemas eu também sugiro isso pois se você tentar apenas encontrar o erro, pode não entender o porquê e se der algo parecido vai perder muito mais tempo.
Cara adivinha o que era que estava acontecendo?
As variaveis declaradas com nome $carrinho na página carrinho, e no arquivo carrinhoDao estavam sobrepondo a session.
Não sei por qual motivo. Mas era o que estava acontecendo.
É brincadeira pessoal?
Nunca ouvi dizer que variaveis declaradas num arquivo comum sobrepõe a a sessão.
Mas enfim. Eis um novo (creio que) bug do PHP e a solução de problemas parecidos.
Acho que não detectamos esse problema devido a ausência de código.
Nos ativemos muito ao fragmento relacionado à mensagem de erro em si ao invés de externar mais o problema.
Porém, não creio que isso seja um bug do PHP e sim uma mostra de que, talvez, você precise melhorar a forma como seus arquivos e as classes deles estejam sendo incluídos.
Pode, inclusive, ser a hora perfeita para você introduzir namespaces na sua aplicação e, assim, evitar esse tipo de colisão (mesmo que namespaces por si só não evitem colisão de variáveis).
Ok amigo. Muito obrigado pelas informações. E agradeço por toda dedicação durante a tentativa de busca pela solução do problema.
Amigo, poste o código para darmos uma olhada.
Abraços.