Alura > Cursos de Programação > Cursos de PHP > Conteúdos de PHP > Primeiras aulas do curso PHP: conheça a programação Orientada a Objetos

PHP: conheça a programação Orientada a Objetos

Conhecendo a Orientação a Objetos - Apresentação

Olá, pessoal! Sejam muito bem-vindos à Alura. Sou o Vinícius Dias e guiarei vocês neste curso sobre orientação a objetos com PHP.

Audiodescrição: Vinicius Dias se declara como um homem branco. Tem olhos escuros e cabelos curtos e escuros. Usa bigode e cavanhaque. Está com uma camiseta preta onde está escrito "PHPeste" em marrom, com uma fonte bastante características para artes do sertão nordestino. Está sentado em uma de encosto preto alto e estofado. Na sua frente tem um microfone em um suporte e, no fundo, uma parede lisa com uma iluminação roxo-claro..

Público-alvo

Neste curso de Programação Orientada a Objetos. Se você é uma pessoa que já conhece PHP, sintaxe da linguagem, sabe o que são variáveis, estruturas de controle, funções, arrays (matrizes) e strings (cadeias de caracteres), se você já conhece o básico da linguagem, este curso é para você.

O que aprenderemos

Aqui, aprenderemos uma nova forma de pensar código. Ao invés de pensar o nosso código somente voltado a variáveis avulsas e funções, vamos organizar, unir comportamento e funcionalidade em uma nova estrutura de dados que ainda não conhecemos.

Aprenderemos a criar tipos de dados. Assim como temos os tipos primitivos do PHP, como inteiro, booleano, float (ponto flutuante), criaremos nossos próprios tipos, como, por exemplo, o tipo filme, que possui suas próprias particularidades. Após aprendermos como criar um tipo e ter dados atrelados a esse tipo, vamos manipular esses dados. Então, adicionaremos comportamentos ao nosso tipo filme, por exemplo, e a partir daí, vamos conhecendo atributos específicos, na verdade, conceitos específicos de PHP e conceitos mais genéricos de orientação a objetos.

Existem quatro pilares da orientação a objetos, que provavelmente você já leu se já estudou ou pesquisou sobre orientação a objetos. Neste curso conheceremos todos eles, ou seja, você sairá deste curso sabendo o que são cada um desses quatro pilares e como aplicá-los com PHP.

Se durante este curso surgir alguma dúvida, algo não ficar claro, acesse o fórum do curso para criar um tópico de dúvida ou entre no servidor do Discord da Alura para iniciar uma discussão sobre o assunto. Com certeza alguém te ajudará, e esse tipo de discussão também ajuda a fixar o conteúdo. Então, não só faça perguntas, mas tente responder algumas perguntas também.

Pré-requisitos

Para fazer este curso, como já dissemos, é importante que você tenha conhecimento sobre:

Portanto, é importante ter feito os cursos anteriores de PHP, até porque o ponto de partida deste curso será o projeto final do curso anterior sobre PHP. Claro, se você já tem os conhecimentos básicos da linguagem e quer começar daqui, vai ter um exercício para que você possa baixar o projeto inicial.

Acreditamos que já falamos bastante. Então, te esperamos no próximo vídeo para começarmos a entender por que utilizar esse novo paradigma de programação, por que a programação orientada a objetos pode ser útil para nós.

Conhecendo a Orientação a Objetos - Problemas procedurais

Antes de melhorarmos nosso código e adotarmos práticas altamente recomendadas no mercado, começaremos a entender quais são os problemas do código no estado em que paramos. Se você não fez os cursos anteriores, além da recomendação de fazê-los, precisa ter este projeto, pois este é o ponto de partida. Começaremos esse curso a partir do último ponto do curso anterior.

Conhecendo os problemas do código

Estamos lidando com um filme da nossa plataforma de streaming, a Screen Match, e este filme tem vários valores dispersos pelo nosso programa. Se abrirmos o arquivo index.php, como ponto de partida do nosso projeto, encontraremos:

Tudo está armazenado dispersamente em variáveis soltas. Até a manipulação de notas está "solta" no código. Também temos uma função que recebe quaisquer dados que passarmos, sem nenhuma relação.

Poderíamos passar um booleano qualquer para $incluidoNoPlano, que indica se o plano da pessoa é Prime ou não, assim como poderíamos passar qualquer valor para o ano de lançamento desse filme. Para exibirmos os dados do filme, podemos usar qualquer variável, assim como na exibeMensagemLancamento().

De modo geral, as informações não têm uma estrutura bem definida de quais são os valores que todo filme precisa ter. Quando vamos manipular um filme, por exemplo, como adicionar as notas para esse filme e obter a nota média desse filme, não temos um local centralizado.

