[RESOLU] PHPMailer et Autoloader

SLK
Petit nouveau ! | 8 Messages

05 juin 2016, 00:20

Bonjour,

J'ai une structure MVC, avec un auto-chargement des classes et namespaces.

L'autoloader fonctionne bien.

Maintenant pour envoyer des e-mails, j'aimerai me passer de la fonction mail(), pour utiliser à la place la bibliothèque PHPMailer.

Le problème c'est que quand j'essaie d'instancier PHPMailer, c'est MON autoloader qui essaie de s'en charger, alors qu'il faudrait que ça soit l'autoader de PHPMailer qui le fasse.

Ce que je fais :
namespace App\Controller;
class UsersController extends AppController
{
    public function newAccount()
    {
        ...
        // j'ai essayé de "require" l'autoloader de PHPMailer juste avant, en espérant que ça le fasse, mais non.
        require ROOT . '/Vendors/PHPMailer/PHPMailerAutoload.php';
        $mail = new \PHPMailer;
        ...
    }
}
La ligne (226) :
$mail = new \PHPMailer;
me donne cette erreur :
Fatal error: Uncaught Error: Class 'PHPMailer' not found in
C:\xampp\htdocs\work\monSite\app\Controller\UsersController.php:226
C'est la 1ère fois que j'essaie d'utiliser une classe extérieur, et je ne sais pas comment je dois m'y prendre.
Si vous pouvez m'aider, merci à vous.

----------------------------------------------------------------------------------------------------------

Je donne le chemin de quelques fichiers au cas où ce serait utile :
C:\xampp\htdocs\work\monSite\app\Autoloader.php
C:\xampp\htdocs\work\monSite\Vendors\PHPMailer\PHPMailerAutoload.php
C:\xampp\htdocs\work\monSite\public\index.php

et mon autoloader (je ne sais pas si c'est important) :
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';
        }
    }
}

Mammouth du PHP | 985 Messages

13 juin 2016, 09:48

Si tu as monté PHPMailer avec composer , alors c'est l'autoload de celui-ci que tu dois utiliser :

Code : Tout sélectionner

require __DIR__.'/vendor/autoload.php'; $mail = new PHPMailer();
L'expérience est la somme de toutes nos erreurs.

SLK
Petit nouveau ! | 8 Messages

13 juin 2016, 10:15

Salut Maitrepylos,

Merci pour ton aide.

En fait non je n'ai pas utilisé Composer.
J'ai téléchargé les sources sur gitHub :
https://github.com/PHPMailer/PHPMailer

Et j'ai mis tout ça dans un dossier : monSite/Vendors/PHPMailer

Mammouth du PHP | 985 Messages

13 juin 2016, 10:19

Et sans le slash ?

Code : Tout sélectionner

//$mail = new \PHPMailer; $mail = new PHPMailer;
L'expérience est la somme de toutes nos erreurs.

SLK
Petit nouveau ! | 8 Messages

13 juin 2016, 10:28

Sans le slash

Code : Tout sélectionner

$mail = new PHPMailer;
Comme mon controller est situé dans le namespace :

Code : Tout sélectionner

namespace App\Controller;
Il essaie de charger PHPMailer depuis ce namespace, en utilisant l'autoloader de mon site (ce qui n'est pas bon).
Ce qui me donne comme erreur : (en gras : le namespace du controller, en souligné: le "new")
Fatal error: require(): Failed opening required 'C:\xampp\htdocs\work\monSite\app/Controller\PHPMailer.php'

Mammouth du PHP | 985 Messages

13 juin 2016, 10:30

Il faut alors ajouter le namespace de PHPMailler avec un use !
L'expérience est la somme de toutes nos erreurs.

SLK
Petit nouveau ! | 8 Messages

13 juin 2016, 11:48

J'avais pensé à ça mais je bloque parce-que les fichiers que j'ai téléchargé de PHPMailer n'ont pas de namespaces eux.

Par exemple dans le dossier de PHPMailer je vois que j'ai comme fichiers (entre autres) :
- /Vendors/PHPMailer/PHPMailerAutoload.php
- /Vendors/PHPMailer/class.phpmailer.php
- /Vendors/PHPMailer/class.phpmaileroauth.php
- /Vendors/PHPMailer/class.pop3.php
- /Vendors/PHPMailer/class.smtp.php
...

Dans ces fichiers que j'ai téléchargé, il n'y a pas de namespace.

Est-ce qu'il faut :
- que je rentre dans tous ces fichiers pour leur mettre des namespaces, et utiliser MON autoloader pour les charger dans mon application ?
OU
- que j'arrive à charger l'autoloader de PHPMailer, et c'est lui qui chargera les fichiers dont il aura besoin

Si c'est la 2ème solution, j'imaginais qu'en mettant un :

Code : Tout sélectionner

require ROOT . 'Vendors/PHPMailer/PHPMailerAutoload.php';
devant mon "new PHPMailer"

Code : Tout sélectionner

$mail = new PHPMailer();
ça irai, mais non.

Je ne vois toujours pas comment faire.
Désolé, j'ai du mal.

Mammouth du PHP | 985 Messages

13 juin 2016, 11:54

Fais seulement un require de ce fichier /Vendors/PHPMailer/class.phpmailer.php cela devrais être bon.
L'expérience est la somme de toutes nos erreurs.

SLK
Petit nouveau ! | 8 Messages

13 juin 2016, 12:07

J'ai essayé ça :

Code : Tout sélectionner

require ROOT . 'Vendors/PHPMailer/class.phpmailer.php'; $mail = new PHPMailer();
Mais il bug toujours en essayant de charger le "new PHPMailer" depuis le namespace courant.
J'ai comme erreur :
Fatal error: require(): Failed opening required 'C:\xampp\htdocs\work\monSite\app/Controller\PHPMailer.php'

Mammouth du PHP | 985 Messages

13 juin 2016, 14:17

Je viens de tester ceci et ça fonctionne :

Code : Tout sélectionner

require_once './Vendor/PHPMailer/class.phpmailer.php'; $mail = new PHPMailer(); echo '<pre>'; var_dump($mail); echo '</pre>' ; /** * object(PHPMailer)#1 (75) { ["Version"]=> string(6) "5.2.16" ["Priority"]=> NULL ["CharSet"]=> string(10) "iso-8859-1" ["ContentType"]=> string(10) "text/plain" ["Encoding"]=> string(4) "8bit" ["ErrorInfo"]=> string(0) "" ["From"]=> string(14) "[email protected]" ["FromName"]=> string(9) "Root User" ["Sender"]=> string(0) "" ["ReturnPath"]=> string(0) "" ["Subject"]=> string(0) "" ["Body"]=> string(0) "" ["AltBody"]=> string(0) "" ["Ical"]=> string(0) "" ["MIMEBody":protected]=> string(0) "" ["MIMEHeader":protected]=> string(0) "" ["mailHeader":protected]=> string(0) "" ["WordWrap"]=> int(0) * * * *
L'expérience est la somme de toutes nos erreurs.

SLK
Petit nouveau ! | 8 Messages

13 juin 2016, 15:27

Ben oui mais moi j'ai mon autoloader qui me bloque.

Quand je fais un "new" de quoi que ce soit, ça fait appel à mon autoloader.
C'était super pratique jusqu'à présent, mais maintenant que je veux utiliser une classe "extérieure" à mon application (comme PHPMailer) ça me fou des bâtons dans les roues.

Dès que je fais un new, dont

Code : Tout sélectionner

new PHPMailer
ça fait appel à mon autoloader :

Code : Tout sélectionner

// 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'; } } }
Je ne vois pas comment m'en sortir. Pourtant je suis sur que c'est tout bête.
Ça me prends la têêête ! #-o
Ça fait tellement longtemps que je bloque la dessus :cry:

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

14 juin 2016, 17:23

salut,
sans namespace : new \PHPMailer()
si tu met ça dans vendor/phpmailer y a des chances que tu doivent modifier les fichiers (ajout namespace PHPMailer) pour que cela fonctionne avec ton autoload. Le but étant que les fichiers de phpmailer collent aux tiens.
Je te déconseille la modif des sources pour éviter les problèmes en cas de mise à jour.

tu peux avoir plusieurs fonction d'autoload et en ajouter une pour phpmailer ;)

@+
Il en faut peu pour être heureux ......

SLK
Petit nouveau ! | 8 Messages

15 juin 2016, 12:47

D'accord,

bon du coup je pense que je fais n'importe quoi là...

En relisant le sujet au début, je me suis rappelé que maitrepylos m'a parlé de Composer.
Alors je suis allé suivre des tutos dessus, et il me semble que ça va être ma solution.

En ce qui concerne le chargement de MES classes, je vais commencer par virer mon autoloader pour utiliser celui de composer.
Quand ça fonctionnera, je pourrai rajouter des classes extérieur (comme PHPMailer) facilement grâce à Composer.

Merci pour votre aide, je pense que je vais m'en sortir maintenant.

Merci.

Petit nouveau ! | 1 Messages

16 sept. 2016, 23:42

Salut Maitrepylos,

Merci pour ton aide.

En fait non je n'ai pas utilisé Composer.
J'ai téléchargé les sources sur gitHub :
https://github.com/PHPMailer/PHPMailertransfers paris airports

Et j'ai mis tout ça dans un dossier : monSite/Vendors/PHPMailer
Bonjour, merci beaucoup pour vos aides, c'est précieux