Ir para conteúdo

Arquivado

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

BrunoBit

Require_once + class

Recommended Posts

Fala rapaziada.

Estou com uma duvida, de acordo com o conhecimento de vocês, é aconselhável fazer um require_once assim dentro do construct de uma class? Veja:

class myClass {

	private $var;

	public function __construct(){
		require_once("../folder/class.file.php");
		$this->var = new newClass();
	}

}

Desde já agradeço rapaziada, abração e fiquem com Deus.

Compartilhar este post


Link para o post
Compartilhar em outros sites
13 horas atrás, BrunoMs disse:

é aconselhável fazer um require_once assim dentro do construct de uma class

 

Não, nunca.

 

Existe um padrão inteiro para isso, veja: http://www.php-fig.org/psr/psr-4/

Exemplo 1: https://pt.stackoverflow.com/questions/91493/classe-autoload-psr4

Exemplo 2 e um pouco de teoria simplificada: https://davidlima.com.br/post/php-fig-e-as-psr-parte-4/

 

Você ainda pode utilizar o Composer (recomendo estudá-lo.. é mais simples do que parece e vai te ajudar muito):

https://pt.stackoverflow.com/questions/19200/composer-autoload-e-psr-0-vs-psr-4

Compartilhar este post


Link para o post
Compartilhar em outros sites

Matheuzão, valeu pela orientação cara, vou estudar a fundo isso pq to precisando bastante, eu tava fazendo dessa forma:

require_once("../folder/class.file.php");
class myClass {

	private $var;

	public function __construct(){
		// puxando a newClass do arquivo class.file.php
		$this->var = new newClass();
	}

}

Porém eu tava sentindo que tinha algo errado nisso, pq meio que tumultua os require nos arquivos conforme eu vou precisando de mais classes, tava achando meio estranho.

Nesse caso de cima você poderia me dar um exemplo utilizando namespaces só pra eu ter uma noção inicial?

Vou iniciar os testes aqui pra ir acostumando e entendendo.

Valeu irmão, obrigadão mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites
35 minutos atrás, BrunoMs disse:

você poderia me dar um exemplo utilizando namespaces só pra eu ter uma noção inicial?

Na verdade você não precisa usar namespaces. Eles são ótimos e eu recomendo, mas eles também trazem uma certa complexidade que nem sempre é necessária. O que eu quero dizer é que você pode ter um autoloader sem utilizar namespaces também.

 

Como eu disse, recomendo o uso do Composer. Veja essa série de vídeos: https://www.youtube.com/watch?v=_n57YVUVT2A

Esse tutorial também é interessante: https://tableless.com.br/composer-para-iniciantes/

 

 

O composer permitirá que você instale pacotes facilmente e já saia utilizando.

Exemplo:

1 - Você quer enviar e-mails autenticados com o PHP. Então você entra no https://packagist.org/ e procura por uma biblioteca.

2 - Você encontrou um tal de Phpmailer.

3 - Agora, supondo que você tenha instalado o composer na sua máquina e inicializado ele no seu projeto, você roda um "composer require phpmailer/phpmailer".

4 - Agora você chama apenas o composer no seu código, assim:

require 'vendor/autoload.php';

5 - Agora basta utilizar as bibliotecas que você instalou ou definiu para serem inicializadas pelo composer. Exemplo:

<?php
require 'vendor/autoload.php';

// perceba que agora eu já saio usando a biblioteca...

// essas barras é simplesmente pq o PHPMailer possui essa estrutura horrível
// você pode resolver o uso desse nome enorme com o 'use'
// Veja: http://php.net/manual/pt_BR/language.namespaces.importing.php
$mail = new PHPMailer\PHPMailer\PHPMailer;
$mail->setFrom('from@example.com', 'Your Name');
$mail->addAddress('myfriend@example.net', 'My Friend');
$mail->Subject  = 'First PHPMailer Message';
$mail->Body     = 'Hi! This is my first e-mail sent through PHPMailer.';
if(!$mail->send()) {
  echo 'Message was not sent.';
  echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
  echo 'Message has been sent.';
}

 