Com esse código que utilizamos até agora, temos os problemas de que todos os valores referentes a um filme não estão no local centralizado. No final, até centralizamos isso em um array associativo criaFilme(), mas podemos adicionar as informações que quisermos nesse array, ou seja, pode ou não ter uma nota, um gênero, um ano de lançamento e até mesmo o título.

Ou seja, os valores referentes ao nosso filme estão mal definidos. Não conseguimos padronizar o que efetivamente é um filme, quais informações ele tem e como acessar esses dados. Além disso, os dados de um filme e seus comportamentos estão separados.

Estamos criando um filme com é um array associativo, como aprendemos no curso anterior, mas temos códigos desestruturados para obter todas as informações referentes a esse filme. Reparem que não está muito organizado ou coeso. E coesão é algo muito mencionado no estudo da orientação a objetos, que é o tema do curso.

Resolvendo os problemas

Nosso propósito com este curso é, principalmente, resolver dois grandes problemas:

  1. Criar coesão entre os dados e os comportamentos que manipulam esses dados;
  2. Ter uma boa modelagem do que são esses dados.

Precisamos descobrir o que todo filme precisa ter. Todo filme tem que ter um nome? O valor precisa se chamar $nome ou posso chamar $titulo? O ano de lançamento vai se chamar $anoLancamento ou chamar $ano? Sempre será o inteiro?

Nesse curso buscaremos uma visão mais definida desses pontos, trabalhando nesses problemas do código. Com isso, acabaremos melhorando a organização e a leitura do código. Resolveremos problemas que nem conseguimos identificar ainda.

Entendendo a teoria

O código que temos no momento usa o que chamamos de programação procedural, mas algumas pessoas chamam de programação imperativa. Embora ambos os termos estejam corretos, eles significam coisas diferentes.

Na programação procedural temos dados soltos e alguns procedimentos que fazemos através de funções. Nesse tipo de programação, a forma que temos de organizar nosso código é por meio de funções. Criamos procedures (procedimentos), subrotinas ou, como chamamos no mundo PHP, funções. Organizar o código por funções é uma possibilidade, tanto que fizemos isso até agora, mas não é suficiente.

Temos outras formas de fazer isso no PHP, e na próxima aula, aprenderemos uma nova estrutura para definirmos exatamente o que é um filme e o que ele precisa ter. Para isso começaremos a preparar o ambiente.

Preparando o ambiente

No menu Explorador, na lateral direita, clicaremos com o botão direito do mouse sobre a pasta "src". Selecionaremos "New Folder (Nova Pasta) para criarmos uma nova pasta chamada "Modelo". Nessa pasta teremos o modelo do que é um filme, por exemplo, ou qualquer outra estrutura que criarmos no nosso serviço de streaming.

Dentro desta pasta, criaremos um novo arquivo, chamado Filme.php. Por enquanto, você não precisa se preocupar tanto em entender os motivos para isso, mas repare que tanto a pasta "Modelo", quanto o arquivo Filme.php estão com a primeira letra em maiúsculo.

Tentaremos seguir esse padrão a partir de agora nessas novas estruturas que conheceremos. Criamos uma pasta "Modelo", com M maiúsculo, e dentro dessa pasta criamos o arquivo Filme.php, com F maiúsculo.

Próximos passos

E este arquivo é o que vamos trabalhar na próxima aula.

No próximo vídeo para criarmos a estrutura de um filme dentro do Filme.php.

Conhecendo a Orientação a Objetos - Definindo um modelo

Vamos definir o que todo filme precisa ter.

Criando a estrutura de um filme

No arquivo Filme.php, criaremos uma estrutura que ainda não conhecemos, chamada Filme. Quando criamos algo que delimita um bloco, precisamos usar chaves ({}), então vamos abrir e fechar chaves. Dentro delas, definiremos alguns valores. Antes de continuarmos, é importante lembrarmos que, no início do arquivo, precisamos colocar a abertura da tag PHP (<?php), porque tudo que escrevermos nesse código será em PHP.

<?php

Filme {
    
}

Dentro dessas chaves, na linha 4, após identarmos, definiremos quais são os valores que todo filme precisa ter. Primeiro, todo filme precisa ter um nome ou título, como você preferir. Eu chamarei de nome, então criarei a variável $nome. Também precisa ter um ano de lançamento e um gênero, então criaremos essas variáveis.

<?php

Filme {
    $nome;
    $anoLancamento;
    $genero;
}

