Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

fekz

[Resolvido] Visibilidade em PHP - OOP

Recommended Posts

Pessoal, estou fazendo uma classe e estou com um problema...

 

abstract class databaseManagement
{
	private $conexao;
	private $database;
	private $fields = array();
	private $resultado;
	private $numRows;
}

beleza, criei a classe filha, e que eu saiba, o private deixa a variável acessível somente dentro da classe.

 

eu instancia a nova classe e se faço assim: $usuario->numRows = 10, ele deixa eu mudar perfeitamente, WTF??

Se eu coloco protected, ele fica certo e não deixa eu acessar...

 

Agora, se eu ponho private e o negócio deixa eu acessar a variável pelo objeto direto, qual a vantagem??

Ou eu to fzndo alguma m*****???

 

Vlw, abraços.

Compartilhar este post


Link para o post
Compartilhar em outros sites

quando você define a propriedade como private ela não é herdada, o que quer dizer que qualquer classe concreta que herde a classe abstrata databaseManagement não possuirá nenhuma das propriedades especificadas

 

faça dois testes para você entender as diferenças de erros:

 

class testeA {

}

class testeB {
   private $valorOculto = 0;
}

$a = new testeA;
$b = new testeB;

 

No primeiro cenário vamos chamar uma variável inexistente:

echo $a->valorOculto;

 

Como retorno vem o seguinte erro:

Notice: Undefined property: testeA::$valorOculto in D:\documentos\www\new\index.php on line 13

enquanto no segundo cenário

echo $b->valorOculto;

 

O parser do PHP é bem claro quanto ao erro:

Fatal error: Cannot access private property testeB::$valorOculto in D:\documentos\www\new\index.php on line 15

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ela não herda apenas a visibilidade ou não herda a variável??

 

Porque eu instanciei a classe filha, e estou usando as variáveis $resultado e $numRows que estão sendo setadas apenas na classe abstrata.

 

Ai eu uso um método para setar e um para recuperar.

 

Então na classe mãe eu tenho

 

Classe login:

 

public class get( return $this->numRows );

 

Quando eu instancio e faço $login->numRows ele me retorna o número certinho...

 

Pelo que você falou, como eu recupero uma variável instanciando a clasee filha, se pelo que você explicou ela não existiria na classe filha? Ele cria sozinho já que eu estou setando?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você pode, no construtor da filha, popular as variáveis de acordo com a Pai (errado) ou definir as propriedades como protected (certo)

Compartilhar este post


Link para o post
Compartilhar em outros sites

@fekz,

 

Quando você define uma propriedade como privada em uma classe, nenhuma classe derivada irá herdar essa propriedade, ou seja, ela simplesmente não terá tal propriedade.

 

Se você quiser "barrar" acesso de propriedades inexistentes nas herdeiras, você pode utilizar os métodos mágicos__get() e __set(), ficaria assim:

 

class Object {
final public function __get( $name ){
	throw new RuntimeException( sprintf( 'Tentando recuperar o valor de uma propriedade inexistente' ) );
}

final public function __set( $name , $value ){
	throw new RuntimeException( sprintf( 'Tentando definir um valor em uma propriedade inexistente' ) );
}
}

abstract class AbstractTest extends Object {
private $myPrivateProperty;

public function mySetter( $value ){
	$this->myPrivateProperty = $value;
}

public function myGetter(){
	return $this->myPrivateProperty;
}

}

class ConcreteTest extends AbstractTest {
}

$teste = new ConcreteTest();
$teste->myPrivateProperty = 10;

var_dump( $teste );

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, João, eu entendi.

 

Mas pelo que você me disse a variável numRows por exemplo, não existe na classe que eu herdei da classe pai.

 

Certo?

 

Acontece que quando eu boto na classe dataBaseManagement, um método que me retorne

return $this->numRows

E estou na classe filha login, se eu fizer echo $login->numRows() ele me traz a variável correta.

 

Se ela não existe, já que eu não declarei na classe login, como ela pode ser recuperada?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Classe Pai:

<?

abstract class databaseManagement
{
	private $conexao;
	private $database;
	private $fields 	= array();
	private $resultado 	= array();
	private $numRows 	= 0;
	
	function __construct()
	{
		global $bdconfig;
		$bdconfig['server'] 	= 'localhost';
		$bdconfig['user'] 		= 'root';
		$bdconfig['pass'] 		= 'root';
		$bdconfig['database']	= '';
		
		if( !$this->conexao )
		{
			$this->conexao = mysql_connect
			(
			$bdconfig['server'], 
			$bdconfig['user'], 
			$bdconfig['pass'] 
			);			
		}
		
		if( !$this->database)
		{
			$this->database = mysql_select_db($bdconfig['database']);
		}
		
		$classObject    = new ReflectionClass(get_class($this));
		$field			= $classObject->getProperties();
				
		for($i=0; $i < count($field); $i++)
		{
			$key 		= $field[$i];
			$name 		= $key->getName();
			$this->setValue($i,$name);
		}
		
	} // Construct
	
	public function setValue($cont,$name)
	{
		$this->fields[$cont] = $name;
	}
	
	public function getValue($cont)
	{
		return $this->fields[$cont];
	}

	public function getTableName()
	{
		return get_class($this);
	}
	
	public function getQuery()
	{
		return $this->resultado;
	}
	
	public function setQuery( $arr )
	{
		$this->resultado = $arr;
	}
	
