Partage
  • Partager sur Facebook
  • Partager sur Twitter

Autoloder un fichier

probleme d'inclusion de classe grace à un autoload

23 juin 2020 à 12:09:33

Bonjour à tous , je suis sur un projet dans laquel je veux autoloder mes classes grace à un autoloder chose que je n'arrive pas a faire

Voici l'architecture de mes fichiers

- un dossier "controllers" contenant le fichier "contact.php"

Voici le code de contact.php

<?php

$db = DBFactory::getMysqlConnexionWithPDO();
$managerContact = new ContactsManagerPDO($db);

if(isset($_GET['modifier']))
{
	$contacts = $managerContact->getUnique((int) $_GET['modifier']);
}

if (isset($_GET['supprimer'])) {
	$managerContact->delete((int) $_GET['supprimer']);
	$message = 'les informations ont été supprimer !!';
}

if (isset($_POST['name'])){
	$contacts = new Contacts(
		[
			'name' => $_POST['name'],
			'entreprise' => $_POST['entreprise'],
			'email' => $_POST['email'],
			'telephone' => $_POST['telephone'],
			'message' => $_POST['message']
		]);

	if(isset($_POST['id_message']))
	{
		$contacts->setIdMessage($_POST['id_message']);
	}

	if($contacts->isValid())
	{
		$managerContact->save($contacts);

		$message = $contacts->isNew() ? 'Les informations ont été envoyées !' : 'Les informations ont été modifiées avec succes !';
	}
	else
	{
		$erreurs = $contacts->erreurs();
	}
}



-un dossier "Lib" contenant mes fichiers

       *autoload.php

Voici le code 

function autoload($classname){
	if (file_exists($file = __DIR__ . '/' .$classname. '.php')) {
		require $file;
	}
}

spl_autoload_register('autoload');

       *Contacts.php

      *ContactsManager.php

      *ContactsManagerPDO.php

     *DBFactory.php

Voici le code

class DBFactory

{

public static function getMysqlConnexionWithPDO(){

$db = new PDO('mysql:host=localhost; dbname=db_odjike', 'root', '');

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

return $db;

}

}

- un dossier "View" qui contient le fichier "Contact.view.php"

Et un fichier "Contact.php" qui est à la racine du projet dans lequel j'ai inclure mes fichiers comme ceci

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

require'Controllers/Contacts.php';
require'views/contact.view.php';

Le probleme se trouve au niveau des inclusions ici bas ,Car voici l'erreur que php me revoie

Fatal error: Uncaught Error: Class 'DBFactory' not found in C:\xampp\htdocs\ODJIKE\ODJIKE-SA-GROUPE3\controllers\Contacts.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\ODJIKE\ODJIKE-SA-GROUPE3\controllers\Contacts.php on line 9


Quelqu'un peut-il m'aider ????

  • Partager sur Facebook
  • Partager sur Twitter
23 juin 2020 à 13:36:35

Tu peux corriger la mise en forme de ton post stp histoire que ce soit plus clair ?