Voltando para o nosso arquivo funcoes.php para descobrir o que mais nosso filme precisa. Além do nome, ano e gênero, a função criaFilme() tem a variável nota, portanto, vamos adicioná-la ao nosso modelo de Filme também.

Arquivo Filme.php

<?php

Filme {
    $nome;
    $anoLancamento;
    $genero;
    $nota;
}

Salvamos esse arquivo e agora vejamos o que acontece. Como temos algumas extensões do PHP no nosso Visual Studio Code, às vezes ele apresenta alguns avisos quando salvamos, e foi exatamente o que aconteceu. No caso, a variável $nome ficou sublinhada em vermelho.

Analisando o erro

Ele indica um erro de sintaxe, porque escrevemos um ponto e vírgula que ele não estava esperando. Na verdade, o que acabamos de criar não faz muito sentido. O PHP se perdeu no que estamos fazendo, porque criamos o Filme sem dizer se ele uma função ou outra coisa.

O que estamos definindo é um modelo (template) dizendo o que todo filme que criarmos precisa ter. Todo filme que criarmos, ou seja, toda variável que for um Filme, precisa ter nome, ano de lançamento, gênero e nota.

O nome para estrutura que modela algo, criando esse template, é classe. Estamos criando a classe Filme, ou seja, class Filme.

<?php

class Filme {
    $nome;
    $anoLancamento;
    $genero;
    $nota;
}

Entendendo sobre a classe (class)

Uma classe nada mais é do que um novo tipo, no caso, um tipo próprio que estamos criando, chamado Filme. Assim como os tipos como string e inteiro, criamos o tipo Filme.

Porém, os tipos como inteiro, string, booleano e os outros são chamados tipos primitivos. porque têm apenas um único valor, já o tipo Filme é mais complexo, porque possui vários valores. Vamos nos adaptando com isso ao decorrer do curso, mas, basicamente, estamos criando um novo tipo, chamado Filme.

