Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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.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.>
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.'; echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo; 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()](http://php.net/manual/pt_BR/function.spl-autoload-register.php)
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](http://www.php-fig.org/psr/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/](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. @Matheus Tavares que aula irmão, obrigado pela orientação, já já começo os testes e vou seguindo o que você disse e lendo os links com calma.
Valeu matheuzão.
@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.
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.>
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).
>
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.'; echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo; 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()](http://php.net/manual/pt_BR/function.spl-autoload-register.php)
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](http://www.php-fig.org/psr/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/](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. *
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?@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/
>
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 ;).
>
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:
>
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