Bonjour,
J'ai un petit soucis de compréhenssion avec les namespaces,
Je m'explique j'ai créer un code qui à cette arborescence :
[..] Test
index. php
[...] app
article.php
//index.php
<?php
include 'app/article.php';
use calendar\holiday;
$saturday = new holiday();
$saturday -> check_day("saturday");
?>
// article.php
<?php
namespace calendar;
class holiday{
public function check_day($check_day){
echo "$check_day is a holiday";
}
}
?>
j'obtiens : saturday is a holiday.
J'ai donc créer un : namespace qui s'appel calendar dans mon fichier article.
J'inclus mon fichier article qui est dans le dossier app.
Et je fais appel à la class holiday grâce à use.
Mais à quoi cela sert d'inclure mon fichier article.php si j'importe ou plutôt on me permet grâce au namespace d'utiliser la class que je souhaite ?
Et si je fais un use calendar cela me permet d'utiliser toutes les fonctions dans le fichier article.php ou dois-je en PHP 7 appeler chaque classe que j'aurai besoin?
Je crée une nouvelle classe pour palier au problème lors de l'initialisation de la Database,
fichier Connect.php, je le rajoute au namespace App
<?php
namespace App;
class Con{
const DB_NAME = 'blog';
const DB_USER = 'root';
const DB_PASS = '';
const DB_HOST = 'localhost';
private static $database;
public static function getDb(){
if( self::$database === null ){
self::$database = new App\Database(self::DB_NAME, self::DB_USER, self::DB_PASS, self::DB_HOST);
}
return self::$database;
}
}
j'utilise ensuite le use App pour utiliser ma classe con, puis je fais un require du fichier Connect. php :
<?php
use App\Con;
require '../app/Connect.php';
foreach (App\Con::getDb()->query('SELECT * FROM articles', 'App\Table\Article') as $post): ?>
<h2><a href="<?= $post->getURL() ?>"><?= $post->titre; ?></a></h2>
<p><?= $post->getExtrait(); ?></p>
<?php endforeach; ?>
Cela me retourne sur : localhost/pages/home.php :
Fatal error: Uncaught Error: Call to undefined method App\Con::getDb() in C:\xampp\htdocs\Blog\pages\home.php:8 Stack trace: #0 {main} thrown in C:\xampp\htdocs\Blog\pages\home.php on line 8
Et forcement sur l'index : localhost/public/index.php :
Fatal error: Uncaught Error: Call to undefined method App\Con::getDb() in C:\xampp\htdocs\Blog\pages\home.php:8 Stack trace: #0 C:\xampp\htdocs\Blog\public\index.php(24): require() #1 {main} thrown in C:\xampp\htdocs\Blog\pages\home.php on line 8
Au secours xS...
Bonsoir.
Tu pourrais par exemple visionner les tutoriels Tutoriel PHP » Composer et Tutoriel PHP » Autoloader PSR-0 / PSR-4, ce qui t'aiderait à mieux comprendre comment utiliser les namespace
.
Bonsoir Lartak,
J'ai bien visionner les 2 vidéos mais ça va trop vite pour moi et il y a trop de dossier\dossier\dossier....
l'exemple n'est pas simple pour un débutant et le contexte est mal choisi.
J'ai visionner cette vidéo qui m'aide un peu
Mais j'ai énormément de mal à faire le raprochement avec le tuto MVC POO, je suis perdu dans les app et App et dossier qui porte le même nom.
C'est une horreur, 3 jours que je suis dessus, alors j'ai recopié le code betement pour voir si ça marcher, mais même la c'est la cata.
Le tuto n'est pas fait sur windows, j'ai l'impression qu'il y a des collisions ou que la mises a jour (PHP 7) à changer la donne, le tuto étant fait sur une version antérieur.
J'ai essayé d'exploiter la doc :
Sur un exemple simple cela fonctionne je réussi à faire mes namespace mais use mais sur le tuto MVC,c'est l'échec, cela me renvoie des erreurs liés au namespaces.
Je vais persister, je vais finir par trouver.
Je te remercie pour ton aide.
Le tuto n'est pas fait sur windows, j'ai l'impression qu'il y a des collisions
Nope, justement, les namespaces évitent les collisions.
que la mises a jour (PHP 7) à changer la donne
Nope
Pour faire simple, dit toi que ton namespace
doit être égale à ton chemin de fichier. Cette façon de faire est normée par le PSR-4. Petit exemple tout bête.
Imaginons l'architecture de dossier suivante :
+ public
+ src
L + Controllers
L + PagesController.php
L + PostsController.php
L + Models
L + Views
La première étape va être de charger composer
pour bénéficier de son autoloader
.
$ composer init
Ensuite, il va faloir dire à composer comment autoloader nos fichiers.
On va lui dire que notre namespace App
contiendra nos sources située dans src
, en gros, quand on fera des use App\...
il ira chercher les classes dans le dossier src
et pas ailleurs.
composer.json
{
...
"autoload": {
"psr-4": {
"App\\": "src"
}
}
}
Puis on génère l'autoloader
$ composer dump-autoload
La seconde étape va être d'écrire notre code
src/Controllers/PagesController.php
Notre fichier se trouvant dans le répertoire src/Controller
, il devra donc être dans le namespace App\Controllers
.
<?php
namespace App\Controllers;
class PagesController
{
public function index()
{
echo 'Hello World !';
}
}
public/index.php
Dans ce fichier, on va require
l'autoloader qui se chargera d'inclure les bons fichiers. Attention, si tes chemins ne sont pas égaux à tes namespaces, les fichiers ne seront pas trouvés.
<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';
use App\Controllers\PagesController;
$pagesController = new PagesControllers;
$pagesController->index();
Après ça, si tu utilises wamp, rend toi sur le répertoire de ton site dans le répertoire public
et tu devrais voir afficher Hello World !.
OU ALORS en ligne de commande (si tu y as accès)
php -S localhost:8000 -t public/ -d error_reporting=1 -d display_errors=1
et rend toi à l'adresse http://localhost:8000
Voilà, un petit exemple, j'ai essayé d'être le plus simple possible. Si t'es débutant, n'essaie pas de regarder les tutos avec beaucoup de classes, concentre toi sur la notion d'autoloader et de namespace, une fois maîtrisé, tu pourras passer à plus difficile.
Ce système de namespace est la base de toutes les bonnes apps web en php.
Bonjour Balsakup,
Merci pour tes explications, je vais étudier sa en profondeur.
J'ai une question dans le tuto Poo, il est utilisé le même namespace App plusieurs fois.
Je m'explique, mes fichiers ont cette arborescence:
+ public
+ app
L + Autoloader.php namespace /App
L + Database.php namespace /DataB <--- Est-ce une bonne manière de faire ? je suis dans le dossier app.
+ Public
L + Index.php
+ Pages
... etc
A t'on le droit d'avoir le même namespace App pour le fichier Database.php et Autoloader.php ?
Pour moi chaque namespace doit être unique, je me trompe ?
Le namespace peut etre utiliser comme ceci dans mon fichier index.php :
<?php
use App\Autoloader;
use DataB\Database; (pour utiliser ma classe Database)
require ../app/Autoloader.php;
require ../app/Database.php'; ( pour inclure le fichier Database)
...
?>
Mais si je fais un use pour utiliser la classe ex: Autoloader;
Ai-je besoin de require mes fichiers ?
Oui, ils peuvent être dans le même namespace.
C'est le namespace + le nom de la classe qui doivent être unique.
Je pense avoir compris cela marche sur mon projet.
Mais je ne comprends pas les différences entre un require et un namespace.
Le namespace sert à ce que j'utilise une classe ou une methode ou des classes et des groupes de methodes.
Mais quand j'importe mon fichier avec un require, celui-ci n'est pas sensé faire la même chose ?
J'ai accès à des classeq et leurs méthodes/fonctions grâce à l'importation du ou des fichiers, non ?
Oups, je n'avais pas vue ta réponse, si je peux les mettre dans le même namespace.
namespace App; // Pour mon fichier Database.php et Autoloader.php
// je peux faire un :
use App; // Et pourvoir utiliser les classes qui sont dans mes fichiers Database.php et Autoloader.php
Du coup j'importe 2 namespaces en un, je fais du regroupement.
Parcontre je dois utiliser mes classes comme ceci : App\Database ... et App\Autoloader ... toujours en spécifiant le namespace ou plutôt directement avec Database... et Autoloader ?
Quand je cherche à utiliser ma class Database cela me retourne une erreur fatal:
J'ai fais une namespace App sur le fichier Database.php
J'ai fais un use App\Database sur le fichier index.php pour utiliser ma classe Database
et j'appel ma classe comme ceci :
// inititialisation des objects
$db = new App\Database('blog');
Fatal error: Cannot declare class App\Database, because the name is already in use in C:\xampp\htdocs\Blog\app\Database.php on line 7
C'est troublant...