Ao salvarmos a mudança da linha 3, onde escrevemos class Filme {, ainda temos o erro. Isso porque não podemos simplesmente criar uma variável na classe sem explicitar que estamos criando algo que faz parte de um modelo do filme.

Temos algumas opções para fazermos isso, usando palavras reservadas. Ainda sem explicar muito detalhes, utilizaremos uma palavra que nos permite acessar as variáveis do tipo Filme, como o nome e o anoLancamento. Para isso, usaremos a palavra public antes de cada variável.

<?php

class Filme {
    public $nome;
    public $anoLancamento;
    public $genero;
    public $nota;
}

Quando salvamos, não temos mais nenhum erro!

Declarando os tipos das variáveis

Antes de, efetivamente, utilizarmos esse novo tipo, precisamos explicitar os tipos de cada uma das variáveis dele. Assim como nos tipos de parâmetros e tipo de retorno de funções, dizer os tipos do que tem dentro do nosso filme também é opcional, mas recomendamos fazer essa declaração.

O nome sabemos que uma string, o anoLancamento é um inteiro, o genero, por enquanto, também será uma string, e a nota será um float. Poderíamos questionar o tipo dessas duas últimas variáveis e pensar em outras abordagens, mas esses tipos nos atendem bem por enquanto e é o que temos utilizado até agora.

<?php

class Filme {
    public string $nome;
    public int $anoLancamento;
    public string $genero;
    public float $nota;
}

Feito isso, voltaremos para o arquivo funcoes.php, porque, na função criaFilme(), ao invés de retornarmos um array associativo, retornemos um Filme. Essa função precisa retornar uma variável do tipo Filme no lugar do array.

Para isso, dentro da função criaremos uma variável $filme e vamos pensar em como criamos um filme. Temos a classe Filme e precisamos criar uma variável com esse tipo. Para isso, utilizaremos outra palavra reservada, chamada new (novo). No caso, new Filme().

Arquivo funcoes.php

// código omitido

function criaFilme(string $nome, int $anoLancamento, float $nota, string $genero): Filme
{
    $filme = new Filme()
    
    return [
        'nome' => $nome,
        'ano' => $anoLancamento,
        'nota' => $nota,
        'genero' => $genero
    ];
}

Criamos uma variável do tipo Filme(). Os parênteses que escrevemos, nesse momento, são opcionais, mas vamos nos acostumar a sempre utilizá-los. Em breve você entenderá o motivo para isso.

Agora que temos a variável do tipo Filme, queremos acessar, de alguma forma, o nome dele. Em um array associativo, utilizamos colchetes e passamos string 'nome', por exemplo, $filme['nome']. Porém, para uma variável criada a partir de uma classe, utilizamos outro operador para acessar as variáveis, o operador seta (->), que é um traço (-) seguido do sinal maior que (>).

Utilizando o operador de seta

A partir dessa seta, podemos acessar o nome, escrevendo $filme->nome = $nome;. Assim atribuímos à variável nome o nome que recebemos por parâmetro. Faremos a mesma coisa com o ano de lançamento, o gênero e a nota.

Arquivo funcoes.php

// código omitido

function criaFilme(string $nome, int $anoLancamento, float $nota, string $genero): Filme
{
    $filme->nome = $nome;
    $fi1me->anoLancamento = $anoLancamento;
$filme->genero = $genero;
$filme->nota = $nota;

    return [
        'nome' => $nome,
        'ano' => $anoLancamento,
        'nota' => $nota,
        'genero' => $genero
    ];
}

Atenção: Precisamos garantir nossa classe de Filme tenha os mesmos parâmetros que passamos para função.

Abrindo o arquivo Filme.php, percebemos que temos todos essas variáveis, escritas da mesma forma que passamos para a função:

Os nomes que passamos nos parênteses de criaFilme() e o nome da variável que damos dentro da função, por exemplo $nome, não importa. O que precisamos verificar é o nome que passamos depois do operador seta, que precisa ser igual ao da classe.

Se passamos $filme->nome, nossa classe Filme precisa ter um parâmetro nome. Outro exemplo, se em Filme.php mudamos de anoLancamento, para ano, no funcoes.php precisamos passar $filme->ano = $anoLancamento. O nome dentro da função pode continuar $anoLancamento, mas o nome após a seta tem que ser idêntico ao da classe. No momento, manteremos como anoLancamento.

De volta ao arquivo funcoes.php, na função criaFilme(), já criamos o nosso filme e atribuímos os valores do nosso filme. Agora, podemos retornar essa variável $filme, codando return $filme;. Com isso, podemos apagar da linha 28 a 33, onde estava o retorno do array associativo.

Arquivo funcoes.php

// código omitido

function criaFilme(string $nome, int $anoLancamento, float $nota, string $genero): Filme
{
    $filme->nome = $nome;
    $fi1me->anoLancamento = $anoLancamento;
$filme->genero = $genero;
$filme->nota = $nota;

    return $filme;
}

Agora, abriremos o arquivo index.php, onde temos a função criaFilme(), na linha 38. Nossa $filme não é mais um array associativo, então, em todo index.php, ao invés de acessarmos através da sintaxe com colchetes ([]), usaremos o operador de seta. Por exemplo, na linha 45 mudaremos echo $filme["ano"]; para echo $filme->anoLancamento;, assim como fizemos dentro da função.

Mudanças no código do index.php

Testando as mudanças e corrigindo erros

Após fazermos essas mudanças em todas as aparições de $filme[] para $filme->, usando o mesmo nome de variável da classe Filme, já temos o necessário para continuar a execução. Então, abriremos o terminal, onde digitaremos php index.php, para rodarmos esse arquivo que alteramos.

Quando executamos, recebemos a notificação de um erro de divisão por zero (Division by zero), porque não nos lembramos de passar as notas para esse filme na hora da execução. Portanto, vamos executar mais uma vez, mas agora passando as notas: php index.php 10 8 7 5.8 e 9

Agora tivemos outro erro, indicando que a classe Filme não foi encontrada ("Uncaught Error: Class "Filme" not found"). Realmente, no arquivo index.php, não definimos a classe Filme em lugar nenhum.

Assim como importamos o funcoes.php, no começo do código, precisamos importar o Filme.php. Faremos isso logo na primeira linha, abaixo abertura da nossa tag de abertura <?php.

<?php

require __DIR__ . "/src/Modelo/Filme.php"
require __DIR__ . "/src/funcoes.php"

// código omitido

Agora, quando executamos o php index.php 10 8 7 5.8 e 9 de novo, nosso código é executado sem erro nenhum. A diferença é que agora temos um pouco mais de organização. Sabemos tudo o que um filme precisa para efetivamente ser um filme, então as coisas começam a ficar mais organizadas.

Apesar de estar melhor, existem muitos códigos que podemos organizar mais. Portanto, no próximo vídeo, entenderemos um pouco melhor a teoria do que acabamos de fazer.

Descobriremos os processos por trás das mudanças que fizemos e revisaremos alguns conceitos que já aprendemos. Esperamos você no próximo vídeo para desvendarmos alguns dos segredos que já até implementamos.

Sobre o curso PHP: conheça a programação Orientada a Objetos

O curso PHP: conheça a programação Orientada a Objetos possui 111 minutos de vídeos, em um total de 53 atividades. Gostou? Conheça nossos outros cursos de PHP em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda PHP acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas