Bonjour,
Ça fait 2 semaines que je galère avec l'auto-chargement de classes, je vous appel à l'aide.
J'ai suivi la formation "La POO en PHP", de Grafikart,
et le tutoriel "Composer", de Grafikart.
(au passage : MERCI pour les tutos, ils sont tous vraiment formidable)
Sources :
https://www.grafikart.fr/formations/programmation-objet-php
https://www.grafikart.fr/tutoriels/php/composer-480
Je rappel ici le "principe" de l'autochargement des classes, utilisé dans la formation :
// fichier : .../monSite/public/index.php
require ROOT . '/app/App.php';
App::load();
// fichier : .../monSite/app/App.php
// AUCUN NAMESPACE
use App\Config\Config;
// plein d'autres "use"
...
class App
{
...
public static function load()
{
require ROOT . '/app/Autoloader.php';
App\Autoloader::register();
}
...
}
// fichier : .../monSite/app/Autoloader.php
namespace App;
class Autoloader
{
static function register()
{
spl_autoload_register(array(__CLASS__, 'autoload'));
}
static function autoload($class_name)
{
if (strpos($class_name, __NAMESPACE__ . '\\') === 0)
{
$class_name = str_replace(__NAMESPACE__ . '\\', '', $class_name);
require __DIR__ . '/' . $class_name . '.php';
}
}
}
Tout fonctionne très bien.
Maintenant j'aimerai charger mes classes INTERNE (je n'en suis pas encore aux dépendences),
non plus par l'autoloader de la formation,
mais par l'autoloader de Composer.
Comme le tutoriel mentionné plus haut (sur Composer), ne parle que de la gestion des dépendances, et pas de l'autochargement des classes INTERNE,
je suis allé voir ce tuto :
http://thomas.bondois.info/installer-composer-sur-un-projet-web-pour-gerer-facilement-les-libraires-externes-et-internes/
À la partie : Bonus : Utiliser l’autoloader de Composer pour tes propres librairies
On peut lire :
"Si par exemple tu utilises les namespaces, et que tes classes de base sont dans /src/Acme/ et commencent par le namespace Acme/,
tandis que celles de tests unitaires sont dans /tests/Acme/ et commencent par le namespace Test/Acme/ :"
"autoload": {
"psr-4": {
"Acme\\": "src/Acme/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\Acme\\": "tests/Acme/"
}
}
MOI :
J'ai donc écris ce fichier composer.json :
// fichier : .../monSite/composer.json
{
"name": "test",
"autoload": {
"psr-4": {
"App\\": "App/"
}
}
}
puis, je n'ai pas oublié de faire un update dans la console :
composer update
ET,
j'ai commenté le chargement de l'autoloader de la formation :
// fichier : .../monSite/public/index.php
/* require ROOT . '/app/App.php';
App::load(); */
Fatal error: Uncaught Error: Class 'App\Router\Router' not found in C:\xampp\htdocs\work\monSite\public\index.php:45
Sachant que dans mon index.php :
...
use App\Router\Router;
$router = new Router(); // LIGNE 45
$router->getroad();
C'est la 1ère fois que j'essaie d'utiliser Composer, et visiblement je fais n'importe quoi... :'(
Je ne me décourage pas, mais ça devient difficile.
Si vous pouviez m'aider, ce serait formidable.
(J'aimerai réussir à utiliser Composer pour charger mes classes interne).
Merci.
Bonjour.
Si tu veux utiliser l'autoloader de composer pour charger tes classes, il ne te faut pas utiliser la fonction load
de ta classe App
et il te faut faire un require du fichier autoload.php qui se situe dans le dossier vendor.
Et puis dans ta classe App, il te faut définir le namespace, soit namespace App;
.
Par contre, je ne sais pas trop si ça peut avoir une influence ou pas, mais tu devrais respecter la casse pour le nom du dossier dans la déclaration du namespace, soit :
{
"name": "test",
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
Au lieu de :
{
"name": "test",
"autoload": {
"psr-4": {
"App\\": "App/"
}
}
}
La 1ère ligne m'intrigue, pourquoi "~5.2" alors que sur le PackageList j'avais vu "v6.0.0rc2"
rc
veut dire Release Candidate
. C'est une version qui est susceptible de partir en release, mais encore en phase de test.
Ensuite, quand tu installes une dépendance avec Composer, pas besoin de charger un autoloader particulier, Composer se charge de tout.
Enfin, Tu as oublié le namespace \
$mail = new \PHPMailer;
Ah SUPER ça fonctionne bien ça y est, merci Lartak.
Il me manquait le require du fichier autoload.php.
Bon sang, c'est comme si j'étais en apnée depuis 2 semaines et que je pouvai enfin respirer ^^
Et merci aussi intelligid pour le conseil, je ne connaissais pas dump-autoload.
Mais en fait ensuite je voulais utiliser PHPMailer, donc je vais aussi utiliser les dépendences.
D'ailleurs,
je met le sujet en résolu mais si je peux me permettre, j'ai du mal à utiliser une classe EXTERNE maintenant...
En suivant le tuto sur Composer,
je suis allé sur Packaglist,
et j'ai fais une recherche sur "PHPMailer",
parmis les choix proposés, j'ai sélectionné celui qui avait LARGEMENT le plus de download :
https://packagist.org/packages/phpmailer/phpmailer
Je vois qu'il y a :
J'ai donc modifié mon composer.json de cette façon :
{
"name": "test",
"require": {
"phpmailer/phpmailer": "v6.0.0rc2"
},
"autoload": {
"psr-4": {
"App\\": "App/"
}
}
}
composer update
Ça m'a créer le dossier :
.../monSite/vendor/phpmailer/phpmailer/
Toujours sur PackageList, j'ai cliqué sur le lien vers le github de PHPMailer (sur la droite).
Sur github,
https://github.com/PHPMailer/PHPMailer
je descend à la partie : A Simple Example
<?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
...
???
J'ai fais une recherche, aucun des fichiers dans vendor/phpmailer/phpmailer/ ne s'appelle "PHPMailerAutoload.php"
Alors toujours sur la page du github, je remonte un peu, et à la partie Installation & loading, je vois :
PHPMailer is available via Composer/Packagist (using semantic versioning), so just add this line to your composer.json file:
"phpmailer/phpmailer": "~5.2"
or
composer require phpmailer/phpmailer
La 1ère ligne m'intrigue, pourquoi "~5.2" alors que sur le PackageList j'avais vu "v6.0.0rc2",
je décide d'utiliser la 2ème méthode pour voir... (plus tard j'ai essayé la 1ère méthode, et ça donne exactement pareil)
j'écris ça dans la console :
composer require phpmailer/phpmailer
et j'update
composer update
OK j'ai toujours le dossier vendor/phpmailer/phpmailer, mais cette fois au moins, dedans j'ai : "PHPMailerAutoload.php" (OUF)
Du coup, en me RE-référant à la partie A Simple Example du github, j'écris comme code :
<?php
namespace App\Controller;
class UsersController extends AppController
{
...
require ROOT . 'vendor/phpmailer/phpmailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
...
}
J'étais CERTAINS que ça allait fonctionner,
mais j'ai eu comme erreure :
Fatal error: Uncaught Error: Class 'App\Controller\PHPMailer' not found in C:\xampp\htdocs\work\start20\app\Controller\UsersController.php:222
la ligne 222 étant :
$mail = new PHPMailer;
Voilà donc,
PackageList, et Github, ne semblent pas donner les même instructions (je crois), et que j'essaie de suivre celles de l'un ou de l'autre, je n'arrive pas à mes fins...
Est-ce que je fais encore n'importe quoi ? :'(
Ah d'accord !
Bon sang xD
Super, tout fonctionne et j'ai bien compris maintenant.
Merci intelligid.