• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

Visibilidade dinâmica de variáveis em OOP

17 mensagens neste tópico

Eu não faço ideia se isto é possível e algo me diz que não, mas como ninguém sabe tudo, o melhor que tenho a fazer é perguntar :)

class Teste {
private $abc;

public function __construct() {
	$this->abc = "A-B-C";
	$this->xyz = "X-Y-Z";
}
}

$Teste = new Teste();

echo $Teste->xyz; // Funciona: Variavel automaticamente declarada como publica
echo $Teste->abc; // Nao funciona: Variavel esta declarada como privada

Pergunta:

Sem declarar explicitamente na classe a variável $xyz, é possível que esta fique automaticamente como privada em vez de ficar pública?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bom que saiba não por defeito a variável é public depois podes dar a visibilidade que queres.

Se queres que a variável seja acedida de forma public mas para modificar seja private podes fazer um método getABC() public que retorna o valor da variável e assim podes aceder ao ser valor mas não modificar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois, mas isso não me serve de nada...

A ideia é criar várias variáveis com nomes dinâmicos (conforme necessário) e para isso não as posso declarar antes porque tanto pode ser uma, como duas ou mais e com diversos nomes, logo, nunca sei ao certo o que declarar. E precisava que elas ficassem como privadas e não publicas.

Poderia existir uma opção qualquer para mudar o comportamento pre-definido, em vez de tornar todas as variáveiss não declaradas (ou sem visibilidade definida) automaticamente como publicas, tornava-as privadas.

Dava mesmo jeito isso...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes sempre usar variáveis ditas 'normais', sem ter o $this->var, podes por só $var

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas isso vai tornar a variável local, apenas acessível dentro da função onde foi inicializada e eu quero que seja global à classe.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É um padrão que nunca usei e nem o conheço bem, mas pesquisa por uma coisa chamada class factory

Acho que é pode ser usado para solucionar este tipo de problema

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes declarar uma array como privada e lá metes as variáveis. Exemplo:

class ola {
    private $vars = array();
    function declarar_var($nome, $valor){
        $this->vars[$nome] = $valor;
        return true;
    }
    function get_var($nome){
        return (empty($this->vars[$nome]) ? NULL : $this->vars[$nome]);
    }
}

$ola = new ola;
$ola->declarar_var('lolada', array("panascas" => array("Nazgulled", "rolando2424")));
var_dump($ola->get_var('lolada'));

Acho que percebes a ideia. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@pedrotuga

Já fiz busca sobre isso mas não consigo encontrar nada que me ajude a resolver este problema...

@djthyrax

Achas que para uma solução tão básica como essa eu tinha criado um tópico? Not the solution I'm looking for...  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Achas que para uma solução tão básica como essa eu tinha criado um tópico?

Nunca se sabe, não eras o primeiro a quem uma coisa "tão básica como essa" não lhe tinha ocorrido. :)
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Modéstia à parte, é raro esse tipo de cenas básicas me acontecer. Até porque o que tu sugeriste, não é uma solução para o problema é mais uma fora de dar a volta ao problema... E eu pa dar a volta aos problemas, safo-me, mas não é isso que eu quero, quero é resolver o problema :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem esse é um problema... estranho :), não conheço soluções OO para esse problema, na verdade não conheço solução nenhuma tida como boa.

A única forma de ver isso feito é +/- como o djthyrax disse, no meu caso usava outra estrutura, mas isso deve ser por estar pouco habituado a PHP e mais a outras linguagens menos permissivas.

Em vez das duas funções iria usar apenas umas, mas no fundo a solução passaria por colocar as "variáveis" numa estrutura de dados que me permitisse relacionar o nome com o valor.

Sinceramente não vejo outra forma, não conheço um padrão de desenho que permita fazer isso, o Factory é destinado à criação de objectos que cuja forma de criação não é conhecida à partida e não para criar variáveis "dinâmicas"...

