Ir para conteúdo

POWERED BY:

Arquivado

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

Thiago Dias_132983

Primeiro código em POO (QueryString) dicas

Recommended Posts

Eai galera, essa foi minha primeira tentativa no mundo POO, fiz esse código simples pra praticar oque aprendi até agora, gostaria da opinião/dicas de vocês oque estou errado e/ou oque devo continuar fazendo, agradeço à atenção.

<?php

class GetPage {

	private $dir;
	//diretório das páginas;
	private $param;
	//parâmetro GET;
	private $default;
	//página padrão;
	private $error;
	//página de erro;

	public function __construct($dir, $param, $default, $error) {

		$this -> dir = $dir . '/';
		$this -> param = $param;
		$this -> default = $default;
		$this -> error = $error;
		$this->VerificaParam();
	}

	public function VerificaParam() {

		if (!isset($_GET[$this -> param]) OR $_GET[$this -> param] == null) {

			$_GET[$this -> param] = $this -> default;

			include_once ($this -> dir . $this -> default . '.php');

		} elseif (!file_exists($this -> dir . $_GET[$this -> param] . '.php')) {

			include_once ($this -> dir . $this -> error . '.php');

		} else {

			include_once ($this -> dir . $_GET[$this -> param] . '.php');
		}

	}// FIM;

}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

É, ficou bem estranho. Mas isso é um sinal de que o código não está claro. Vamos lá.

 

 

class GetPage

 

Um nome de uma classe não deveria ser um verbo. Uma classe não representa uma ação, quem faz isso é um método.

 

 

	private $dir;
	//diretório das páginas;
	private $param;
	//parâmetro GET;
	private $default;
	//página padrão;
	private $error;
	//página de erro;

 

Você pode (e deve) usar docblocks ao invés de comentários para depois poder gerar documentação. Indo além, você poderia eliminá-los colocando nomes menos genéricos como pageDirectory, urlParam, defaultPage e errorPage, respectivamente.

 

 

		$this->VerificaParam();

 

Construtor, como o nome diz, serve para construir um objeto. Invocar um método é responsabilidade de quem usa a classe, não do construtor.

 

 

	public function VerificaParam() {

 

The book is on the table! Misturar dois idiomas não faz muito sentido na maioria dos casos e esse é um. CheckParam seria um nome mais adequado.

 

 

		if (!isset($_GET[$this -> param]) OR $_GET[$this -> param] == null) {

 

Não use as superglobais diretamente, o potencial de reutilização cai, testar em isolamento se torna impossível e o acoplamento aumenta.

 

Além disso, você deveria usar || e ===. Como uma alternativa simples, bastaria usar a função empty do próprio PHP.

 

 

			$_GET[$this -> param] = $this -> default;

 

Qual a intenção disso? Sobrescrever as superglobais não faz sentido.

 

 

			include_once ($this -> dir . $this -> default . '.php');

 

Aqui a confusão aumenta ainda mais. O que raios uma classe de query string tem a ver com inclusão de um arquivo?

 

 

		} elseif (!file_exists($this -> dir . $_GET[$this -> param] . '.php')) {

 

:seta: Open/Closed Principle.

 

 

	}// FIM;

 

O fechamento das chaves já diz que é o fim, código não é peça teatral :lol:.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agradeço pelas dicas, mas algumas coisas não ficaram muito claras pra mim, eu devo só retornar o nome do parâmetro/arquivo e incluir o mesmo fora da classe? e oque fazer no caso das superglobais?
e eu uso OR porque não sei o comando do pipe no windows rsrs, mas por que é melhor usar do outro jeito?

Agradeço pela atenção!

Compartilhar este post


Link para o post
Compartilhar em outros sites

e eu uso OR porque não sei o comando do pipe no windows rsrs, mas por que é melhor usar do outro jeito?

 

Por causa de precedência e convenção.

 

eu devo só retornar o nome do parâmetro/arquivo e incluir o mesmo fora da classe?

 

Qual a intenção da classe? Uma classe de query string não tem nada a ver com arquivos. Você está confundindo responsabilidades e pensando em código procedural.

 

e oque fazer no caso das superglobais?

 

Passar por parâmetro no construtor e quem sabe ter uma classe de Request para representar uma requisição.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Passar por parâmetro no construtor e quem sabe ter uma classe de Request para representar uma requisição.

 

Acho que não entendi direito, pode dar um exemplo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

De forma simples, sugiro mais ou menos isso aqui:

class Request {
    const QUERY = 'query';
    const POST = 'post';
    const COOKIE = 'cookie';

    private $queryParams = array();
    private $postParams = array();
    private $cookieParams = array();

    public function __construct(array $params = array()) {
        foreach ($params as $key => $p) {
            switch($key) {
                case self::QUERY:
                    $this->setupQuery($p);
                    break;
                case self::POST:
                    $this->setupPost($p);
                    break;
                case self::COOKIE:
                    $this->setupCookie($p);
                    break;
            }
        }
    }

    private function setupQuery(array $data) {
        foreach ($data as $key => $val) { 
            $this->queryParams[(string) $key] = (string) $data; //parâmetros de requisição sempre são strings
        }
    }

    private function setupPost(array $data) {
        // idem
    }

    private function setupCookie(array $data) {
        // idem
    }

    public function getQuery($var, $default = null) {
        $var = (string) $var;
        return array_has_key($var, $this->queryParms) 
            ? $this->queryParms[$var] 
            : $default;
    }

    public function getPost($var, $default = null) {
        // idem
    }


    public function getCookie($var, $default = null) {
        // idem
    }
}

Uso:

$request = new Request(array(
    Request::QUERY => array_filter($_GET),
    Request::POST => array_filter($_POST),
    Request::COOKIE => array_filter($_COOKIE),
));

var_dump($request->getQuery('page'));

P.S.: incluir páginas por meio de parâmetros na URL é uma PÉSSIMA prática, leva a falhas de segurança. Pesquise um pouco sobre URL routers.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pelo que eu entendi (acho), essa classe request pega todos os dados de GET/COOKIE/POST e joga num array? e depois eu devo passar o parâmetro que eu quero para minha outra classe de QueryString?

 

P.S.: incluir páginas por meio de parâmetros na URL é uma PÉSSIMA prática, leva a falhas de segurança. Pesquise um pouco sobre URL routers.


Henrique, mas se eu fizer a validação se o arquivo existe ou não já não é o bastante? vamos com calma que sou novato, rs.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Henrique, mas se eu fizer a validação se o arquivo existe ou não já não é o bastante? vamos com calma que sou novato, rs.

Não, pois [inline]file_exists[/inline] e mesmo [inline]is_file[/inline] são capazes de avaliar arquivos dentro de uma mesma rede. Se alguém tiver acesso à rede em que a sua aplicação roda, poderá injetar scripts maliciosos.

 

NUNCA, JAMAIS dê poder ao usuário.

Compartilhar este post


Link para o post
Compartilhar em outros sites

E minha outra dúvida:

 

Pelo que eu entendi (acho), essa classe request pega todos os dados de GET/COOKIE/POST e joga num array? e depois eu devo passar o parâmetro que eu quero para minha outra classe de QueryString?

 

A QueryString só faria então me passar os parâmetros GET já com todas as validações de segurança e por onde eu devo incluir o arquivo? devo criar outra classe só pra incluir a página?

Obrigado pela atenção!

Compartilhar este post


Link para o post
Compartilhar em outros sites

O maior erro seu é pensar em classes, e pior ainda pensar em procedimentos.

 

Ontem, o criador do Erlang falou uma coisa muito sábia: "OOP = mensagens + isolamento + polimorfismo + late binding, mas não classes + métodos, que são apenas organização de código.".

 

Tente se libertar do pensamento de classes e pensar em APIs e responsabilidades. O que você está tentando fazer? Quais são as funções? Como posso tornar isso reutilizável? Diferente do procedural, OO é algo abstrato, ou seja, requer um pensamento diferente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A QueryString só faria então me passar os parâmetros GET já com todas as validações de segurança e por onde eu devo incluir o arquivo? devo criar outra classe só pra incluir a página?

Mais uma vez: pesquise sobre URL routers...

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.