<?php // //declare(strict_types=1); // //namespace Database; // ///** // * Classe permettant de retourner une instance unique et configurée de PDO. // * // * Ceci permet de ne pas multiplier les connexions au serveur de base de données. // * L'instance peut être configurée de trois façons, utilisées dans cet ordre jusqu'à obtenir une configuration valide : // * - programmatique ; MyPDO::setConfiguration(DSN, username, password) // * - variables d'environnement ; MYPDO_DSN, MYPDO_USERNAME et MYPDO_PASSWORD // * - fichier ; [APP_DIR/].mypdo[.MYPDO_ENV].ini où APP_DIR et MYPDO_ENV sont des variables d'environnement // * // * @startuml // * // * namespace Database { // * class MyPdo { // * - {static} dsn : string // * - {static} username : string := '' // * - {static} password : string := '' // * - {static} options : array := [] // * // * - __construct(\n\tdsn : string,\n\tusername : string := null,\n\tpassword : string := null,\n\toptions : array := null) // * - private __clone() : void // * + {static} getInstance() : MyPdo // * + {static} setConfiguration(\n\tdsn : string,\n\tusername : string := '',\n\tpassword : string := '',\n\toptions : array := []) : void // * - {static} hasConfiguration() : bool // * - {static} setConfigurationFromEnvironmentVariables() : bool // * - {static} setConfigurationFromIniFile() : bool // * } // * } // * // * Database\\MyPdo -left-|> PDO // * Database\\MyPdo "1" *-- "1\n-<u>myPdoInstance</u>" Database\\MyPdo : contains // * // * @enduml // */ //final class MyPdo extends \PDO //{ // /** // * Instance unique de PDO. // */ // private static self $myPdoInstance; // // /** // * DSN pour la connexion BD. // */ // private static string $dsn; // // /** // * Nom d'utilisateur pour la connexion BD. // */ // private static string $username = ''; // // /** // * Mot de passe pour la connexion BD. // */ // private static string $password = ''; // // /** // * Options du pilote BD. // */ // private static array $options = [ // \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, // \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, // ]; // // /** // * Constructeur privé. // * // * Seule la classe MyPDO peut construire une instance de MyPDO. // * // * @param string $dsn DSN pour la connexion BD // * @param string|null $username Utilisateur pour la connexion BD // * @param string|null $password Mot de passe pour la connexion BD // * @param array|null $options Options du pilote BD // */ // private function __construct(string $dsn, ?string $username = null, ?string $password = null, ?array $options = null) // { // parent::__construct($dsn, $username, $password, $options); // // La base de données est-elle de type SQLite // if ('sqlite' === $this->getAttribute(\PDO::ATTR_DRIVER_NAME)) { // // Activer les clés étrangères qui sont désactivées par défaut // $this->exec('PRAGMA foreign_keys = ON'); // } // } // // /** // * Empêcher le clonage, le singleton doit rester unique. // */ // private function __clone(): void // { // } // // /** // * Point d'accès à l'instance unique. // * // * L'instance est créée au premier appel et réutilisée aux appels suivants. // * // * @return self Instance unique de MyPdo // * // * @throws \PDOException Si la configuration n'a pas été effectuée // */ // public static function getInstance(): self // { // // Instance de la classe présente ? // if (!isset(self::$myPdoInstance)) { // // Configuration effectuée ? // if (!self::hasConfiguration() // && !self::setConfigurationFromEnvironmentVariables() // && !self::setConfigurationFromIniFile()) { // throw new \PDOException(__CLASS__.': Configuration not set'); // } // // Construire une instance // self::$myPdoInstance = new self(self::$dsn, self::$username, self::$password, self::$options); // } // // return self::$myPdoInstance; // } // // /** // * Fixer programmatiquement la configuration de la connexion à la BD. // * // * @param string $dsn DSN pour la connexion BD // * @param string $username Utilisateur pour la connexion BD // * @param string $password Mot de passe pour la connexion BD // * @param array $options Options du pilote BD // * // * @throws \PDOException Si la variable d'environnement APP_DIR est utilisée, mais n'est pas définie // */ // public static function setConfiguration( // string $dsn, // string $username = '', // string $password = '', // array $options = [], // ): void { // self::$dsn = $dsn; // self::$username = $username; // self::$password = $password; // self::$options = $options + self::$options; // // // Remplacer %APP_DIR% par le chemin de l'application si SQLite est utilisé // if (preg_match('/^(.*)(%APP_DIR%)(.*)$/', $dsn, $matches)) { // if (!($appDir = getenv('APP_DIR'))) { // throw new \PDOException(__CLASS__.': APP_DIR environment variable not set'); // } // self::$dsn = $matches[1].$appDir.$matches[3]; // } // } // // /** // * Vérifier si la configuration de la connexion à la BD a été effectuée. // */ // private static function hasConfiguration(): bool // { // return isset(self::$dsn); // } // // /** // * Lire la configuration depuis des variables d'environnement. // * // * Les variables sont : // * - MYPDO_DSN pour le DSN // * - MYPDO_USERNAME pour le nom d'utilisateur // * - MYPDO_PASSWORD pour le mot de passe. // * // * @return bool Vrai si la configuration a été trouvée // * // * @throws \PDOException Si self::setConfiguration() échoue // */ // private static function setConfigurationFromEnvironmentVariables(): bool // { // // DSN ? // $dsn = getenv('MYPDO_DSN', true); // if (false !== $dsn) { // // username et password facultatifs // $username = getenv('MYPDO_USERNAME', true) ?: ''; // $password = getenv('MYPDO_PASSWORD', true) ?: ''; // self::setConfiguration($dsn, $username, $password); // // return true; // } // // return false; // } // // /** // * Lire la configuration depuis un fichier ini. // * // * Le nom du fichier peut être : // * - ".mypdo.ini" // * - ".mypdo<.environment_name>.ini" (environment_name dans la variable d'environnement MYPDO_ENV) // * Le fichier peut être placé : // * - dans un répertoire accessible (https://www.php.net/manual/fr/ini.core.php#ini.include-path) // * - dans le répertoire défini par la variable d'environnement APP_DIR // * Le fichier contient : // * [mypdo] // * dsn = ... // * username = ... // * password = ... // * // * @return bool Vrai si la configuration a été trouvée // * // * @throws \PDOException Si le fichier des paramètres est invalide // */ // private static function setConfigurationFromIniFile(): bool // { // // Environnement MyPdo défini ? // $myPdoEnv = getenv('MYPDO_ENV', true) ?: ''; // // Chemin du fichier en fonction de APP_DIR // $appDir = getenv('APP_DIR'); // $directory = false !== $appDir ? $appDir.DIRECTORY_SEPARATOR : ''; // $parameterFile = sprintf('%s.mypdo%s.ini', $directory, $myPdoEnv ? ".$myPdoEnv" : ''); // // Lecture du fichier de configuration // $parameters = @parse_ini_file($parameterFile, true); // if (false !== $parameters) { // if (!isset($parameters['mypdo'])) { // throw new \PDOException('`mypdo` section not found in `'.basename($parameterFile).'`'); // } // if (!isset($parameters['mypdo']['dsn'])) { // throw new \PDOException('`dsn` not found in `'.basename($parameterFile).'`'); // } // $dsn = $parameters['mypdo']['dsn']; // // username et password facultatifs // $username = $parameters['mypdo']['username'] ?? ''; // $password = $parameters['mypdo']['password'] ?? ''; // self::setConfiguration($dsn, $username, $password); // // return true; // } // // return false; // } //} // ///* Exemple de configuration et d'utilisation // //use Database\MyPdo; // //MyPDO::setConfiguration('mysql:host=mysql;dbname=cutron01_music;charset=utf8', 'web', 'web'); // //$stmt = MyPDO::getInstance()->prepare( // <<<'SQL' // SELECT id, name // FROM artist // ORDER BY name //SQL //); // //$stmt->execute(); // //while (($ligne = $stmt->fetch()) !== false) { // echo "<p>{$ligne['name']}\n"; //} //*/