Ir para conteúdo

Pesquisar na Comunidade

Mostrando resultados para as tags ''oop''.

  • Pesquisar por Tags

    Digite tags separadas por vírgulas
  • Pesquisar por Autor

Tipo de Conteúdo


Todas as áreas do Fórum

  • Q&A Desenvolvimento
    • Perguntas e respostas rápidas
  • Desenvolvimento e Banco de Dados
    • HTML e CSS
    • Java
    • Javascript
    • .NET
    • PHP
    • Python
    • Ruby
    • Mobile
    • Ambientes de Desenvolvimento
    • Arquitetura e Métodos Ágeis
    • Banco de Dados
    • DevOps
    • Desenvolvimento de Games
    • E-Commerce e Pagamentos Online
    • SEO e Otimizações
    • WordPress
    • Algoritmos & Outras Tecnologias
  • Design e Produto
    • Fotografia
    • Photoshop
    • Design de interfaces e UX
    • Edição/Produção de Vídeos
    • Marketing Online
    • Desenho, Ilustração e 3D
  • Entretenimento e uso pessoal
    • Geral
    • Segurança & Malwares
    • Gadgets e wearable
    • Softwares e Apps
    • Entretenimento

Encontrar resultados em...

Encontrar resultados que...


Data de Criação

  • Início

    FIM


Data de Atualização

  • Início

    FIM


Filtrar pelo número de...

Data de Registro

  • Início

    FIM


Grupo


Google+


Hangouts


Skype


Twitter


deviantART


Github


Flickr


LinkedIn


Pinterest


Facebook


Site Pessoal


Localização


Interesses