Mas a forma como o djthyrax disse resolve o problema e não cria mais problemas, se bem que são necessários mais alguns cuidados, mas numa primeira análise não vejo problemas em usar essa solução.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas a forma como o djthyrax disse resolve o problema e não cria mais problemas, se bem que são necessários mais alguns cuidados, mas numa primeira análise não vejo problemas em usar essa solução.

Tas a confundir, eu nunca disse que a solução apresentada trazia problemas ou whatever... Apenas é o tipo de solução que eu não quero, porque não é uma solução, é dar a volta ao problema. A ideia final ia ser ter de executar linhas como:

$this->Template->TemplateLoad()

$this->Global->FuncaoXYZ()

E ter algo assim:

$this->whatever['Template']->TemplateLoad()

$this->whatever['Global']->FuncaoXYZ()

Para mim, é uma solução parva para o que eu quero fazer e menos legível. Parece programação feita às 3 pancadas e eu não gosto.

De qualquer forma arranjei outra solução:

A ideia inicial de fazer isto é porque (tomando o exemplo do primeiro post) as variáveis $abc e $xyz iriam ser repetidas por varias classes e em todas elas deveriam ser privadas, alem disso, o construtor de todas estas classes também seria comum, completamente igual. De momento tenho 2 variáveis, abc e xyz, mas e se tivesse mais? Era parvo estar a repetir declarações de variáveis por cada classe e eu queria evitar isso, declarando as variáveis em run-time quando fossem definidas, o problema disto é que ficam como pública e eu não quero.

A solução passou por algo muito básico que eu não sei porque raio não pensei nisto antes. Que foi, criar uma classe à parte (A), onde declaro uma única vez essas variáveis privadas e ainda, coloco lá o construtor que será também como. Depois, em cada uma das outras classes, bastava fazer extend à classe A e pronto. A única diferença é que nada pode estar declarado como privado, mas sim protegido. E como vocês devem perceber porquê eu não vou explicar.

Problem solved.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

[...] A solução passou por algo muito básico que eu não sei porque raio não pensei nisto antes. [...]

Percebes agora porque eu tinha postado aquela solução básica? :D

Em relação ao protegido, explica-me que eu não sei mt de OOP.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas uma coisa é solução básica de mais e dar a volta ao problema. A minha solução é básica, mas não tanto como o que sugeriste e eu não dou a volta ao problema, resolvo-o. :D

$this->Whatever['Template']->TemplateLoad() - sucks ass

$this->Template->TemplateLoad() - r0xs ass

private = apenas visivel dentro da classe em que foi definida

protected = apenas visivel dentro da classe em que foi definida e da classe "parente" (n sei se é este o nome que se dá em português)

public = visivel em todo o lado

Percebes porquê que usei protected em vez de private? Até porque private, provoca erros e não me deixa aceder à variável :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Apesar de já teres encontrado uma solução e provavelmente a minha solução não ser a melhor para o teu problema mesmo assim vou sugerir uma que encontrei :D

<?php

class Teste {
        private $abc;

        public function factory( $var, $visibility, &$property ) {

                $factory = '$class = new factory(); class factory extends Teste { '. $visibility .' $'. $var .'; function __construct() { return $this; } }';

                eval( $factory );

                $property = $class;
        }

        public function __construct() {

                $this->abc = "A-B-C";

                $this->factory( 'xyz', 'private', $call ); //declara a varivel xyz como private 

                $call->xyz = "X-Y-Z";
        }
}

$Teste = new Teste();

echo $Teste->xyz; //Não mostra
echo $Teste->abc; //Nao mostra

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Thanks, mas para o que eu queria fazer, esse tipo de solução também é para a dar volta ao problema e complica de mais o que eu quero fazer. Alias, eu ate prefiro a solução que arranjei ao contrário daquela a que estava à procura...

@djthyrax

No exemplo que tava a fazer para ti, surgiu-me um problema, vou pro noutro topico, vê lá pa teres uma ideia e depois alguém que perceba + do que eu de OOP (nunca usei muito em PHP), irá perceber onde está o problema.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora