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

Sign in to follow this  
Nazgulled

Visibilidade dinâmica de variáveis em OOP

Recommended Posts

Nazgulled

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?

Share this post


Link to post
Share on other sites
magician

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.


I haven’t lost my mind; it’s backed up on DVD somewhere!

Share this post


Link to post
Share on other sites
Nazgulled

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

Share this post


Link to post
Share on other sites
karva

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


Proud LEIC-A@IST student!

Share this post


Link to post
Share on other sites
Nazgulled

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.

Share this post


Link to post
Share on other sites
pedrotuga

É 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

Share this post


Link to post
Share on other sites
djthyrax

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


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
Nazgulled

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

Share this post


Link to post
Share on other sites
djthyrax

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

Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
Nazgulled

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

Share this post


Link to post
Share on other sites
Knitter

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.

Share this post


Link to post
Share on other sites
Nazgulled

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.

Share this post


Link to post
Share on other sites
djthyrax

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


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
Nazgulled

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

Share this post


Link to post
Share on other sites
djthyrax

Uhm, podes dar-me um exemplo em código mesmo?


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
kingless

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

Share this post


Link to post
Share on other sites
Nazgulled

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.