Tu devrais supprimer le file_exists [de l'autoload], au moins, s'il y a une erreur de chemin, ça fera planter le require et ça permettra de savoir lequel a été utilisé.

Sur Unixoïde, ton code ne fonctionnera : le répertoire s'appelle controllers mais tu fais require'Controllers/Contacts.php';

> - un dossier "controllers" contenant le fichier "contact.php"

Il s'appelle contact.php ou Contacts.php ce contrôleur ?

> - un dossier "View" qui contient le fichier "Contact.view.php"

Pareil, ça ne colle pas avec require'views/contact.view.php';

Le message d'erreur parle de la ligne 9, c'est 3 sur ton code ?

Tes fichiers sont mal organisés par rapport à l'autoload : ce serait mieux pensé, ton autoload ne serait pas limité à charger les classes de son propre répertoire. Ca t'épargnerait les require de tes contrôleurs et vues tout en lui donnant plus de sens : à quoi bon avoir un autoload si c'est pour charger une partie des classes à la main ?

Question débile : il y a bien les balises PHP dans le fichier Lib/autoload.php ?

-
Edité par julp 23 juin 2020 à 13:53:21

  • Partager sur Facebook
  • Partager sur Twitter
23 juin 2020 à 16:16:01

Merci julp j'ai enlever le "file_existe de mon autoload.php

le code

<?php
function autoload($classname){
	
	$file = __DIR__ . '/' .$classname. '.php';
	
		require $file;

}

spl_autoload_register('autoload');

Consernant le dossier "controllers" il contient "contacts.php" et non contact.php

- En ce qui conserne le dossier Views : il s'agit de "Views/Contact.view.php" et non" View"

Consernant l'emplacement du fichier autoload.php, je pense que pour que les classes puissent etre enregistrer automatiquement il faut que le fichier "autoload.php" et les classe à autoloader soient dans le meme dossier dans le car contraire, je dois donc creer le fichier autoloader.php dans un autre dossier ou quoi , je ne sais pas trop. bref je vais remettre le code montrant le message d'erreur

Le fichier "Contacts.php" placé dans le dossier "controllers.php"

<?php

$db = DBFactory::ConnexionPDO();
$managerContact = new ContactsManagerPDO($db);

if(isset($_GET['modifier']))
{
	$contacts = $managerContact->getUnique((int) $_GET['modifier']);
}

if (isset($_GET['supprimer'])) {
	$managerContact->delete((int) $_GET['supprimer']);
	$message = 'les informations ont été supprimer !!';
}

if (isset($_POST['name'])){
	$contacts = new Contacts(
		[
			'name' => $_POST['name'],
			'entreprise' => $_POST['entreprise'],
			'email' => $_POST['email'],
			'telephone' => $_POST['telephone'],
			'message' => $_POST['message']
		]);

	if(isset($_POST['id_message']))
	{
		$contacts->setIdMessage($_POST['id_message']);
	}

	if($contacts->isValid())
	{
		$managerContact->save($contacts);

		$message = $contacts->isNew() ? 'Les informations ont été envoyées !' : 'Les informations ont été modifiées avec succes !';
	}
	else
	{
		$erreurs = $contacts->erreurs();
	}
}

Le message d'erreur

Erreur fatale : erreur non interceptée: classe 'DBFactory' introuvable dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php: 3 Trace de pile: # 0 {main} levée dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php sur la ligne 3





  • Partager sur Facebook
  • Partager sur Twitter
23 juin 2020 à 16:24:35

Soit ton autoload n'intervient pas soit ton fichier Lib/DBFactory.php est bien chargé mais celui-ci ne déclare pas une classe nommée DBFactory.

Essaie voir d'ajouter un var_dump($classname); dans ta fonction d'autoload ?

-
Edité par julp 23 juin 2020 à 16:25:30

  • Partager sur Facebook
  • Partager sur Twitter
23 juin 2020 à 18:38:37

Quand j'ajoute "var_dump($classname)" voici le message d'erreur qui s'affiche

string (9) "DBFactory"
Erreur fatale : erreur non interceptée: classe 'DBFactory' introuvable dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php: 3 Trace de pile: # 0 C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ contact.php (4): require () # 1 {main} jeté dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php on ligne 3

mon ficchier Lib/DBFactory contient bien une classe nommée DBFactory . je reenvoie le code

<?php
namespace Lib;

class DBFactory
{
	public static function ConnexionPDO(){
		$db = new PDO('mysql:host=localhost; dbname=db_odjike', 'root', '');
		$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

		return $db;
	}
}

je ne sais vraiment pas oû se situe l'erreur cela fait maintenant des heures que je ne peux pas bouger


  • Partager sur Facebook
  • Partager sur Twitter
23 juin 2020 à 18:44:40

Ah oui mais non, ce n'est pas du tout le même code, le namespace Lib; change absolument tout : tel qu'était fait ton projet au départ, on ne devrait pas trouver de namespace dans ton fichier.

Sinon ta classe n'est plus DBFactory mais Lib\DBFactory (= il faut un use Lib\DBFactory; ou écrire (\)Lib\DBFactory::getMysqlConnexionWithPDO() et pas simplement DBFactory::getMysqlConnexionWithPDO() dans controllers/contacts.php) et ça implique alors que DBFactory soit dans un sous-répertoire nommé Lib par rapport à celui de ton autoload (puisque ce dernier se base sur __DIR__ pour inclure) - à moins de déplacer l'autoload à la racine au lieu de le mettre dans Lib/ ou d'adapter/bidouiller les chemins lors pour le require de l'autoload.

-
Edité par julp 23 juin 2020 à 18:54:00

  • Partager sur Facebook
  • Partager sur Twitter
24 juin 2020 à 12:44:04

Bonjour julp Merci pour ta disponibilité. j'ai essayé avec le namespace mais l'erreur persiste toujours. je veux donc partir de la base ou il n'y avait pas de namespace .j'ai donc cree le fichier "autoload" à la racine et adapter le chemin a mes classes mais toujours pareil

le code de autoload.php

<?php
function autoload($classname){

	$file = __DIR__ . 'Lib' .$classname. '.php';
	
		require $file;
		var_dump($classname);

}

je le require dans "contact.php

<?php 
require'autoload.php';

require'controllers/Contacts.php';
require'views/contact.view.php';

toujours meme erreurs

Erreur fatale : erreur non interceptée: classe 'DBFactory' introuvable dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php: 3 Trace de pile: # 0 C: \ xampp \ htdocs \ ODJIKE \ ODJIKE -SA-GROUPE3 \ contact.php (4): require () # 1 {main} jeté dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ controllers \ Contacts.php sur la ligne 3


J'aimerais savoir si c'est l'organisation de mes fichiers qui n'est pas bonne ou quoi .Si oui comment devrais je les organiser pour le code fonctionne 

  • Partager sur Facebook
  • Partager sur Twitter
24 juin 2020 à 13:31:37

Ce ne devrait pas être Lib/ ?

Tu as viré le spl_autoload_register, non ?

Parce que l'autoload n'a pas l'air d'entrer en action. Ou alors tu as laissé le namespace Lib; dans DBFactory.php ?

Déjà ça aiderait d'avoir un point d'entrée unique pour ton application. C'est lui qui mettrait en place l'autoload. Cet autoload se chargerait de require toutes les classes dynamiquement, tu n'aurais pas à en faire une partie à la main.

Ensuite, soit tu utilises des namespace ou non mais il faut en avoir compris le concept :

  • il faut utiliser le FQDN de tes classes et/ou les "déclarer" par des use : tu ne peux pas utiliser DBFactory (sans un use préalable j'entends) si ta classe est dans le namespace Lib, elle s'appelle Lib\DBFactory pas DBFactory
  • il faut que l'arborescence de tes fichiers suivent celui des noms de tes classes (enfin, ce n'est pas obligé mais si tu galères déjà, tu vas ramer encore plus). Si ta classe (FQDN) s'appelle Controllers\Admin\UserManager.php : ça donne un fichier UserManager.php dans les sous-répertoires Controllers > Admin C'est surtout ce dernier point qui est important, plus tôt tu structures ton projet, moins ça te demandera à modifier comme déplacer tes scripts.

EDIT : ok, je n'y avais pas véritablement prêté attention, tes contrôleurs ne sont pas des classes du coup tu es obligé de les charger à la main :/ Effectivement, ça en serait des classes, tu pourrais les charger automatiquement.

EDIT2 : si mon aide n'est pas appréciée, tu aurais au moins pu le dire avant d'aller reposter ailleurs mine de rien ...

-
Edité par julp 25 juin 2020 à 11:38:53

  • Partager sur Facebook
  • Partager sur Twitter
25 juin 2020 à 13:05:09

salust julp je suis desolé p our avoir eu a poster ailleurs mais puisque je n'arrive pas à trouvé la solution , je me suis donc dire que se serait encore mieux de poster le sujet sur deux forum differents , comme ça je pourais peut etre avoir une reponse approche. Mille excuses 

Si je reviens au sujet, j'ai toujours un message d'erreur

Consernant l'utlisation de "use" je pensais que qu'il etait neccessaire lors d'un heritage 

par exemple dans mon projet la classe ContactsManager herite de la classe ContactsManagerPDO , le "use" va nous permettre ici de require le fichier ContactsManger comme ceci 

<?php
namespace Lib;
 
use \Lib\ContactsManager;
class ContactsManagerPDO extends ContactsManager 
{

Mais consernant la classe DBFactory elle n'herite d'aucune autre classe je ne sais donc pas comment utilisé le "use" sur cette classe

Lorsque je met les namespaces Lib sur mes classes il y a toujours erreurs

 -DBFactory

<?php
namespace Lib;
class DBFactory
{
	public static function ConnexionPDO(){
		$db = new PDO('mysql:host=localhost; dbname=db_odjike', 'root', '');
		$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

		return $db;
	}

	
}

-autoload

<?php
function autoload($classname){

	$file = __DIR__ . '/Lib/' .$classname. '.php';
	
		require $file;
		var_dump($classname);

}
spl_autoload_register('autoload');

-Contacts.php

<?php
$db = Lib\DBFactory::ConnexionPDO();
$managerContact = new ContactsManagerPDO($db);

l'erreur

Avertissement : nécessite (C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 / Lib / Autoloader.php): échec d'ouverture du flux: aucun fichier ou répertoire de ce type dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA- GROUPE3 \ autoload.php sur la ligne 6

Erreur fatale : require (): Échec de l'ouverture requise 'C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 / Lib / Autoloader.php' (include_path = 'C: \ xampp \ php \ PEAR ') dans C: \ xampp \ htdocs \ ODJIKE \ ODJIKE-SA-GROUPE3 \ autoload.php sur la ligne 6







  • Partager sur Facebook
  • Partager sur Twitter
25 juin 2020 à 13:37:32

En même temps, difficile de donner une solution quand tu ne donnes pas les vrais codes complets ... La première fois, il manquait le namespace Lib;, pourtant un élément clé. La deuxième fois, le spl_autoload_register('autoload'); était passé à l'as.

> Concernant l’utilisation de "use" je pensais que qu'il était nécessaire lors d'un héritage

Non, use ici (hors Trait) ça sert à aliaser une classe. Un use (\)Lib\DBFactory; te permet ensuite d'écrire DBFactory tout court sinon tu ne peux pas utiliser DBFactory tout court, tu aurais à écrire (\)Lib\DBFactory partout à la place (bon, c'est pour simplifier parce que ça dépend aussi du namespace courant éventuellement). Et ça doit être fait pour toutes les classes utilisées dans le script, ça n'est pas valable que pour celle en extends.

use c'est bien pour définir un alias, use Foo\Bar; vaut en fait use Foo\Bar as Bar; (on alias la classe "Foo\Bar" par "Bar") et qu'en as tu pourrais mettre ce qui te chante (use Foo\Bar as Truc;).

> $file = __DIR__ . '/Lib/' .$classname. '.php';

Tu n'as pas à mettre Lib/ ici, avec namespace Lib; dans DBFatory, c'est déjà inclus dans le nom de ta classe => il suffit de regarder la valeur du paramètre $classname de ta fonction d'autoload.

Ensuite soit autoload est à la racine et tu dois utiliser $file = __DIR__ . '/' .$classname. '.php'; soit il est dans Lib/ comme au départ et tu dois en utiliser $file = __DIR__ . '/../' .$classname. '.php';

Avec un (\)Lib\DBFactory et non simplement DBFactory dans les scripts qui utilisent cette classe à moins de d'abord faire un use (\)Lib\DBFactory; dans celles-ci.

-
Edité par julp 25 juin 2020 à 13:53:16

  • Partager sur Facebook
  • Partager sur Twitter
16 avril 2021 à 12:47:36

bonjour, 

svp j'ai un souci lorsque je fais une communication serie RS232 avec le langage PHP sa m'affiche cette erreur

Erreur fatale: Erreur non enseignée : Classe « phpSerial » in trouvable dans C:\xampp\htdocs\port\ok.php:16 Trace de pile: #0 {main} jeté en C:\xampp\htdocs\port\ok.php sur la ligne 16

  • Partager sur Facebook
  • Partager sur Twitter
16 avril 2021 à 13:08:31

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter

Pas d'aide concernant le code par MP, le forum est là pour ça :)