Os require_once são feitos pelo autoloader quando o PHP não encontrar uma classe, graças a essa função: spl_autoload_register()

 

Esse exemplo acima foi para você entender o propósito principal do Composer, mas ele também traz o recurso de autoload para o seu próprio projeto. Exemplo:

 

1 - Após ter lido o padrão PSR-4 e entendido como você deve organizar seus namespaces, você cria uma pasta, digamos, /src.

2 - Suas classes vão dentro dessa pasta e seu projeto se chama Tabajara, então decidiu que seu namespace vai começar assim. Resumindo: as classes do namespace Tabajara vão ser procuradas em /src.

3 - Agora você cria uma classe qualquer dentro dessa pasta e desse namespace:

 

/src/MinhaClasse.php (note o CamelCase)

<?php
namespace Tabajara;

class MinhaClasse {
    //...
}

 

4 - Agora, supondo que você tem o Composer instalado, você define essa estrutura de autoload para ele, em seu arquivo de configurações composer.json. Exemplo:

{
    "name": "empresa_do_bruno/tabajara",
    "description": "projeto tabajara",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Bruno",
            "email": "bruno@brunocorp.org"
        }
    ],
    "minimum-stability": "stable",
    "require": {
        "php": "^7"
    },
    "autoload": {
        "psr-4": {
            "Tabajara\\": "src/",
        },
        "files": [
            "src/um_arquivo_que_eu_quero_inicializar.php",
            "src/outro_arquivo.php"
        ]
    },
}

 

Feito isso, vamos usar:

 

/index.php

<?php
require 'vendor/autoload.php';

//Exemplo 1:
use Tabajara\MinhaClasse;
$tabajara = new MinhaClasse;

//Exemplo 2:
$tabajara = new Tabajara\MinhaClasse;

 

 

Expliquei utilizando o Composer pq é a melhor forma, mas você ainda pode implementar o autoloader você mesmo e ignorar o Composer... exemplo: http://www.php-fig.org/psr/psr-4/examples/

 

Obs: acho que os códigos estão certos, mas não garanto, pq não testei nada... de qlqr forma o caminho é esse. :smiley:

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Matheus Tavares como que faço pra navegar entre as pastas utilizando o spl_autoload_register? Estou tentando aqui, porém ainda não consegui.

Eu consegui navegar entre as pastas e usar as classes normalmente usando namespaces + __autoload, porém o __autoload vai ser descontinuado futuramente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Rapaiz, acho que consegui, ficou dessa forma:

autoload/autoload.php

<?php

function autoloadClasses($class){

	$class = str_replace("\\" , "/" , dirname(__FILE__)) . "/" . str_replace("\\" , "/" , $class) . ".php";
	if(!file_exists($class)){
		throw new Exception("File path {$class} not found.");
	}

	require_once($class);
}
spl_autoload_register("autoloadClasses");

?>

autoload/index.php

<?php

require_once("../autoload_another_folder/autoload.php");


use classes\database\app\Foo;
use classes\Bar;

$f = new Foo();
echo "<br>";
$b = new Bar();


?>

../autoload_another_folder/database/app/Foo.php

<?php
namespace classes\database\app;
class Foo {
	public function __construct(){
		echo "Foo loaded";
	}
}

?>

pasta autoload contém: index.php e autoload.php

pasta ../autoload_another_folder contém: classes/database/app/Foo.php

 

Dessa forma consegui fazer a navegação nas pastas usando os namespaces + spl_autoload_register. Está certo dessa forma? Será preciso acrescentar ou remover algo?

 

Mais uma vez obrigado pela orientação matheuzão, valeu mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites
19 horas atrás, BrunoMs disse:

Está certo dessa forma? Será preciso acrescentar ou remover algo?

 

Aparentemente tá certinho sim... mas observe que para cada classe carregada pelo autoload você dispara um file_exists.

Essa função faz o que? Acessa seu disco (tarefa sabidamente lenta para qualquer linguagem ou sistema) e verifica a existência do arquivo.

 

O composer também possui essa implementação, mas antes de verificar se o arquivo existe no disco, ele consulta um array com todos os arquivos do seu sistema, que é gerado internamente por ele. Isso significa que a verificação não é feita no disco, mas no array, que fica em memória (mais rápido).

Veja mais sobre isso: https://pt.stackoverflow.com/questions/123097/qual-é-a-diferença-entre-o-dump-autoload-normal-e-o-otimizado-no-composer

 

Eu já consegui ganhos consideráveis em performance (em aplicações em produção) apenas por utilizar esse conceito.

 

Em suma: tá tudo certo, mas ainda recomendo o uso do composer... ou mais estudos e uma implementação manual disso que eu expliquei acima... A propósito, todo o código do Composer é em PHP simples (poucos arquivos) e você pode consultá-lo ao instalá-lo em sua máquina (para ver como ele implementa isso).

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 09/12/2017 at 18:47, Matheus Tavares disse:

Na verdade você não precisa usar namespaces. Eles são ótimos e eu recomendo, mas eles também trazem uma certa complexidade que nem sempre é necessária. O que eu quero dizer é que você pode ter um autoloader sem utilizar namespaces também.

 

Como eu disse, recomendo o uso do Composer. Veja essa série de vídeos: https://www.youtube.com/watch?v=_n57YVUVT2A

Esse tutorial também é interessante: https://tableless.com.br/composer-para-iniciantes/

 

 

O composer permitirá que você instale pacotes facilmente e já saia utilizando.

Exemplo:

1 - Você quer enviar e-mails autenticados com o PHP. Então você entra no https://packagist.org/ e procura por uma biblioteca.

2 - Você encontrou um tal de Phpmailer.

3 - Agora, supondo que você tenha instalado o composer na sua máquina e inicializado ele no seu projeto, você roda um "composer require phpmailer/phpmailer".

4 - Agora você chama apenas o composer no seu código, assim:


require 'vendor/autoload.php';

5 - Agora basta utilizar as bibliotecas que você instalou ou definiu para serem inicializadas pelo composer. Exemplo:


<?php
require 'vendor/autoload.php';

// perceba que agora eu já saio usando a biblioteca...

// essas barras é simplesmente pq o PHPMailer possui essa estrutura horrível
// você pode resolver o uso desse nome enorme com o 'use'
// Veja: http://php.net/manual/pt_BR/language.namespaces.importing.php
$mail = new PHPMailer\PHPMailer\PHPMailer;
$mail->setFrom('from@example.com', 'Your Name');
$mail->addAddress('myfriend@example.net', 'My Friend');
$mail->Subject  = 'First PHPMailer Message';
$mail->Body     = 'Hi! This is my first e-mail sent through PHPMailer.';
if(!$mail->send()) {
  echo 'Message was not sent.';
  echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
  echo 'Message has been sent.';
}

 

Os require_once são feitos pelo autoloader quando o PHP não encontrar uma classe, graças a essa função: spl_autoload_register()

 

Esse exemplo acima foi para você entender o propósito principal do Composer, mas ele também traz o recurso de autoload para o seu próprio projeto. Exemplo:

 

1 - Após ter lido o padrão PSR-4 e entendido como você deve organizar seus namespaces, você cria uma pasta, digamos, /src.

2 - Suas classes vão dentro dessa pasta e seu projeto se chama Tabajara, então decidiu que seu namespace vai começar assim. Resumindo: as classes do namespace Tabajara vão ser procuradas em /src.

3 - Agora você cria uma classe qualquer dentro dessa pasta e desse namespace:

 

/src/MinhaClasse.php (note o CamelCase)


<?php
namespace Tabajara;

class MinhaClasse {
    //...
}

 

4 - Agora, supondo que você tem o Composer instalado, você define essa estrutura de autoload para ele, em seu arquivo de configurações composer.json. Exemplo:


{
    "name": "empresa_do_bruno/tabajara",
    "description": "projeto tabajara",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Bruno",
            "email": "bruno@brunocorp.org"
        }
    ],
    "minimum-stability": "stable",
    "require": {
        "php": "^7"
    },
    "autoload": {
        "psr-4": {
            "Tabajara\\": "src/",
        },
        "files": [
            "src/um_arquivo_que_eu_quero_inicializar.php",
            "src/outro_arquivo.php"
        ]
    },
}

 

Feito isso, vamos usar:

 

/index.php


<?php
require 'vendor/autoload.php';

//Exemplo 1:
use Tabajara\MinhaClasse;
$tabajara = new MinhaClasse;

//Exemplo 2:
$tabajara = new Tabajara\MinhaClasse;

 

 

Expliquei utilizando o Composer pq é a melhor forma, mas você ainda pode implementar o autoloader você mesmo e ignorar o Composer... exemplo: http://www.php-fig.org/psr/psr-4/examples/

 

Obs: acho que os códigos estão certos, mas não garanto, pq não testei nada... de qlqr forma o caminho é esse. :smiley:

Vi todos os artigos que você enviou sobre composer, bom eu instalei o Composer queria saber como faço para utilizar minhas próprias classes vi esse seu mine tutorial segui ele passo a passo mais não funciona.

Meu composer.jason

{
    "name": "gas/composer",
    "description": "Website",
    "authors": [
        {
            "name": "Gleyson Abreu",
            "email": "gleyson_datu@hotmail.com"
        }
    ],
    "require": {
		"php": "^7"
	},
	"require-dev":{
		"phpunit/phpunit": "^4.3"
	},
    "autoload": {
        "psr-4": {
            "Bancodedados\\": "src/"
        },
        "files": [
            "src/database.class.php",
            "src/datauser.class.php"
        ]
    }
}

E sempre da esse erro:

Citar
( ! ) Fatal error: Class 'Bancodedados\DadosUser' not found in C:\wamp64\www\bancodedados\index.php on line 5
Call Stack
# Time Memory Function Location
1 0.0004 235648 {main}( ) ...\index.php:0

Meu php index:

	 	require 'vendor/autoload.php';
		$idLogado = 8;
		use Bancodedados\DadosUser;
		$user = new DadosUser($idLogado);
		$p = $user->dados();

Alguma luz?

Compartilhar este post


Link para o post
Compartilhar em outros sites
3 horas atrás, EdCesar disse:

@Gleyson Abreu, joia!

Dependendo da ordem que você fez as coisas, ou se alterou as informações da psr-4 no composer.json, basta executar o comando composer dump-autoload e tentar novamente.
 

Dica de ouro, siga padrões, siga as PSRs!
http://www.php-fig.org/

@EdCesar valeu cara ajudou bastante, nunca tinha mexido com o Composer, o erro foi solucionado com seu comando é seguindo os padrões, enfrentei outro erro com a conexão com o banco de dados PDO mais bastava somente por \ para apontar para raiz as bibliotecas do php.

Três dúvidas cruciais para me esclarecer mais um pouco se poder responder.

1° Toda vez que eu criar uma classe uma tenho que por ela no composer.json desta maneira: "src/classeblabla.php" ou tem alguma forma de só de criar na pasta src adicionar automático?

2° Toda vez que eu criar uma classe eu tenho que por namespace Bancodedados; , certo?

3° Toda vez que for instanciar uma classe chamo ela com "use Bancodedados\MinhaClasse;" ou  diretamente na classe $tabajara = new Bancodedados\MinhaClasse; como Matheus postou acima, certo?

