Ir para conteúdo

POWERED BY:

Arquivado

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

guih_oliveira10

nota para minha classe

Recommended Posts

olá pessoal,

 

estou há muito tempo estudando e muito PHP.

estou gostando muito de programar PHP OO, e estou desenvolvendo uma class, e gostaria que vcs dessem uma nota e dicas, sugestões.

 

muito obrigado

 

principal.class.php

<?php	

class principal extends mysql{

//Algumas configurações
protected static $errorLocation = 'erro.php';
private static $error_file      = 'log_error.txt';
private static $diretos   = array('index.php');
private static $indiretos = array('principal.class.php');

//Função a ser executada ao iniciar a classe
public function __construct(){

	if(self::perms($_SERVER['SCRIPT_NAME'],'1')){

		parent::conectar();

	}else{

		self::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'22','');

	}

}

//Função a ser execultada quando terminar a execução
public function __destruct(){

	parent::close_conn();

}

//Função que trata os erros
public static function errorLog($errorCod,$errorMsg,$errorFile,$errorLine,$errorContext){

	$error_arq = fopen(self::$error_file,'a');

	$errorData = date('d/m/Y') . ' às ' . date('H:i:s');
	$errorIp   = $_SERVER['REMOTE_ADDR'];

	if(empty($errorContext)){

		$context = '';

	}else{

		$context = "($errorContext)";

	}

	$erro = "Erro[$errorCod]: $errorMsg (Caminho: $errorFile) (Linha: $errorLine) $context (Data: $errorData) (IP: $errorIp) \r\n\r\n";

	fwrite($error_arq,$erro);
	fclose($error_arq);

	header('Location: ' . self::$errorLocation);

}