	public function numRows()
	{
		return $this->numRows;
	}
	
	public function setNumRows( $rows )
	{
		$this->numRows = $rows;
		return $this->numRows;
	}
	
	public function getData($arguments = array())
	{
	
		$fields 	= isset( $arguments['FIELDS'] ) 	? $arguments["FIELDS"] : "*" ;
		$innerjoin	= isset( $arguments['JOIN'] ) 		? $arguments["JOIN"] : "" ;
		$where 		= isset( $arguments['EXTRAWHERE'] ) ? $arguments["EXTRAWHERE"] : "" ;
		$orderby 	= isset( $arguments['ORDERBY'] ) 	? $arguments["ORDERBY"] : "" ;
		$limit 		= isset( $arguments['LIMIT'] ) 		? $arguments["LIMIT"] : "" ;
		
		if($innerjoin != "") $innerjoin = " " . $innerjoin;
		
		
		$sql = "SELECT $fields FROM " . $this->getTableName();
		
		if(!empty($innerjoin)) $sql .= $innerjoin;
		if(!empty($where)) $sql 	.= " WHERE $where";
		if(!empty($orderby)) $sql 	.= " ORDER BY $orderby";
		if(!empty($limit)) $sql 	.= " LIMIT $limit";
		
		$exec 	= mysql_query($sql);
		
		$this->setNumRows( mysql_num_rows($exec) );
		
		while( $res = mysql_fetch_assoc($exec) )
		{
			$obj[] = $res;
		}
		
		$this->setQuery($obj);
		return $this->getQuery();
	}
	
	
	public function getRecordValue($cont, $fieldName)
	{
		$rows		= $this->getQuery(); 
		$founded 	= $rows[$cont][$fieldName];
		if( count($founded) > 0 )
			return $founded;
		else
			throw new Exception('A linha ' . $cont . ' não foi encontrada');
	}
	
	public function getRow($cont)
	{
		$res = $this->getQuery();
		if($res[$cont] != "")
		{
			return $res[$cont];
		} else {
			throw new Exception('A linha ' . $cont . ' não foi encontrada');
		}
	}
	
	public function getItem( $id )
	{	
		if( !is_int( $id ) )
			throw new Exception("Argumento inválido! É necessário um argumento inteiro");		
		
		$this->getData(array(
		"EXTRAWHERE" => $this->getValue(0) . " = " . $id
		));
		
		$results = $this->getQuery();
		
		return $results;	
	}
		
}

Classe Filha:

 

class Login extends databaseManagement
{
	protected /** integer */ 	$id;
	protected /** string */ 	$nome;
	protected /** string */ 	$senha;	
	protected /** string */ 	$aprovado;
}

Agora se eu faço

 

$usuario = new Login();

$usuario->numRows = 10;

ou

$usuario->numRows()

 

 

A minha primeira dúvida é porque eu posso fazer isso: $usuario->numRows = 10;

se é private. Se for a explicação de que ela não cria na classe debaixo, então como ela existe no objeto $usuario que foi extendido da classe que tinha essa variável

 

Outra dúvida:

Eu fiz uma função para setar o número de linhas, e uma para retornar o número de linhas... e aí em qualquer lugar do código que eu chamar, volta o numero certo.

 

Se eu fizesse dentro de getData: $this->numRows = 10;

 

E tentasse pegar o $this->numRows em outro método, ele me retornava vazio, como se a variável só tivesse sido alterada no escopo do getData();

Compartilhar este post


Link para o post
Compartilhar em outros sites

faça o seguinte teste e creio que entenderá:

 

$teste = new Login;
$teste->numRows = 13;
var_dump($teste->numRows()); // int(0);

 

Se for a explicação de que ela não cria na classe debaixo, então como ela existe no objeto $usuario que foi extendido da classe que tinha essa variável

 

Quem te disse que ela existe? Já experimentou fazer isso aqui:

$teste = new Login;
var_dump($teste->numRows);

 

Notice: Undefined property: Login::$numRows in D:\documentos\www\iMasters\testes\heranca_classes.php on line 161

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho um disperdicio criar essa classe, e usar funções antigas e obsoletas em metodos novos, mesma coisa que usar remendo novo em roupa velha

 

porque nao usa Mysqli?, mysql_select_db é uma função obsoleta, e nao só ela todas mysql_ são obsoletas e ultrapassadas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

faça o seguinte teste e creio que entenderá:

 

$teste = new Login;
$teste->numRows = 13;
var_dump($teste->numRows()); // int(0);

 

Se for a explicação de que ela não cria na classe debaixo, então como ela existe no objeto $usuario que foi extendido da classe que tinha essa variável

 

Quem te disse que ela existe? Já experimentou fazer isso aqui:

$teste = new Login;
var_dump($teste->numRows);

 

Notice: Undefined property: Login::$numRows in D:\documentos\www\iMasters\testes\heranca_classes.php on line 161

 

Você falou que ao definir como private ele não era herdado pelas classes filhas ué.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é herdado, logo não existe =)

 

Não conseguiu entender ainda que são duas variáveis diferentes??

 

$teste->numRows = 10;

var_dump($teste->numRows); // int(10);

var_dump($teste->numRows()); // int(0);

No primeiro caso, você invoca uma variável CRIADA dentro da classe Login.

 

No segundo caso, você acessa o método numRows() dentro de databaseManagement, que por sua vez, mostra o resultado armazenado na classe abstrata.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.