Encontrado 16 registros

  1. Rodrigo5468

    Validação em PDO OOP

    Boa tarde a todos. Estou desenvolvendo um sistema de registro para fins de estudos, mas tenho algumas dúvidas e dificuldades até. Estou usando "programação orientada a objetos", e quero validar alguns campos do meu registro, se puderem me auxiliar, será de grande ajuda. Meu Diretório: Projeto1/ ├── backend/ │ ├── classes/ │ │ ├── Register.php ├── index.php Em Register.php tenho o seguinte código para fazer a validação, mas acredito que estou fazendo algo de errado. public function setUsername($username) { $sql = "SELECT * FROM $this->table WHERE username = :username"; $stmt = Database::prepare($sql); $stmt->execute(array('username' => $_POST["username"])); if(empty($_POST["username"])) { return "O campo usuário não pode ser vázio."; }elseif(ctype_space($_POST["username"])) { return "Não pode usar apenas espaços no campo de usuário."; }elseif(strlen($_POST["username"] < 3)) { return "É necessário no mínimo 3 (três) caracteres no usuário."; }elseif(strlen($_POST["username"] > 15)) { return "O máximo é de 15 (quinze) caracteres no usuário."; }elseif(preg_match("/^[a-zA-Z0-9]*$/", $_POST["username"] == 0)) { return "O nome de usuário só pode conter letras e números. (sem espaços e sem caracteres epeciais)"; }elseif($stmt->num_rows !== 0) { return "O nome de usuário já está cadastrado em nossos bancos de dados."; }else { $this->username = $username; } } E no index.php tenho o seguinte código, acredito que está certo, mas eu gostaria de mostrar as mensagens de erros que estão no Register.php, como que posso fazer isso? $register = new Registers(); if(isset($_POST["cadastrar"])) { $username = $_POST["username"]; $email = $_POST["email"]; $password = $_POST["password"]; $register->setUsername($username); $register->setEmail($email); $register->setPassword($password); if($register->insert()) { return "Usuário cadastrado com sucesso."; } } Obrigado pela atenção!
  2. dayenne

    AGENDA EM JAVA DUVIDAS

    Galera então é o seguinte, tenho um trabalho da faculdade para fazer porém ainda não entendo quase nada de java, to meio perdida no trabalho. o trabalho propoe que eu faça uma agenda de contatos, onde eu possa armazenar contatos, excluir contatos, pesquisa-los, edita-los, tudo isso usando arquivos txt, porém não consigo de jeito nenhum sair da estaca 0, queria que você me orientasse melhor para que eu consiga flluir melhor os codigos.
  3. Olá galera, eu estou tendo um problema que está me aflingindo muito, nunca vi algo assim, eu estou desenvolvendo algumas classes para trabalhar com WordPress e estou usando Output Buffering para gerar as saidas dos meus templates em meus plugins, porem, estou enfrentando um problema quando tento executar um método render de um mesmo tipo, o que acontece é que o PHP me retorna uma string vazia apos a chamada da primeira instancia. View.php: <?php namespace App\Core; class View { /** * Renderiza uma view * @param string $path * @param array $data */ public static function render($path, $data = []) { ob_start(); extract($data); include_once ROOT_PATH . '/views/' . $path . '.php'; return ob_get_clean(); } } Input.php <?php namespace App\Core\Fields; use App\Core\Field; use App\Core\View; class Input implements Field { ... public function render() { return View::render('fields/input', [ 'key' => $this->getKey(), 'label' => $this->getLabel(), 'type' => $this->getType(), 'value' => $this->getValue() ]); } } O código client: $f1 = new Input('athlete_address', 'Endereço', 'text'); $f2 = new Input('athlete_birthdate', 'Data de nascimento', 'date'); $f1->render(); // Retorna saida normal $f2->render(); // Retorna string vazia Porém se eu fizer assim... $select = (new Select('athlete_category', 'Categoria')) ->addOption('Open', 'Open') ->addOption('Master', 'Master'); $f1 = new Input('athlete_address', 'Endereço', 'text'); $f2 = new Input('athlete_birthdate', 'Data de nascimento', 'date'); $f1->render(); // Retorna saida normal $f2->render(); // Retorna string vazia $select->render(); // Retorna saida normal Codigo da classe Select.php <?php namespace App\Core\Fields; use App\Core\Field; use App\Core\View; class Select implements Field { public function render() { return View::render('fields/select', [ 'key' => $this->getKey(), 'label' => $this->getLabel(), 'options' => $this->getOptions(), 'value' => $this->getValue() ]); } } As classes Input.php e Select.php compartilham de uma interface comum, porem quando eu tento renderizar uma segunda instancia de Input o que eu recebo é uma string vazia, o que pode ser isso?
  4. Estou começando e tenho algumas dúvidas, sobre como implementar isso. Dúvida sobre a classe DAO, é melhor passar o objeto de conexão com injeção de dependência ou instância-lo no construtor? Qual seria a melhor abordagem?
  5. claudiojuniorfabiao

    Ações especiais em API Restful

    Fala, galera! Qual tipo de requisição HTTP (HTTP Verbs) eu deveria usar para solicitar a emissão de uma nota fiscal para a API Rest no meu aplicativo PHP (arquitetura MVC) rodando no servidor? Digo, é fácil criar uma aplicação Restful, quando se tem apenas tarefas de CRUD básico, mas quando se deseja executar tarefas diferentes das tradicionais? Estou aprendendo agora sobre padrões, arquitetura de software e, sobretudo, APIs Rest, mas conheço bem o PHP e OOP, quer dizer, sou fluente na linguagem. Agradeço desde já a ajuda de todos! ;)
  6. claudiojuniorfabiao

    Abstração de classes

    Oi, galera! Bem, acredito estar postando na área certa, apesar de isso também estar relacionado com a estrutura da aplicação e não necessariamente PHP. É o seguinte, estou criando uma aplicação orientada a objetos; nela preciso de algumas funções comuns como cadastro de clientes, cadastro de funcionários, alguns produtos cadastrados, é básico, nada difícil de fazer do ponto de vista de um programador: conheço a sintaxe e sei trabalhar legal com a linguagem, mas minha dúvida é sobre a divisão das responsabilidades entre os tipos de objetos. Por exemplo, no cadastro de um novo cliente, quem está executando esta ação é um funcionário no sistema, mas quem deve ser o responsável pelo método? Ele deve ser parte da classe do funcionário, ou do cliente? Se for na classe "funcionário", seria algo como "cadastrarCliente", mas se for na classe do cliente (o que eu jugo mais correto, pelo princípio de responsabilidade única), seria como? Desde já agradeço qualquer luz que possam me dar sobre o assunto.
  7. Rodrigo5468

    Login

    Olá. Estou fazendo um sistema de cadastro e login, está funcionando quais perfeitamente. Porem tem alguns erros que eu não consigo resolver, já procurei na internet mas não achei nada relevante. Poderia me ajudar? Usuarios.php <?php require_once 'Crud.php'; class Usuarios extends Crud { protected $table = 'usuarios'; private $usuario; private $nomesobrenome; private $email; private $senha; public function setUsuario($usuario) { $this->usuario = $usuario; } public function setNomesobrenome($nomesobrenome) { $this->nomesobrenome = $nomesobrenome; } public function setEmail($email) { $this->email = $email; } public function setSenha($senha) { if(!empty($senha)) { $options = [ 'cost' => 11, ]; $this->senha = password_hash($senha, PASSWORD_BCRYPT, $options); if(password_verify($senha, $this->senha)) { return true; } } return false; } public function insert() { $propriedades = [ 'usuario' => $this->usuario, 'nomesobrenome' => $this->nomesobrenome, 'email' => $this->email, 'senha' => $this->senha ]; if(strlen($this->senha) < 8) { return('A sua senha precisa ter pelo menos 8 caracteres.'); exit(); } if(!filter_var($this->email, FILTER_VALIDATE_EMAIL)) { return('E-mail invalido.'); exit(); } foreach($propriedades as $propriedade => $valor) { if(empty($this->$propriedade)) { return('O campo '.$propriedade.' não foi preenchido.'); exit(); } } $stmt = DB::prepare("SELECT * FROM {$this->table} WHERE usuario=:usuario OR nomesobrenome=:nomesobrenome OR email=:email"); $stmt->bindValue(':usuario',$this->usuario,PDO::PARAM_STR); $stmt->bindValue(':nomesobrenome',$this->nomesobrenome,PDO::PARAM_STR); $stmt->bindValue(':email',$this->email,PDO::PARAM_STR); $stmt->execute(); $resultado = $stmt->fetch(\PDO::FETCH_ASSOC); $dadosJaExistem = array_intersect([ 'usuario' => $this->usuario, 'nomesobrenome' => $this->nomesobrenome, 'email' => $this->email], $resultado ); if($dadosJaExistem) { $mensagem = 'O(s) valor(es): ' . implode(', ', $dadosJaExistem) . ' já existem no banco de dados, por favor escolha outro(s).'; return($mensagem); exit(); } $sql = "INSERT INTO $this->table (usuario, nomesobrenome, email, senha) VALUES (:usuario, :nomesobrenome, :email, :senha)"; $stmt = DB::prepare($sql); $stmt->bindParam(':usuario', $this->usuario); $stmt->bindParam(':nomesobrenome', $this->nomesobrenome); $stmt->bindParam(':email', $this->email); $stmt->bindParam(':senha', $this->senha); if($stmt->execute()) { return 'Conta registrada com sucesso!'; exit(); } return 'Falha ao cadastrar.'; } public function login($usuario, $email, $senha) { try { $stmt = DB::prepare("SELECT id, usuario, email, senha FROM $this->table WHERE usuario = :usuario OR email=:email"); $stmt->execute(array(':usuario'=>$usuario, ':email'=>$email)); $row = $stmt->fetch(PDO::FETCH_ASSOC); if($stmt->rowCount() == 1) { if(password_verify($senha, $row['senha'])) { $_SESSION['user_session'] = $row['id']; return true; }else { return false; } } }catch(PDOException $e) { echo $e->getMessage(); } } public function is_loggedin() { if(isset($_SESSION['user_session'])) { return true; } } public function redirect($url) { header("Location: $url"); } public function logout() { session_destroy(); unset($_SESSION['user_session']); return true; } public function update($id) { $sql = "UPDATE $this->table SET usuario = :usuario, nomesobrenome = :nomesobrenome, email = :email, senha = :senha WHERE id = :id"; $stmt = DB::prepare($sql); $stmt->bindParam(':usuario', $this->usuario); $stmt->bindParam(':nomesobrenome', $this->nomesobrenome); $stmt->bindParam(':email', $this->email); $stmt->bindParam(':senha', $this->senha); $stmt->bindParam(':id', $id); return $stmt->execute(); } } session.php <?php session_start(); function __autoload($class_name){ require_once 'classes/' . $class_name . '.php'; } $session = new Usuarios(); if(!$session->is_loggedin()) { $session->redirect('index'); } Esses dois arquivos ficam dentro de uma pasta chamada classe. E esse fica no diretório raiz. login.php <?php session_start(); function __autoload($class_name){ require_once 'classes/' . $class_name . '.php'; } $login = new Usuarios(); if($login->is_loggedin()!="") { $login->redirect("index"); } if(isset($_POST["btn-entrar"])) { $usuario = strip_tags($_POST["usuario_email"]); $email = strip_tags($_POST["usuario_email"]); $senha = strip_tags($_POST["senha"]); if($login->Login($usuario,$email,$senha)) { $login->redirect("index"); }else { $error = "Detalhes errados."; } } ?> index.php <?php require_once("classes/session.php"); require_once("classes/Usuarios.php"); $auth_user = new Usuarios(); $user_id = $_SESSION['user_session']; $stmt = $auth_user->runQuery("SELECT * FROM users WHERE user_id=:user_id"); $stmt->execute(array(":user_id"=>$user_id)); $userRow=$stmt->fetch(PDO::FETCH_ASSOC); ?> Os erros que dá são esses... — Quando vai registrar — Quando vai fazer o login Por favor, peço a vocês que me auxilie com os avisos e erros. Muito obrigado.
  8. Você recomenda fazer um curso de UML antes de fazer um curso de OOP? sendo que sei o basico da OOP
  9. Vinicius Cainelli

    Compartilhar variáveis entre dois métodos

    Basicamente, o que eu tenho em uma classe são dois métodos. - getEstablishment($establishmentId) que pega todos os dados de um determinado estabelecimento baseado no id passado. - getAllEstablishments() que me da um array com todos os dados de todos os estabelecimentos que tenho no meu banco Se repararem no código, vão ver que repete muitas variaveis, existe alguma forma de eu compartilha-lhas entre esses métodos? function getEstablishment($establishmentId) { $query = "SELECT * FROM establishment WHERE establishment_id='{$establishmentId}' LIMIT 0,1"; $result = mysqli_query($this->connection, $query); $establishmentArray = mysqli_fetch_assoc($result); $docNumber = $establishmentArray['doc_number']; $legalName = $establishmentArray['legal_name']; $socialName = $establishmentArray['social_name']; $type = $establishmentArray['type_id']; $email = $establishmentArray['email']; $website = $establishmentArray['website']; $plan = $establishmentArray['plan_id']; $agreeTerm = $establishmentArray['agree_term']; $address = $establishmentArray['address']; $district = $establishmentArray['district']; $city = $establishmentArray['city_id']; $zipCode = $establishmentArray['postal_code']; $phone = $establishmentArray['phone']; $created = $establishmentArray['created']; $lastUpdate = $establishmentArray['last_update']; $establishment = new Establishment($docNumber, $legalName, $socialName, $type, $email, $website, $plan, $agreeTerm, $address, $district, $city, $zipCode, $phone, $created, $lastUpdate); return $establishment; } function getAllEstablishments() { $establishments = array(); $query = "SELECT * FROM establishment ORDER BY establishment_id DESC"; $result = mysqli_query($this->connection, $query); while ($establishmentArray = mysqli_fetch_assoc($result)) { $establishmentId = $establishmentArray['establishment_id']; $docNumber = $establishmentArray['doc_number']; $legalName = $establishmentArray['legal_name']; $socialName = $establishmentArray['social_name']; $type = $establishmentArray['type_id']; $email = $establishmentArray['email']; $website = $establishmentArray['website']; $plan = $establishmentArray['plan_id']; $agreeTerm = $establishmentArray['agree_term']; $address = $establishmentArray['address']; $district = $establishmentArray['district']; $city = $establishmentArray['city_id']; $zipCode = $establishmentArray['postal_code']; $phone = $establishmentArray['phone']; $created = $establishmentArray['created']; $lastUpdate = $establishmentArray['last_update']; $establishment = new Establishment($docNumber, $legalName, $socialName, $type, $email, $website, $plan, $agreeTerm, $address, $district, $city, $zipCode, $phone, $created, $lastUpdate); $establishment->setId($establishmentId); array_push($establishments, $establishment); } return $establishments; }
  10. hyper_pixel

    problema com orientacao

    Estou com o seguinte problema, criei uma classe chamada robo, quando acesso com ajax pela primeira vez o arquivo com a classe, instancio ela, faco operacoes etc em um segundo acesso a instancia do robo nao existe mais e todas as configuracoes sao perdidas, ele fica zerado novamente. Alguem sabe como resolvo isso?
  11. Bom dia a todos, Tenho um projeto atualmente zero orientado a objeto. Estava dando uma lida e pesquisada pela net, muita gente diz que o PHP é muito "misto", praticamente todos projetos irá encontrar linguagem procedural a grosso modo como também linguagem orientada a objeto (juntas), principalmente se for algo pequeno que não utilize frameworks como zend, cake, etc. Também ciente que orientação a objeto é um paradigma para nosso código se tornar "algo real", já li até mesmo que não é necessário o código ser baseado em classes para ser orientado a objeto(nunca vi POO sem classes), achei estranho e comecei a duvidar do que estava lendo, onde também dizia que Orientação a Objeto é mais a parte de organização do nosso código e algumas medidas que são padrões para manter essa organização. OK, até ai tudo é teoria. DÚVIDAS QUE NÃO ME DEIXAM DORMIR: • MVC: É possível eu seguir a estrutura MVC em php para um código não orientado a objeto? É possível ter o MVC em algo mais procedural ou misto? • MIGRAÇÃO: Caso eu seja obrigado a refazer meu projeto orientado a objeto, o que eu preciso saber que irei encarar pela frente? É algo que leva tempo, mas existe alguma forma de tornar essa migração facilitada? • PDO / MySQLi: PDO é um método montado em cima do paradigma orientado a objeto, sendo assim posso dizer que PDO é orientado a objeto? Minhas manipulações sql/php com pdo são orientadas a objetos apenas por utilizá-lo? O mesmo para MySQLi. OBS: Boatos de que BOA PARTE da documentação do PHP é estrutural, isto é por si verdade ou não, tudo que existe em PHP estruturado/procedural também existe em PHP orientado a objeto? Eu consigo argumentar para uma banca examinadora de TFC que meu projeto não foi desenvolvido orientado a objeto por algum bom motivo (igual este da documentação se for verdade)? Eu realizei testes de software (funcional/unitário com badboy e análise estática com rips) incrivelmente consegui zerar as falhas de sql injection, session e banco e quase zerar os erros de cross-scripting. Não consegui resolver file manipulation e alguns cross-scripting que quando apliquei a correção com htmlentities deu alguns bug na página. Enfim, com os testes de software consigo "provar", ou melhor, argumentar que minha gambiarra é funcional !!! Porém agora estou preso no MVC/Orientação a Objeto. O que vocês podem me ajudar nesse conceito galera? Estou fudido e tenho que desenvolver orientado a objeto ou existe uma saída? rsrs
  12. brhue

    Classe upload

    Estou continuando meus estudos sobre oop e SOLID, e queria saber se minhas classes estão violando algum principio do SOLID. Segue a tentativa: Upload.class.php <?php class Upload { private $fileName; private $fileSize = 2.0; private $fileType; private $filePath; private $token; protected $userFile; public function __construct(Token $token) { $this->token= $token; } public function setFileSize($maxSize) { $this->fileSize = (float)$maxSize * 1024 * 1024; } public function setFileType(Array $type) { $this->fileType = $type; } public function setFilePath($path) { $this->filePath = $path; } public function setUserFile($userFile) { $this->userFile = $userFile; } public function getFileName() { if (is_null($this->fileName)) $this->randomName(); return $this->fileName; } public function uploadFile() { if (!in_array($this->getExtension(), $this->fileType)) throw new RuntimeException("Extensão de arquivo não permitido."); else if ($this->fileSize < $_FILES[$this->userFile]['size']) throw new RuntimeException("Tamanho de arquivo não permitido."); else if (!move_uploaded_file($_FILES[$this->userFile]['tmp_name'], $this->filePath.$this->getFileName())) throw new RuntimeException("Falha ao mover arquivo."); } private function randomName() { $this->fileName = $this->token->generateToken().'.'.$this->getExtension(); } private function getExtension() { return pathinfo($_FILES[$this->userFile]['name'], PATHINFO_EXTENSION); } } ?> Esses sets, seria ideal colocar tudo no construtor? Token.php <?php interface Token { public function generateToken(); } ?> Bin2Hex.class.php class Bin2Hex implements Token { public function generateToken() { return bin2hex(openssl_random_pseudo_bytes(32)); } } UploadImage.class.php <?php class UploadImage extends Upload { private $height; private $width; public function setImageHeight($height) { $this->height = $height; } public function setImageWidth($width) { $this->width = $width; } public function uploadFile() { list($height, $width) = getimagesize($_FILES[$this->userFile]['tmp_name']); if ($this->height < $height) { throw new RuntimeException("Altura da imagem não permitida."); } else if ($this->width < $width) { throw new RuntimeException("Largura da imagem não permitida."); } parent::uploadFile(); } } ->A ideia aqui seria uma classe mais especifica para imagem... E a maior dúvida é se nessa parte viola o LSP (herança). index.php $upload = new UploadImage(new Bin2Hex()); $upload->setUserFile('photo'); $upload->setFilePath('uploads/'); $upload->setFileType(array('jpg', 'png')); $upload->setFileSize(1.0); $upload->setImageHeight(800); $upload->setImageWidth(600); try { $upload->uploadFile(); } catch (RuntimeException $e) { echo $e->getMessage(); }
  13. Estou estudando php e por consequência orientação objetos. Nesses últimos dias, me deparei com os princípios do SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion) e tive algumas dúvidas. Como por exemplo, na tentativa de criar um "registration system", não consegui implementar os conceitos do SOLID, principalmente o SRP e OCP. Com isso me deparei com algumas dúvidas, por exemplo: Como escolher os nomes das classes e suas funções (objetivo, etc) ? Como relacionar os objetos (banco de dados, usuario, etc) ? Como deve ser a estrutura de classes(ex: DataBase, User, User Service) para um 'registration system' ou similar ? Como saber se estou violando ou não os principios do SOLID (dicas, etc) ? Como deveria ser implementada as classes abaixo, principalmente a DataBase ? Segue a tentativa: DataBase.class.php <?php require_once 'config.php'; class DataBase { private $DB; private $table = 'cadastro'; public function __construct() { $this->DB = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS); } public function insertUser($name, $lastname, $email, $password) { $sql = "INSERT INTO {$this->table} (name, lastname, email, password) VALUES (:name, :lastname, :email, :password)"; $stmt = $this->DB->prepare($sql); $stmt->bindParam(':name', $name, PDO::PARAM_STR); $stmt->bindParam(':lastname', $lastname, PDO::PARAM_STR); $stmt->bindParam(':email', $email, PDO::PARAM_STR); $stmt->bindParam(':password', $password, PDO::PARAM_STR); return $stmt->execute(); } public function findUserByEmail($email) { //... } public function findAll() { //... } //... } ?> User.class.php <?php class User { private $id; private $name; private $lastname; private $email; private $password; public function __construct($name = null, $lastname = null, $email = null, $password = null) { $this->name = $name; $this->lastname = $lastname; $this->email = $email; $this->password = $password; } public function getId() { return $this->id; } public function setId($id) { $this->id = $id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function getLastname() { return $this->lastname; } public function setLastname($lastname) { $this->lastname = $lastname; } public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } public function getPassword() { return $this->password; } public function setPassword($password) { $this->password = $password; } } ?> UserAction.class.php <?php class UserAction { public function register($user, $database) { return $database->insertUser($user->getName(), $user->getLastname(), $user->getEmail(), $user->getPassword()); } /* public function login($user, $database) { //... } */ //... } ?> register.php <?php require_once 'autoload.php'; $name = (isset($_POST['name']))?$_POST['name']:null; $lastname = (isset($_POST['lastname']))?$_POST['lastname']:null; $email = (isset($_POST['email']))?$_POST['email']:null; $password = (isset($_POST['password']))?$_POST['password']:null; $user = new User($name, $lastname, $email, $password); $database = new DataBase(); $action = new UserAction(); $action->register($user, $database); //... ?> Se puderem me indicar materias ou exemplos para prática ficarei grato. Obrigado !
  14. Alison_Melo

    Relatorio com titulo agrupado

    Bom dia a todos, Estou desenvolvendo um sistema onde possui três tabelas e uma tabela é de relacionamento.. as consultas estão OK, porém eu preciso separar os titulos pelo conteudo agrupado.. Por exemplo.. Tenho filmes e em cada filme tenho vinculado varios atores, porém, quando eu listo, ele repete varias vezes o filme. O que eu preciso é que exiba apenas uma vez o filme e logo abaixo todos os atores vinculados, e assim sucessivamente, Sei que com group_by eu consigo o titulo (estou utilizando codeigniter), porém eu consigo os dados em tabelas separadas, e queria exibir na mesma. ------------------Filme 1 ----------------- ator 1 ator 2 ator 3 -----------------Filme 2----------------- ator1 ator2 -----------------Filme 3----------------- ator 1 ator 2 ator 3 Como posso proceder? posso criar um foreach aninhado? Se puderem me dar um norte quanto a este assunto fico grato! Abraços!
  15. Gabriel Heming

    [Tutorial] Integridade de coleções com uso de Iterator

    Muitas vezes durante o desenvolvimento em orientações a objetos, tive problemas usando coleções de objetos, principalmente quanto a integridade. Veja o exemplo de uma Pessoa que possui uma lista de Contatos. Aqui vemos a implementação simples de uma classe Pessoa com uma lista de contatos (demais métodos foram omitidos para simplificação): class Pessoa { private $contatoList = array(); public function setContatoList(array $contatoList) { $this->contatoList = $contatoList; } public function getContatoList() { return $this->contatoList; } } E, agora, nossa entidade de contato: class Contato { const EMAIL = 1; const TELEFONE = 2; private $contato; private $tipo; public function __construct($contato , $tipo) { $this->contato = $contato; $this->tipo = $tipo; } } Com nossas entidades implementadas, vamos usufruir de suas funcionalidades: $contatoList = array(); $contatoList[] = new Contato('(54) 9999-9999' , Contato::TELEFONE); $contatoList[] = new Contato('email@provedor.com.br' , Contato::EMAIL); $pessoa = new Pessoa(); $pessoa->setContatoList($contatoList); var_dump($pessoa->getContatoList()); Saída: Dessa forma implementamos rapidamente uma classe simples Pessoa com sua lista de Contatos. Entretanto, não é possível adicionar apenas um contato para a lista já existente e nem podemos garantir a integridade dos dados (algo muito importante na orientação a objetos). Veja Só: $contatoList = array(); $contatoList[] = new Contato('(54) 9999-9999' , Contato::TELEFONE); $contatoList[] = new Contato('email@provedor.com.br' , Contato::EMAIL); $contatoList[] = 'meu email é email@provedor.com.br'; $pessoa = new Pessoa(); $pessoa->setContatoList($contatoList); var_dump($pessoa->getContatoList()); Saída: Como podemos ver na saída acima, tivemos um falha na integridade da lista. Foi permitida a inserção de item que não é um contato, apesar de "parecer ser um". Como podemos garantir que sempre será inserido um Contato na lista de usuários e poder adicionar um usuário existente a lista de contatos? Vamos mudar um pouco a implementação da classe Pessoa: class Pessoa { private $contatoList = array(); public function setContatoList(array $contatoList) { /** verificar se existe algum elemento que não é do tipo contato **/ $callback = function($row) { return !$row instanceof Contato; }; if(array_filter($contatoList , $callback)) { throw new \RuntimeException('Somente valores do tipo Contato são permitidos'); } $this->contatoList = $contatoList; } public function getContatoList() { return $this->contatoList; } } E vamos ao novo teste: $contatoList = array(); $contatoList[] = new Contato('(54) 9999-9999' , Contato::TELEFONE); $contatoList[] = new Contato('email@provedor.com.br' , Contato::EMAIL); $contatoList[] = 'meu email é @provedor.com.br'; $pessoa = new Pessoa(); try { $pessoa->setContatoList($contatoList); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } Saída: A lógica é simples, sempre que algum item da lista não for um Contato, o array retornado por array_filter será maior que zero. Nesse caso, será lançada uma exceção informando que a lista não está correta. Ok, garantimos, por enquanto e sem minha total satisfação, a integridade de adicionar apenas listas que contenham apenas contatos. Deixarei a implementação da lista parada por enquanto e vamos implementar a funcionalidade para adicionar um contato a lista já existente. class Pessoa { private $contatoList = array(); public function setContatoList(array $contatoList) { /** verificar se existe algum elemento que não é do tipo contato **/ $callback = function($row) { return !$row instanceof Contato; }; if(array_filter($contatoList , $callback)) { throw new \RuntimeException('Somente valores do tipo Contato são permitidos'); } $this->contatoList = $contatoList; } public function addContato(Contato $contato) { $this->contatoList[] = $contato; } public function getContatoList() { return $this->contatoList; } } Implementamos o método, na classe pessoa, para permitir que possamos adicionar apenas um contato a lista já existente, vamos ao teste: $contatoList = array(); $contatoList[] = new Contato('(54) 9999-9999' , Contato::TELEFONE); $pessoa = new Pessoa(); try { $pessoa->setContatoList($contatoList); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } $pessoa->addContato(new Contato('email@provedor.com.br' , Contato::EMAIL)); var_dump($pessoa->getContatoList()); Saída: Ok, ok e ok. Está funcionando da forma esperada. Mas esse código não está, como diria Kent Beck, "fedendo"? Vamos a alguns pontos: - Por que a classe Pessoa está validando a lista? - Por que a classe Pessoa está implementando um método de lista? - Por que meu café... digo... por que a classe Pessoa está assumindo essas responsabilidades? A resposta é simples, o PHP não implementa nativamente essa integridade. A partir de então, e com muita pesquisa, percebe-se que é necessário implementar esta integridade. Neste momento partimos para o design pattern Iterator. Para que quiser saber mais sobre o Iterator como um Design Pattern, sugiro a leitura deste tópico. Vamos a implementação da classe generalizada para coleções. Classe a qual será nossa base para qualquer implementação de coleções de objetos. Obs: Essas implementações fazem parte do meu TCC da Pós e implementadas sobre o namespace Harbinger, nome o qual utilizo para o desenvolvimento das minhas API/Plugins e framework de estudos. namespace Harbinger\Iterator; /** * @author Gabriel Heming <gabriel.heming@hotmail.com> * @package Harbinger\Iterator **/ abstract class Collection implements \Iterator { /** * @var Object[] **/ protected $object = array(); /** * @var int **/ private $pointer = 0; /** * @var int **/ protected $total = 0; /** * add an Object into collection * @param Object $object * @return $this * @throws \UnexpectedValueException If Object isn't part of a object kind **/ public function add($object) { $class = $this->getTargetClass(); if(!$object instanceof $class) { throw new \UnexpectedValueException("This is a {$class} collection"); } $this->object[$this->total] = $object; $this->total++; return $this; } /** * retrieve the object from current position * @return Object * @throws \OutOfBound---ception If the collection not has any object **/ public function current() { if(isset($this->object[$this->key()])) { return $this->object[$this->key()]; } throw new \OutOfBound---ception("Index {$this->key()} not exists as a object index"); } /** * retrieve the current key * @return int **/ public function key() { return $this->pointer; } /** * move the pointer to next index position **/ public function next() { $this->pointer++; } /** * move the pointer to beginning **/ public function rewind() { $this->pointer = 0; } /** * check if the actual position is valid * @return boolean **/ public function valid() { return (isset($this->object[$this->key()])); } /** * return the object kind for collection * @return string **/ abstract public function getTargetClass(); } Dessa forma, desenvolvemos nossa base abstrata para a criação de uma coleção. Nossa abstração exige apenas uma implementação, o método getTargetClass. Este método é reponsável por informar qual objeto a coleção será responsável por manipular, não permitindo a inserção de nenhum outro tipo de objeto. A partir desse ponto, podemos prosseguir de duas formas: uma classe genérica para trabalhar com objetos especificados em tempo de execução ou uma classe especializada em um determinado tipo de objeto. Pois bem, vamos realizar das duas formas, iniciando com a nossa classe genérica: namespace Harbinger\Iterator\Collection; /** * @author Gabriel Heming <gabriel.heming@hotmail.com> * @package Harbinger\Iterator * @subpackage Collection **/ class Object implements \Harbinger\Iterator\Collection { /** * @var string **/ private $targetClass; public function __construct($targetClass) { $this->targetClass = $targetClass; } /** * {@inheritdoc} **/ public function getTargetClass() { return $this->targetClass; } } Vamos a modificação da classe pessoa: class Pessoa { private $contatoCollection; public function __construct() { $this->contatoCollection = new \Harbinger\Iterator\Collection(\Contato::class); } public function setContatoCollection(\Harbinger\Iterator\Collection $contatoCollection) { if($this->contatoCollection->getTargetClass() != $contatoCollection->getTargetClass()) { throw new \UnexpectedValueException( sprintf( "Expected a %s collection. %s given." $this->contatoCollection->getTargetClass(), $contatoCollection->getTargetClass() ) ); } $this->contatoCollection = $contatoCollection; } public function getContatoCollection() { return $this->contatoCollection; } } E o nosso uso: $contatoCollection = new \Harbinger\Iterator\Collection\Object('Contato'); $contatoCollection->add(new Contato('(54) 9999-9999' , Contato::TELEFONE)); $pessoa = new Pessoa(); try { $pessoa->setContatoCollection($contatoCollection); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } $pessoa->getContatoCollection()->add(new Contato('email@provedor.com.br' , Contato::EMAIL)); foreach($pessoa->getContatoCollection() AS $contato) { var_dump($contato); } Saída: A implementação genérica está pronta e funcionando como o desejado. E caso eu tente utilizar uma classe que suporte outro tipo de objetos, teremos uma exception: $collection = new \Harbinger\Iterator\Collection\Object('Pessoa'); $pessoa = new Pessoa(); try { $pessoa->setContatoCollection($collection); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } Saída: A nossa única baixa, neste tipo de implementação, é a necessidade de verificar o tipo de coleção adicionada a pessoa. Mas vamos a nossa implementação específica que resolve esse problema Neste caso, ao invés de utilizar uma coleção genérica, utilizarei uma coleção especializada para objetos do Contato. namespace Collection; class Contato extends \Harbinger\Iterator\Collection { /** * {@inheritdoc} **/ public function getTargetClass() { return \Contato::class; } Realizemos as modificações (ou exclusões) necessárias na classe Pessoa, class a qual ficará mais "enxuta". class Pessoa { private $contatoCollection; public function __construct() { $this->contatoCollection = new \Collection\Contato(); } public function setContatoCollection(\Collection\Contato $contatoCollection) { $this->contatoCollection = $contatoCollection; } public function getContatoCollection() { return $this->contatoCollection; } } E nossa utilização: $contatoCollection = new \Collection\Contato(); $contatoCollection->add(new Contato('(54) 9999-9999' , Contato::TELEFONE)); $pessoa = new Pessoa(); try { $pessoa->setContatoCollection($contatoCollection); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } $pessoa->getContatoCollection()->add(new Contato('email@provedor.com.br' , Contato::EMAIL)); foreach($pessoa->getContatoCollection() AS $contato) { var_dump($contato); } Saída: Como está se tornando frequente, obtivemos exito quanto o sucesso da implementação. Uma classe específica nos da a vantagem de uma modelagem mais específica, utilizando o type hint da coleção necessária. Entretanto, nos gera granularidade, pois cada coleção especializada necessita de uma implementação e isso nos é traduzido através de uma nova classe. Voltando ao Iterator, estou sentindo falta de algumas implementações, por exemplo, Iterator não permite contar quantos objetos existem em sua coleção, veja: $collection = new \Collection\Contato(); $collection->add(new Contato('(54) 9999-9999' , Contato::TELEFONE)); $collection->add(new Contato('email@provedor.com.br' , Contato::EMAIL)); echo 'Quantidade de contatos: '.count($collection); Saída: Mas como 1? Se eu tenho dois elementos? Como podemos resolver esse problema? Para este fim, podemos utilizar a interface Countable. Para essa interface devemos implementar apenas um método denominado count. Vamos a implementação: namespace Harbinger\Iterator; abstract class Collection implements \Iterator , \Countable { /** demais métodos e propriedades omitidos **/ /** * retrieve the number of rows * @return int **/ public function count() { return (int)$this->total; } } E, agora, vamos novamente ao uso: $collection = new \Collection\Contato(); $collection->add(new Contato('(54) 9999-9999' , Contato::TELEFONE)); $collection->add(new Contato('email@provedor.com.br' , Contato::EMAIL)); echo 'Quantidade de contatos: '.count($collection); Saída: Neste momento, podemos contar quantos objetos nossa coleção possui. Uma outra implementação interessante, é a interface SeekableIterator. Essa interface define que podemos ir para qualquer registro em específico e não apenas iterar sobre nossa coleção. A interface SeekableIterator extende a interface Iterator, logo devemos substituir a interface Iterator e utilizar em seu lugar a interface SeekableIterator. Vamos a nossa implementação: namespace Harbinger\Iterator; abstract class Collection implements \SeekableIterator , \Countable { /** demais métodos e propriedades omitidos **/ /** * Seeks to a given position in the iterator. * @param int $position * @throws \OutOfBound---ception If an invalid position has been given **/ public function seek($position) { if (!isset($this->object[$this->key()])) { throw new \OutOfBound---ception("invalid seek position ($position)"); } $this->pointer = $position; } } Vamos a nosso teste recorrente: try { $collection = new \Collection\Contato(); $collection->add(new Contato('(54) 9999-9999' , Contato::TELEFONE)); $collection->add(new Contato('email@provedor.com.br' , Contato::EMAIL)); var_dump($collection->current()); $collection->seek(1); var_dump($collection->current()); $collection->seek(2); var_dump($collection->current()); } catch (\RuntimeException $exception) { echo $exception->getMessage(); } Saída: Com um pouco de implementação, conseguimos um grande avanço na integridade quanto a orientação à objetos. Outra interface interessante para se utilizar com Iterator é ArrayAccess que permite que objetos sejam acessados como arrays. Essa implementação, deixarei para os interessados :yes: No próximo artigo, quero demonstrar o uso de Iterator com dados retornados do banco de dados e a sua criação em tempo de execução. Dúvidas, sugestões e críticas são muito bem vindas! ------ Código disponibilizado como pacote do composer: https://bitbucket.org/harbingerproject/iterator Para realizar a instalção do pacote, basta adicionar o repositório ao composer e adicionar como requerimento: composer.json { "repositories": [ { "type": "vcs", "url": "https://username@bitbucket.org/harbingerproject/iterator.git" } ], "require": { "harbinger/iterator": "^1.0.2", } } E rodar o comando composer install (pode ser executado em qualquer sistema operacional).
  16. Mateus Silva

    Erro No Pdo

    seguinte, to fazendo um sistema e ele tá dando um erro na classe do banco de dados, onde eu tento usar o prepare() ele diz que to chamando um método de um não objeto, não sei o que pode ser, enfim, vou deixar as classes: Model.class.php <?php namespace system; use \system\DB; Class Model { private $conn; protected $table; public $error; public function __construct(){ $this->conn = DB::init(); } public function setTable($table){ $this->table = $table; } private function buildInsert(array $data){ $columns = null; $values = null; foreach($data AS $key => $value): $columns .= "{$key},"; $values .= '?,'; endforeach; $columns = (substr($columns, -1) == ',') ? trim(substr($columns, 0, (strlen($columns) -1))) : $columns; $values = (substr($values, -1) == ',') ? trim(substr($values, 0, (strlen($values) -1))) : $values; $query = "INSERT INTO {$this->table}({$columns}) VALUES({$values})"; return trim($query); } private function buildUpdate(array $data, array $condition, $operator = '='){ $fields = null; foreach($data AS $key => $value): $fields .= "{$key} = ?,"; endforeach; $where = null; foreach($condition AS $key => $value): $where .= "{$key} {$operator} ? AND "; endforeach; $fields = (substr($fields, -1) == ',') ? trim(substr($fields, 0, (strlen($fields) -1))) : $fields; $where = (substr($where, -4) == 'AND ') ? trim(substr($where, 0, (strlen($where) -4))) : $where; $query = "UPDATE {$this->table} SET {$fields} WHERE {$where}"; return trim($query); } private function buildDelete(array $condition, $operator = '='){ $where = null; foreach($condition AS $key => $value): $where .= "{$key} {$operator} ? AND "; endforeach; $where = (substr($where, -4) == 'AND ') ? trim(substr($where, 0, (strlen($where) -4))) : $where; $query = "DELETE FROM {$this->table} WHERE {$where}"; return trim($query); } public function insert(array $data){ try { $sql = $this->conn->prepare($this->buildInsert($data)); $count = 1; foreach($data AS $value): $type = (is_numeric($value)) ? PDO::PARAM_INT : PDO::PARAM_STR; $sql->bindValue($count, $value, $type); $count++; endforeach; return $sql->execute(); }catch(PDOException $e){ echo "Erro: {$e->getMessage()}"; } } public function update(array $data, array $where){ try { $sql = $this->conn->prepare($this->buildUpdate($data, $where)); $count = 1; foreach($data AS $value): $type = (is_numeric($value)) ? PDO::PARAM_INT : PDO::PARAM_STR; $sql->bindValue($count, $value, $type); $count++; endforeach; foreach($where AS $value): $type = (is_numeric($value)) ? PDO::PARAM_INT : PDO::PARAM_STR; $sql->bindValue($count, $value, $type); $count++; endforeach; return $sql->execute(); }catch(PDOException $e){ echo "Erro: {$e->getMessage()}"; } } public function delete(array $where){ try { $sql = $this->conn->prepare($this->buildDelete($where)); $count = 1; foreach($where AS $value): $type = (is_numeric($value)) ? PDO::PARAM_INT : PDO::PARAM_STR; $sql->bindValue($count, $value, $type); $count++; endforeach; return $sql->execute(); }catch(PDOException $e){ echo "Erro: {$e->getMessage()}"; } } public function generic($query, $params = false, $all = true){ try { $sql = $this->conn->prepare($query); if($params): $count = 1; foreach($params AS $value): $type = (is_numeric($value)) ? PDO::PARAM_INT : PDO::PARAM_STR; $sql->bindValue($count, $value, $type); $count++; endforeach; endif; $sql->execute(); if($all) return $sql->fetchAll(PDO::FETCH_OBJ); else return $sql->fetch(PDO::FETCH_OBJ); }catch(PDOException $e){ echo "Erro: {$e->getMessage()}"; } } } ?> DB.class.php <?php namespace system; class DB { private static $conn; public static function init(){ if(is_null(self::$conn)): try { self::$conn = new \PDO(DSN, USER, PASS); }catch(PDOException $e){ echo "Erro ao conectar com o banco de dados: {$e->getMessage()}"; } endif; return self::$conn; } } ?> me ajudem, pfv :s
×

Informação importante

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