//Função que verifica se o arquivo tem as permissões corretas
function perms($arqNome,$tipoAcesso){

	$arqNome = explode('/',$arqNome);

	if($tipoAcesso == '1'){

		if(in_array($arqNome[1],self::$diretos) AND !in_array($arqNome[1],self::$indiretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}elseif($tipoAcesso == '2'){

		if(in_array($arqNome[1],self::$indiretos) AND !in_array($arqNome[1],self::$diretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}

}

}

class mysql{

//Configurações da conexão MYSQL
private $host  = '127.0.0.1';
private $user  = 'root';
private $senha = '';
private $db    = 'teste';

//Definições de variáveis
private $conn;
public $sql;

//Função a ser executada ao iniciar a classe
public function __construct(){

	new principal;

}

//Função a ser execultada quando terminar a execução
public function __destruct(){

	$this->close_conn();

}

protected function conectar(){

	$this->conn = mysql_connect($this->host,$this->user,$this->senha) or die(parent::errorLog('2',mysql_error(),'C:\Program Files (x86)\EasyPHP-5.3.8.1\www\teste.class.php','98',''));
	mysql_select_db($this->db,$this->conn) or die(parent::errorLog('2',mysql_error(),'C:\Program Files (x86)\EasyPHP-5.3.8.1\www\teste.class.php','99',''));

}

//Função para fechar a conexão MYSQL
protected function close_conn(){

	if($this->conn != NULL){

		unset($this->sql);
		mysql_close($this->conn);

	}

}

//Função anti-injection SQL
public function anti_injection($sintese){

	$sintese = preg_replace("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/i",'',$sintese);
	$sintese = strip_tags($sintese);
	$sintese = trim($sintese);

	if(!get_magic_quotes_gpc()){

		$sintese = mysql_real_escape_string($sintese,$this->conn);

	}

	return $sintese;

}

//Função que executa uma query no MYSQL
public function query($s){

	return $this->sql = mysql_query($s,$this->conn);

}

}

//Seta o nome da função para tratar errors
set_error_handler("principal::errorLog");

?>

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você está gostando de PHP OO, mas de forma errada .. cara tem muita coisa que podia alterar aí, até mesmo porque, não vi o motivo do extends ..sem falar de coisa desnecessária aí no teu código .. o método conectar, pode ser um método publico, alias .. eu acho que deve, pois você pode querer abrir a conexão somente para execução de uma query .. então, ele com protected, você fica na dependência de uma herança .. ou seja, já começa com o pé esquerdo ou ( direto ) se você é canhoto .

 

Outra coisa desnecessária, é esse método anti_injection .. qual a razão disso ? porque você remove keywords sql da string ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você está gostando de PHP OO, mas de forma errada .. cara tem muita coisa que podia alterar aí, até mesmo porque, não vi o motivo do extends ..sem falar de coisa desnecessária aí no teu código .. o método conectar, pode ser um método publico, alias .. eu acho que deve, pois você pode querer abrir a conexão somente para execução de uma query .. então, ele com protected, você fica na dependência de uma herança .. ou seja, já começa com o pé esquerdo ou ( direto ) se você é canhoto .

 

Outra coisa desnecessária, é esse método anti_injection .. qual a razão disso ? porque você remove keywords sql da string ?

 

muito obrigado pelas dicas, usei o extends pra separar as duas classes, pois já quis começar pensando alto, num site que pode vir ser maior, não sei em questão de desempenho, mais em organização ajuda. Alias, qual a finalidade da palavra 'extends'???

 

o anti_injection e para evitar hackers invadirem via SQL-INJECTION , gera mais segurança ao site, as vezes eu exagero nessa parte.

 

Outro ponto à melhorar, é não usar a função nativa do PHP mysql, mas sim a classe PDO.

 

Essa classe realmente não conheço ainda, já ouvi falar, so que não tive a curiosidade de aprender ainda, vou estudar mais sobre ela

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

usei o extends pra separar as duas classes, pois já quis começar pensando alto

Francamente, isso não é pensar alto, nem baixo, e sim pensar bonito .. cara .. herança nisso aí não tem nada haver .. esquece ! heranças são aplicáveis em casos por exemplo : Membro , Moderador , Administrador

 

<?php

         class Member {

                public function post (  ) { }

                public function edit (  ) { }

         }

         class Moderator extends Member {

                public function delete ( ) { }

                public function setAsSolved( ) { }

         }

         class Administrator extends Moderator {

                public function setAsModerator ( ) { }

                public function setAsAdministrator ( ) { }

                public function setLockedDate (  ) { }                 
         }

         $Administrator = new Administrator ( ) ;
         print_r( get_class_methods ( $Administrator ) ) ;

         $Moderator = new Moderator ( ) ;
         print_r( get_class_methods ( $Moderator ) ) ;

         $Member = new Member ( ) ;
         print_r( get_class_methods ( $Member ) ) ;

 

Saída:

Array
(
   [0] => setAsModerator
   [1] => setAsAdministrator
   [2] => setLockedDate
   [3] => delete
   [4] => setAsSolved
   [5] => post
   [6] => edit
)
Array
(
   [0] => delete
   [1] => setAsSolved
   [2] => post
   [3] => edit
)
Array
(
   [0] => post
   [1] => edit
)

 

num site que pode vir ser maior, não sei em questão de desempenho, mais em organização ajuda.

Desempenho não depende da keyword que você usa para herdar uma classe, e sim do código escrito

 

Alias, qual a finalidade da palavra 'extends'???

Herança ..

 

o anti_injection e para evitar hackers invadirem via SQL-INJECTION , gera mais segurança ao site, as vezes eu exagero nessa parte.

Isso não resolve teu problema .. tem injections de vários tipos .. afinal é um assunto bem discutido e indeterminado, podem existir injections de vários e vários tipos .. isso aí ajuda no injection mais tradicional que é o das aspas, .. e remover keywords sql de um texto é a pior coisa a se fazer, pra não dizer que é porco e feio fazer isso ..

Compartilhar este post


Link para o post
Compartilhar em outros sites

shereck olha esse material :seta: http://php.net/manua...nguage.oop5.php

 

 

obrigado, vou dar uma olhada no material

 

realmente não pensava isso de PHP OO, kkkkkkk

vou dar uma estudada mais aprofundada, acho que me preocupo muito com questões de segurança, estava dando uma olhada na parte:

 

//Função que verifica se o arquivo tem as permissões corretas
function perms($arqNome,$tipoAcesso){

	$arqNome = explode('/',$arqNome);

	if($tipoAcesso == '1'){

		if(in_array($arqNome[1],self::$diretos) AND !in_array($arqNome[1],self::$indiretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}elseif($tipoAcesso == '2'){

		if(in_array($arqNome[1],self::$indiretos) AND !in_array($arqNome[1],self::$diretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}

}

 

 

 

e vi que posso fazer essa proibição atraves do .htaccess , mais simples.

 

não sei porque essa minha aptidão por segurança, acho que me espelho muito nesses grandes sites como Facebook, Goolge+, etc.

 

alias, alguém tem alguma classe bem programada de exemplo pra me mostrar?

 

muito obrigado pela ajuda de vocês

 

 

<?php

         class Member {

            	public function post (  ) { }

            	public function edit (  ) { }

         }

         class Moderator extends Member {

            	public function delete ( ) { }

            	public function setAsSolved( ) { }

         }

         class Administrator extends Moderator {

            	public function setAsModerator ( ) { }

            	public function setAsAdministrator ( ) { }

            	public function setLockedDate (  ) { }             	
         }

         $Administrator = new Administrator ( ) ;
         print_r( get_class_methods ( $Administrator ) ) ;

         $Moderator = new Moderator ( ) ;
         print_r( get_class_methods ( $Moderator ) ) ;

         $Member = new Member ( ) ;
         print_r( get_class_methods ( $Member ) ) ;

 

Saída:

Array
(
   [0] => setAsModerator
   [1] => setAsAdministrator
   [2] => setLockedDate
   [3] => delete
   [4] => setAsSolved
   [5] => post
   [6] => edit
)
Array
(
   [0] => delete
   [1] => setAsSolved
   [2] => post
   [3] => edit
)
Array
(
   [0] => post
   [1] => edit
)

 

 

muito bom esse exemplo Andrey

Compartilhar este post


Link para o post
Compartilhar em outros sites

vi dizer por ai, que o uso de PHP OO é somente para projetos maiores, para projetos menores e melhor usar programação estruturada, isso procede?

 

e outra coisa, pra que serve a palavra 'final' nos métodos da class?

Compartilhar este post


Link para o post
Compartilhar em outros sites

e gostaria que vcs dessem uma nota e dicas, sugestões.

 

Okay amigo,

 

Como você, deliberadamente, pediu para que dessem nota, vou ser absolutamente sincero:

 

principal.class.php

 

Já começou errado, o nome da classe deve representar o que ela faz, deve ser curto e objetivo para que a pessoa que ler o nome já tenha ideia do que ela faz.

 

Principal não diz absolutamente nada sobre essa classe, por isso você deve começar a correção por ai.

 

protected static $errorLocation = 'erro.php';
private static $error_file      = 'log_error.txt';
private static $diretos   = array('index.php');
private static $indiretos = array('principal.class.php');

 

Qual o sentido dessas propriedades serem estáticas?

 

	
	if(self::perms($_SERVER['SCRIPT_NAME'],'1')){

		parent::conectar();

	}else{

		self::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'22','');

	}

 

Cuidado ao utilizar a super global $_SERVER, ela representa o servidor que hospeda a aplicação e, não necessariamente, possuirá as mesmas chaves em todos os servidores.

 

//Função a ser execultada quando terminar a execução
public function __destruct(){

	parent::close_conn();

}

 

E se a conexão não tiver sido aberta?

 

public static function errorLog($errorCod,$errorMsg,$errorFile,$errorLine,$errorContext){

 

Isso é uma violação explícita do princípio da responsabilidade única, não deve ser responsabilidade dessa classe lidar com manipulação de arquivo e gravação de logs.

 

public function __construct(){

	new principal;

}

 

Isso é uma violação explícita do princípio da inversão de dependências: Dependa de abstrações não de implementações.

 

Sem contar que principal deriva dessa classe. :ermm:

 

//Função a ser execultada quando terminar a execução
public function __destruct(){

	$this->close_conn();

}

 

E se a conexão não tiver sido aberta?

 

	
	$sintese = preg_replace("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/i",'',$sintese);

 

Isso sai um pouco fora do escopo da avaliação da classe (que é o que você pediu para fazer), mas é um erro tremendo esse tipo de implementação.

 

Alias, qual a finalidade da palavra 'extends'???

 

A palavra chave extends está relacionada com herança de classes. Usamos herança para escrever subclasses, reaproveitando implementação.

 

Basicamente uma subclasse é uma derivação de uma classe base, ou seja, Banana é uma classe derivada de Fruta.

 

Quanto ao objetivo do post, não vou dar uma nota pois acho que você precisa melhorar muitas coisas na sua classe, mas vá postando suas modificações gradativamente que vamos analisando seu progresso.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá pessoal,

 

 

estive pensando muito esses dias, e fiz alguma alterações na minha classe, muitas na verdade kkkk.

 

 

Criei uma classe para tratar só erros e a outra que tem o objetivo de tratar MYSQL.

 

 

Sei que já existem as classes PDO / MySQLi que são muito boas, mais quero fazer uma classe que aborda MYSQL pois acho mais fácil a interpretação da minha parte.

 

 

mysql.class.php

<?php

require('erro.class.php');

class mysql{

//Algumas configurações
private static $diretos = array('index.php');
private static $indiretos = array('mysql.class.php');

//Configurações da conexão MYSQL
private $host  = '127.0.0.1';
private $user  = 'root';
private $senha = '';
private $db    = 'teste';

//Definições de variáveis
private $conn;
public $sql;

//Função a ser executada ao iniciar a classe
public function __construct(){

	if(self::perms($_SERVER['SCRIPT_NAME'],'1')){

		$this->conectar();

	}else{

		parent::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'30','');

	}

}

//Função a ser execultada quando terminar a execução
public function __destruct(){

	$this->close_conn();

}

//Função que verifica se o arquivo tem as permissões corretas
public static function perms($arqNome,$tipoAcesso){

	$arqNome = explode('/',$arqNome);

	if($tipoAcesso == '1'){

		if(in_array($arqNome[1],self::$diretos) AND !in_array($arqNome[1],self::$indiretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}elseif($tipoAcesso == '2'){

		if(in_array($arqNome[1],self::$indiretos) AND !in_array($arqNome[1],self::$diretos) AND file_exists($arqNome[1])){

			return true;

		}else{

			return false;

		}

	}

}

public function conectar(){

	if($this->conn == NULL){

		$this->conn = mysql_connect($this->host,$this->user,$this->senha) or die(parent::errorLog('2',mysql_error(),'membros.class.php','80',''));
		mysql_select_db($this->db,$this->conn) or die(parent::errorLog('2',mysql_error(),'membros.class.php','81',''));

	}

}

//Função para fechar a conexão MYSQL
public function close_conn(){

	if($this->conn != NULL){

		unset($this->sql);
		mysql_close($this->conn);

	}

}

//Função anti-injection SQL
public function anti_injection($sintese){

	$sintese = strip_tags($sintese);
	$sintese = trim($sintese);

	if(!get_magic_quotes_gpc()){

		$sintese = mysql_real_escape_string($sintese,$this->conn);

	}

	return $sintese;

}

//Função que executa uma query no MYSQL
public function query($s){

	return $this->sql = mysql_query($s,$this->conn);

}

}

?>

 

 

 

erro.class.php

<?php	

class erro{

//Algumas configurações
private static $errorLocation = 'erro.php';
private static $error_file = 'log_error.txt';

//Função que trata os erros
public static function errorLog($errorCod,$errorMsg,$errorFile,$errorLine,$errorContext){

	$error_arq = fopen(self::$error_file,'a');

	$errorData = date('d/m/Y') . ' às ' . date('H:i:s');
	$errorIp   = $_SERVER['REMOTE_ADDR'];

	if(empty($errorContext)){

		$context = '';

	}else{

		$context = "($errorContext)";

	}

	$erro = "Erro[$errorCod]: $errorMsg (Caminho: $errorFile) (Linha: $errorLine) $context (Data: $errorData) (IP: $errorIp) \r\n\r\n";

	fwrite($error_arq,$erro);
	fclose($error_arq);

	header('Location: ' . self::$errorLocation);

}

}

//Seta o nome da função para tratar errors
set_error_handler("erro::errorLog");

?>

 

 

 

acho que não é necessário a criação de uma classe só para tratar erros, podia ser uma simples function, mais quero postar cada progresso meu, assim cada vez vai ficando mais fácil deu entender.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vou citar alguns fragmentos de um texto de Robert "UncleBob" Martin, leia atentamente o que ele disse:

 

O que é design orientado a objetos? Sobre o que é isso tudo? Quais são seus benefícios? Quais são seus custos? Pode parecer bobagem fazer essas perguntas em uma época em que praticamente todos os desenvolvedores estão usando uma linguagem, de alguma forma, orientada a objetos. No entanto, a questão é importante porque, parece-me, que a maioria de nós estamos usando essas linguagens sem saber porquê e sem saber como obter o máximo de benefício delas.

 

...

 

Programas escritos nessas linguagens podem parecer estruturados e orientados a objetos, mas as aparências enganam. Muitas vezes os programadores hoje em dia ignoram o fato de que os princípios que são a base das disciplinas em que essas linguagens foram construídas.

 

...Os princípios, no entanto, o foco é fortemente na gestão de dependência.

 

Gestão de dependência é uma questão que a maioria de nós temos enfrentado. Sempre que trazemos em nossas telas até um lote desagradável de código legado, estamos experimentando o resultado de uma gestão de dependência pobre. Má gestão de dependência leva a um código que é difícil mudar, frágil, e não reutilizável. Na verdade, eu falo sobre os vários diferentes cheiros de design no livro PPP, todos relacionadas com a gestão de dependência. Por outro lado, quando as dependências são bem geridas, o código permanece flexível, robusto e reutilizável.

 

Perceba que "UncleBob" fala sobre diversos cheiros de design orientado a objetos, Martin Fowler também tratou disso quando escreveu todo um capítulo sobre "Maus Cheiros" no código.

 

Logo no início desse capítulo do livro Refactoring, ele cita uma discussão filosófica:

 

If it stinks, change it.

—Grandma Beck, discussing child-rearing philosophy

 

Vamos lá:

 

<?php		
//Configurações da conexão MYSQL
private $host  = '127.0.0.1';
private $user  = 'root';
private $senha = '';
private $db    = 'teste';

 

"Bad Smell" detected. :sick:

 

Perceba que, sempre que você for usar esses dados, você os utilizará em conjunto. Outro ponto é que, cada vez que você trocar de host, você precisará editar essa classe para ajustar as configurações.

 

Uma classe deve ser fechada para edição, ou seja, você não deve escrever uma classe que precisará ser editada.

 

Você precisa extrair esses dados dai. Passe esses dados como parâmetro, seja na forma de objeto de configuração de conexão ou como parâmetros do método de conexão.

 

class mysql{

//Algumas configurações
private static $diretos = array('index.php');
private static $indiretos = array('mysql.class.php');

  //Função que verifica se o arquivo tem as permissões corretas
public static function perms($arqNome,$tipoAcesso){

 

"Bad Smell" detected. :sick:

 

Aqui você está dando mais responsabilidades à sua classe do que ela deve ter. Você deve extrair da sua classe mysql essa verificação de permissões.

 

//Função a ser executada ao iniciar a classe
   	public function __construct(){

           	if(self::perms($_SERVER['SCRIPT_NAME'],'1')){

                   	$this->conectar();

           	}else{

                   	parent::errorLog('2','Esse arquivo não pode ser  acessado por este modo',$_SERVER['SCRIPT_NAME'],'30','');

           	}

   	}

 

"Bad Smell" detected. :sick:

 

Esse construtor pode ser totalmente removido. Deixe o método conectar() ser acessado pela interface da classe, é mais barato assim. Também não é responsabilidade dele verificar se o arquivo está sendo chamado diretamente.

 

Como as únicas duas coisas que seu construtor faz, não deveriam estar ai, ele pode ser completamente removido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Qual o resultado que você espera do seguinte trecho de código no construtor?

parent::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'30','');

:ermm:

Compartilhar este post


Link para o post
Compartilhar em outros sites

@sherek,

 

você pode continuar do jeito que está, não tem problema.. mas lá na frente, um dia você vai se deparar com "as escolhas do passado" e amargar arrependimentos..

 

estude e faça da forma mais correta possível e, aproveite que tem um monte de fera aí disposto a ajudar..

;)

 

 

nota para a sua classe.. zero rsss :D

nota para as modificações: -10

 

e aí? quer aprender ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Perceba que, sempre que você for usar esses dados, você os utilizará em conjunto. Outro ponto é que, cada vez que você trocar de host, você precisará editar essa classe para ajustar as configurações.

 

Uma classe deve ser fechada para edição, ou seja, você não deve escrever uma classe que precisará ser editada.

 

Você precisa extrair esses dados dai. Passe esses dados como parâmetro, seja na forma de objeto de configuração de conexão ou como parâmetros do método de conexão.

 

 

realmente não deve-se fazer uma classe que precisará ser editada, acabei de ler isso em uma apostila que estou estudando e quando vim ver as respostas, deparei com a mesma frase sua. Captado laugh.gif

 

 

Aqui você está dando mais responsabilidades à sua classe do que ela deve ter. Você deve extrair da sua classe mysql essa verificação de permissões.

 

 

Realmente percebi isso, vou fazer essa verificação através do .htaccess

 

 

 

Esse construtor pode ser totalmente removido. Deixe o método conectar() ser acessado pela interface da classe, é mais barato assim. Também não é responsabilidade dele verificar se o arquivo está sendo chamado diretamente.

 

Como as únicas duas coisas que seu construtor faz, não deveriam estar ai, ele pode ser completamente removido.

 

 

Interface da classe? Se for o que eu estou pensando entendi.

Alias, alguém tem algum exemplo realmente Útil de uso do __construct

 

 

 

 

 

Qual o resultado que você espera do seguinte trecho de código no construtor?

parent::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'30','');

:ermm:

 

gravar em um log de erros kkkkkk cool.gif

desnecessário neh

 

 

 

 

@sherek,

 

você pode continuar do jeito que está, não tem problema.. mas lá na frente, um dia você vai se deparar com "as escolhas do passado" e amargar arrependimentos..

 

estude e faça da forma mais correta possível e, aproveite que tem um monte de fera aí disposto a ajudar..

;)

 

 

nota para a sua classe.. zero rsss :D

nota para as modificações: -10

 

e aí? quer aprender ?

 

estou cuidando disso, kkkk estudando muito

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

gravar em um log de erros kkkkkk cool.gif

desnecessário neh

 

Sim, mas você acha que este parent aí, vai se transformar em que?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, mas você acha que este parent aí, vai se transformar em que?

 

vai chamar a função dentro da classe erro.

 

o parent está no código pois no primeiro exemplo que postei, a classe erro era extends da mysql, mais mudei o código e esqueci de trocar por:

 

 

erro::errorLog('2','Esse arquivo não pode ser acessado por este modo',$_SERVER['SCRIPT_NAME'],'30','');

 

 

 

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.