Se houver algo para acrescente fique a vontade ;).

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 minutos atrás, Gleyson Abreu disse:

1° Toda vez que eu criar uma classe uma tenho que por ela no composer.json desta maneira: "src/classeblabla.php" ou tem alguma forma de só de criar na pasta src adicionar automático?

 

Não, somente se adicionar um namespace totalmente novo e que não está contido no existente.

 

Basicamente, tudo que estiver no namespace, Bancodedados ou abaixo dele, continuará utilizando a regra já existente. Mas, se você quiser criar um novo namespace, que utilize outro root do filepath, ai precisará adicionar. Como por exemplo


{
   "autoload": {
      "psr-4": {
         "Bancodedados\\": "src/",
         "Application\\": "Application/"
      }
   }
}

Mas, caso você adicione um subnamespace dentro de Bancodedados, basta apenas seguir com o caminho das pastas.

 

 

5 minutos atrás, Gleyson Abreu disse:

2° Toda vez que eu criar uma classe eu tenho que por namespace Bancodedados; , certo?

 

Sim, o namespace é especificado dentro de cada arquivo.

 

5 minutos atrás, Gleyson Abreu disse:

3° Toda vez que for instanciar uma classe chamo ela com "use Bancodedados\MinhaClasse;" ou  diretamente na classe $tabajara = new Bancodedados\MinhaClasse; como Matheus postou acima, certo?

Se houver algo para acrescente fique a vontade ;).

 

Indiferente. O use é para você "importar" e não ficar repetindo namespaces extremamente longos, além de poder criar um alias para melhorar e manter a clareza no escopo, como o seguinte:

 

<?php

namespace Foo;

use Foo\Bar\Model\User as UserModel;

Logo, quando for usar, sabe que Model\User é User Model.

$userModel = new UserModel();

Se não tivesse usado o Alias, a classe sera apenas User

$userModel = new User(); //Foo\Bar\Model\User

