AprendendoC Posted September 5, 2013 at 11:50 PM Report #523579 Posted September 5, 2013 at 11:50 PM (edited) buenas galera, tudo bom! bom tenho aqui umas classes que estou criando para aprender. classe de conexao com o banco de dados <?php class Conexao extends PDO { private $dataBase = 'mysql'; private $host = 'localhost'; private $dbName = 'nome_do_banco'; private $user = 'nome_usuario'; private $pass = 'senha_usuario'; static $conexao = NULL; public function __construct(){ try{ self::$conexao = parent::__construct($this->dataBase.':host='.$this->host.';dbname='.$this->dbName, $this->user, $this->pass); self::$conexao = parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); }catch(PDOException $e){ echo 'Erro ao se conectar a base de dados'.$e->getMessage(); } }// __construct public function __destruct(){ self::$conexao = NULL; }// __destruct public function insert($dados, $tabela){ //INSERT INTO tabela (campos) VALUES (valores) $sql = "INSERT INTO ".$tabela." ("; foreach($dados as $key => $value): $campos[] = $key; is_numeric($value) ? $valores[] = $value : $valores[] = "'".$value."'"; endforeach; $sql .= implode(", ", $campos).") VALUES (".implode(", ", $valores).")"; $query = $this->prepare($sql); $query->execute(); echo $sql; }// insert public function update($dados, $tabela){} public function select($dados, $tabela){} public function delete($dados, $tabela){} }// Conexao ?> classe Usuarios require_once("Conexao.class.php"); // estendo a classe usuarios da classe conexao para fazer as transaçoes com o banco. class Usuarios extends Conexao { private $nome; private $email; private $senha; public function setNome($nome){ $this->nome = $nome; }// setNome public function setEmail($email){ $this->email = $email; }// setEmail public function setSenha($senha){ $this->senha = $senha; }// setSenha public function getNome(){ return $this->nome; } public function getEmail(){ return $this->email; } public function getSenha(){ return$this->senha; } // criei essa funcao para inserir os dados no banco, chamando a funcao insert(classe da conexao) //não sei se é correto fazer isto, mas esta funcionando. public function inserir($dados, $tabela){ //pega as variaveis da classe e as coloca em um array $dados $dados = get_object_vars($dados); //chama a função insert da classe pai parent::insert($dados, $tabela); } } // Usuarios ?> teste.php onde faço os teste pra ver se esta funcionando <?php require_once("Usuarios.class.php"); $user = new Usuarios(); // insiro dados nas variaves da classe Usuarios $user->setNome("Testando as classses"); $user->setEmail("teste@teste.com"); $user->setSenha("12345"); // chamo a funcao inserir (classe usuarios) e passo pra ela o objeto criado da propria classe e // a tabela que desejo inserir os dados. // testei e está funcionando tudo certo, fez a inserção no banco de dados sem dar erro algum. $user->inserir($user, "tabela_usuarios"); ?> e ai pessoal nao sei se o que eu fiz está correto, pois estou fazendo para aprender... entao gostaria da opiniao dos mais experientes se está correto o que estou fazendo, se posso fazer assim, e sugestoes de melhorias. desde já agradeço a todos! Edited September 5, 2013 at 11:53 PM by AprendendoC
HappyHippyHippo Posted September 6, 2013 at 06:46 AM Report #523587 Posted September 6, 2013 at 06:46 AM ora bem ... tens aqui pano para mangas ... 1º - Se queres ter esse tipo de relação entre classes, então a classe Conexao deverá ser abstracta sendo impossível instânciar-la por si só: $conexao = new Conexcao(); // <-- isto é possivel nesse código. deverias tornar a função __construct protegida para que isso não aconteça e possa ser chamada pela classe derivada <?php class A { protected function __construct() { echo "__construct class A<br />"; } } class B extends A { // é obrigatório ter esta função porque senão o construtor da classe A será chamado // no entanto, como é protegido, vai dar bronca ao tentar instânciar a classe B public function __construct() { parent::__construct(); // não esquecer de chamar o construtor da classe A (isto não é C++ ou Java, tens de fazer à mão) echo "__construct class B<br />"; } } $obj1 = new B(); // __construct class A // __construct class B $boj2 = new A(); // ERRO : impossível instâncias a classe ?> 2º - as funções CRUD da classe Conexao, não fazem sentido serem públicas. o que achas que faz sentido : $obj = new Usuarios(); // esta ? $obj->insert(array("id", 1), "my table"); // ou esta ? $obj->insert(array("id", 1)); a primeira até poderia bem dar bronca se te enganasses a colocar o nome da tabela ... o que deverias fazer seria alterar o nivel de acesso das funções CRUD da classe Conexao protegidas e teres funções frontend na classe Usuarios class Conexao { protected function insert($dados, $tabela) { // ... } } class Usuarios { static protected $tabela = "tbl_usuarios"; // eu explico a palavra "static" mais à frente public function insert($dados) { parent::insert($dados, self::$tabela); } } 3º - apesar do ponto anterior estar a funcionar, a própria maneira como a função se apresenta não faz muito sentido ... pensa bem, estás a manusear um objecto, não vais estar a dizer a um objecto para inserir outro pois não ? $user1 = new Usuarios(); $user2 = new Usuarios(); $user1->inserir($user2); // <-- pedir a "user1" para inserir "user2" ??? pois bem, a função inserir (e afins) não deveriam ter o parâmtro dados, porque é suporto serem acções sobre os dados da classe/objecto instânciado class Usuarios { static protected $tabela = "tbl_usuarios"; // eu explico a palavra "static" mais à frente public function insert() { parent::insert(get_object_vars($this), self::$tabela); } public function update() { parent::insert(get_object_vars($this), self::$tabela); } } $user = new Usuarios(); // ... $user->insert(); // inserir a si próprio na base de dados // ... $user->update(); // actualizar os seus próprios dados na base de dados 4º - vamos supor que é para usar o modelo apresentado. o que acontece se tiveres duas instâncias da classe Usuarios ? $user1 = new Usuarios(); $user2 = new Usuarios(); - quantas ligações à base de dados existem ? - e se tiveres outro tipo de dados que deriva também de Conexao ? - e quantas instâncias desses outros tipos de dados irás ter ? - quantas ligações irâo ser no final ? estás a ver o problema ? pois é ... é por isso que não se faz assim. tens duas soluções: - fazes a convencial separação dos classes guardando uma referência da classe Conexao na class Usuarios class Conexao { public function __construct() { // terá de ser publica porque terás de instâncias a classe } } class Usuarios { protected $conexao; public function __construct($conexao) { $this->conexao = $conexao; } } $conexao = new Conexao(); $user1 = new Usuarios($conexao); $user2 = new Usuarios($conexao); como podes ver, agora só existirá uma ligação à base de dados tens ainda uma outra solução mais engraçada, que é a combinação de um design pattern chamadoSingleton com a derivação convencional do OOP. algo semelhante ao teu código, mas com algumas alterações <?php class Conexao { static protected $conexao = null; // nota no uso da palavra reservada "static", é uma variável de classe e não de instância da classe // isto quer dizer que é transversal a todas as instâncias da classe protected function __construct() { if (self::$conexao == null) { // verificar se a ligação à base de dados já foi efectuada // nota : usar sempre o "self::" para referênciar a variável !!! // caso contrário, uma nova variável local com o mesmo nome será criada echo "connetion initialization<br />"; // ... } } protected function conexao() { return self::$conexao; // não esquecer do "self::" } } class Usuarios extends Conexao { public function __construct() { parent::__construct(); // <-- não esquecer !!! } } $user1 = new Usuarios(); // vai criar a ligação à base de dados $user2 = new Usuarios(); // este já não vai criar a ligação à base de dados ?> 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Rui Carlos Posted September 6, 2013 at 08:40 AM Report #523595 Posted September 6, 2013 at 08:40 AM Parece-me que o 3º e 4º problemas apontados no post anterior se devem ao facto de se estar a misturar um objecto com a lista de objectos. Rui Carlos Gonçalves
taviroquai Posted September 6, 2013 at 09:26 AM Report #523618 Posted September 6, 2013 at 09:26 AM <?php require_once("Usuarios.class.php"); $user = new Usuarios(); $user->setNome("Testando as classses"); $user->setEmail("teste@teste.com"); $user->setSenha("12345"); $user->inserir($user, "tabela_usuarios"); ?> @AprendendoC O que queres fazer chama-se de ORM, ou seja, queres ter um objecto que represente um utilizador (usuario) e queres que esse objeto possa ser inserido/guardado/apagado de uma base de dados relacional. Eu também já fiz uma ORM apenas para Mysql e também já existem algumas ORMs para PHP e digo-te que são todas de alguma complexidade... Se fosse eu a fazer, não tornava a classe Usuario extensão da Classe conexão. Na classe Usuario adicionava propriedades de metadados para indicar à classe Conexao algumas informações necessárias para saber guardar os dados. Podias ter uma API assim: <?php $usuario = new Usuario(); $usuario->setNome('bla'); $usuario->setMetaTable('tbl_usuarios'); // Algumas ORMs nem precisam disto porque fazem a sua própria gestão de nomes de tabelas... // Até aqui tens um simples objecto independente de bases de dados // Agora se quiseres o CRUD... $orm = new Conexao('pdo string...'); $orm->save($usuario); // isto serve tanto para inserir (se não existir) como para alterar $orm->delete($usuario); // isto serve para apagar $orm->find('tbl_usuarios', ' email like ?', array('%@teste.com%')); // faz um select e devolve objectos Usuario com os metadados
yoda Posted September 6, 2013 at 04:00 PM Report #523683 Posted September 6, 2013 at 04:00 PM (edited) Talvez assim fosse mais simples : <?php $user = new User; $user->name = 'Testando as classses'; $user->email = 'teste@teste.com'; $user->password = '12345'; $user->update(); class User extends ORM {} // User extende ORM que tem os métodos insert, select, delete, .. class ORM extends PDO {} // ORM extende PDO para interacção directa com a base de dados ?> Edited September 6, 2013 at 04:08 PM by yoda before you post, what have you tried? - http://filipematias.info sense, purpose, direction
AprendendoC Posted September 6, 2013 at 11:18 PM Author Report #523739 Posted September 6, 2013 at 11:18 PM @HappyHippyHippo @Rui Carlos @taviroquai @yoda Muito obrigado pelas opiniões e dicas, vou estudar e implementar o restante me baseando nas explicações de vocês!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now