Você pode ler um pouco mais sobre isso aqui: 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por douglas79
      Bom dia,
       
      Estou seguindo uma vídeo aula no Youtube e o instrutor lá colocou uma sequência de div's (seja id ou class), o seletor background não funciona.

      Vou postar o código até o momento:
       
      @charset "utf-8";
       
      body, ul{padding:0;margin:0;background: #e2e2e2;list-style: none;}
      #geral{overflow: hidden;}
      #geral #topo{width:1018px;margin:0 auto;overflow: hidden;}
      #geral #topo #logo, #menuTopo{float:left;width:400px;}
      #geral #topo #logo{background:#ccc;}
      #geral #topo #menuTopo{}
      #geral #topo #menuTopo li{float:left;padding:5px;}

      Alguém pode me tirar essa dúvida???
      Desde já, agradeço!
    • Por Worn
      Fala rapaziada estou tendo alguma Warmi no meu sistema to batendo a cabeça aqui e não consigo resolver 
      https://prnt.sc/oqrcmy
       
      linha do erro
      <?php /* * Login Class * * Desenvolvido por Gabriel Neves * Seguir cotes de desenvolvimento * */ class Login { private $tabela, $campoID, $campoLogin, $campoSenha; function __construct($tabela = 'tbl_usuarios', $campoID = 'id', $campoLogin = 'email', $campoSenha = 'senha') { // Iniciando sessão session_start(); // Definindo atributos $this->tabela = $tabela; $this->campoID = $campoID; $this->campoLogin = $campoLogin; $this->campoSenha = $campoSenha; } // ------------------------------------------------------------------------ /* * Retornando login do usuário que está na sessão * * @access public * @return string */ function getLogin() { return $_SESSION[$this->campoLogin]; } // ------------------------------------------------------------------------ /** * Retornando ID do usuário que está na sessão * * @access public * @return integer */ function getID() { return $_SESSION[$this->campoID]; } // ------------------------------------------------------------------------ /** * Trata as informações recebidas, procura o usuário no banco de dados e, se encontrado, * registra as informações na sessão. * * @access public * @param string * @param string * @param string * @return boolean */ function logar($login, $senha, $redireciona = null) { // Tratando as informações $login = mysqli_real_escape_string($login); $senha = mysqli_real_escape_string($senha); // Verifica se o usuário existe $query = mysqli_query($conexao, "SELECT {$this->campoID}, {$this->campoLogin}, {$this->campoSenha} FROM {$this->tabela} WHERE {$this->campoLogin} = '{$login}' AND {$this->campoSenha} = '{$senha}'"); // Se encontrado um usuário if(mysqli_num_rows($query) > 0) { // Instanciando usuário $usuario = mysqli_fetch_object($query); // Registrando sessão $_SESSION[$this->campoID] = $usuario->{$this->campoID}; $_SESSION[$this->campoLogin] = $usuario->{$this->campoLogin}; $_SESSION[$this->campoSenha] = $usuario->{$this->campoSenha}; // Se informado redirecionamento if ($redireciona !== null) header("Location: {$redireciona}"); else return true; } else return false; } // ------------------------------------------------------------------------ /** * Verifica se o usuário está logado * * @access public * @param string * @return boolean */ function verificar($redireciona = null) { // Se as sessões estiverem setadas if(isset($_SESSION[$this->campoID]) and isset($_SESSION[$this->campoLogin]) and isset($_SESSION[$this->campoSenha])) return true; else { // Se informado redirecionamento if ($redireciona !== null) header("Location: {$redireciona}"); return false; } } // ------------------------------------------------------------------------ /** * Finaliza a sessão do usuário * * @access public * @param string * @return void */ function logout($redireciona = null) { // Limpa a Sessão $_SESSION = array(); // Destroi a Sessão session_destroy(); // Modifica o ID da Sessão session_regenerate_id(); // Se informado redirecionamento if ($redireciona !== null) header("Location: {$redireciona}"); } } ?>  
    • Por Guss
      A programadora Cafiaspirina Cruz deseja que todos os elementos <h2> de sua página ganhassem a classe "titulo", para que depois a fonte dos <h2> pudesse ser modificada por um CSS,  deixando-os com um destaque específico. Escreva abaixo um código em Javascript para que todos os <h2> da página ganhem a classe "titulo" de uma única vez?
    • Por Guss
      Agradeço quem puder me ajudar a responder essa questão de PHP <3.
      Desenvolva um programa utilizando PHP e  exibir os resultados desse programa que tenha todas as classes suficientes para que:
       
      Represente o nome completo de uma pessoa, composto de três strings (nome próprio, nome do meio e nome da família). 
       
      Escreva nessa classe o método rubrica que retorna somente as iniciais do nome completo em caracteres minúsculos,  Escreva nessa classe o método assinatura que retorna as iniciais dos nomes próprio e do meio (com pontos)  Escreva nessa classe um método que retorne o nome de família completo.  Por exemplo, se o nome da pessoa representado por essa classe for “Marijuana Pepsi Jackson”, o método rubrica deve retornar ”mpj” e o método assinatura deve retornar ”M.P.Jackson”. Para facilitar, considere armazenar os três nomes em strings separadas.
    • Por Guss
      Boa noite galera, to com um trabalho para entregar daqui a pouco e gostaria da ajuda de vocês a me ajudar a resolver essa questão:
      Desenvolva um programa utilizando PHP para exibir os resultados desse programa que tenha todas as classes suficientes para que:
       
      Exista uma classe DiferencaData, que possui um método chamado calculaDias, que recebe como parâmetro duas datas e calcula a diferença em dias entre essas datas. Considere que sempre a primeira data fornecida é maior do que a segunda. Considere para efeitos de simplificação que todo mês tem 30 dias e um ano com 365 dias
×

Informação importante

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