Si vous avez besoin d'utiliser PDO, la première étape consiste à écrire correctement le DSN (nom de la source de données). Cet article régle synthématique la syntaxe DSN, les points faciles à manquer et les meilleures pratiques des bases de données courantes, et fournit une liste d'exemples de codes et vérifications qui peuvent être appliqués directement.
DSN : raconte à PDO quel pilote (MySQL, PGSQL, SQLITE…), quel hôte, quelle bibliothèque et d'autres paramètres de connexion auxquels se connecter.
Emplacement : Nouveau APD ($ DSN, Nom d'utilisateur $, $ Password, $ Options)
Structure : <Diver>: <Key> = <value>; [<Key> = <value>;…]
Sensibilité à la casse : les noms de pilotes et les noms de clés ne sont généralement pas sensibles à la casse, mais la valeur est différente (comme les chemins de fichier).
Base:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'mysql:host=127.0.0.1;port=3306;dbname=app;charset=utf8mb4'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>, [
PDO::</span><span><span class="hljs-variable constant_">ATTR_ERRMODE</span></span><span> => PDO::</span><span><span class="hljs-variable constant_">ERRMODE_EXCEPTION</span></span><span>,
]);
</span></span>Points et options importantes:
Hôte : le nom de domaine / IP est disponible; Si vous allez sur Unix Socket, utilisez Unix_Socket = / Path / MySQL.Sock et n'écrivez pas à nouveau hôte / port.
DBNAME : Nom de la base de données cible.
Charset : il est fortement recommandé de régler sur UTF8MB4 .
Port : peut être omis, la valeur par défaut est 3306.
SSL : La nouvelle version de MySQL / Driver peut être combinée avec l'option PDO :: MYSQL_ATTR_SSL_ * (voir "Options de sécurité et de performance" à la fin de l'article).
Exemple de socket Unix:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=app;charset=utf8mb4'</span></span><span>;
</span></span>Méthode d'écriture sûre pour l'épissage multi-paramètres (antisémi-colon / caractères spéciaux):
<span><span><span class="hljs-variable">$params</span></span><span> = [
</span><span><span class="hljs-string">'host'</span></span><span> => </span><span><span class="hljs-string">'db.internal'</span></span><span>,
</span><span><span class="hljs-string">'port'</span></span><span> => </span><span><span class="hljs-number">3306</span></span><span>,
</span><span><span class="hljs-string">'dbname'</span></span><span> => </span><span><span class="hljs-string">'app'</span></span><span>,
</span><span><span class="hljs-string">'charset'</span></span><span> => </span><span><span class="hljs-string">'utf8mb4'</span></span><span>,
];
</span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'mysql:'</span></span><span> . </span><span><span class="hljs-title function_ invoke__">implode</span></span><span>(</span><span><span class="hljs-string">';'</span></span><span>, </span><span><span class="hljs-title function_ invoke__">array_map</span></span><span>(
fn(</span><span><span class="hljs-variable">$k</span></span><span>,</span><span><span class="hljs-variable">$v</span></span><span>) => </span><span><span class="hljs-variable">$k</span></span><span> . </span><span><span class="hljs-string">'='</span></span><span> . </span><span><span class="hljs-title function_ invoke__">str_replace</span></span><span>(</span><span><span class="hljs-string">';'</span></span><span>, </span><span><span class="hljs-string">'\;'</span></span><span>, (</span><span><span class="hljs-keyword">string</span></span><span>)</span><span><span class="hljs-variable">$v</span></span><span>),
</span><span><span class="hljs-title function_ invoke__">array_keys</span></span><span>(</span><span><span class="hljs-variable">$params</span></span><span>),
</span><span><span class="hljs-variable">$params</span></span><span>
));
</span></span>Base:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'pgsql:host=127.0.0.1;port=5432;dbname=app'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span></span>Points clés:
L'hôte peut être un chemin d'accès (répertoire de socket de domaine UNIX, généralement / var / run / postgresql ), et le port peut être omis pour le moment.
Le jeu de caractères est recommandé pour exécuter des noms de définition après des options ou une connexion, ou d'utiliser des options = '- client_encoding = utf8' .
Certains scénarios préfèrent la méthode d'écriture de host = / var / run / postgresql .
Exemple de socket Unix:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">"pgsql:host=/var/run/postgresql;dbname=app"</span></span><span>;
</span></span>Base de données de fichiers:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'sqlite:/path/to/database.sqlite'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>);
</span></span>Base de données en mémoire:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'sqlite::memory:'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>);
</span></span>Points clés:
Lorsque le chemin contient des espaces ou des demi-colons, il est recommandé d'éviter les caractères spéciaux dans le chemin du fichier réel; Utilisez des barres à barres doubles ou des chemins de barre de barrage sous Windows: C: \\ data \\ db.sqlite ou c: /data/db.sqlite .
Base:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'sqlsrv:Server=127.0.0.1,1433;Database=app'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span></span>Points clés:
Le serveur peut écrire l'hôte, le port ou le nom d'hôte \ instance .
Il est recommandé de définir le codage via les options: PDO :: SQLSRV_ATTR_ENCODING .
TLS / Encryption est généralement transmis par les options du conducteur (voir la fin de l'article).
Exemples nommés:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'sqlsrv:Server=WIN-SRV\\SQLEXPRESS;Database=app'</span></span><span>;
</span></span>Base:
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'oci:dbname=//127.0.0.1:1521/ORCL;charset=AL32UTF8'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span></span>Points clés:
Dbname prend en charge les alias dans // hôte: port / service_name ou tnsnames local.ora.
Encodage AL32UTF8 recommandé.
<span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=APP;HOSTNAME=127.0.0.1;PORT=50000;PROTOCOL=TCPIP;'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span></span> <span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-string">'firebird:dbname=localhost:/path/to/db.fdb;charset=UTF8'</span></span><span>;
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span></span>Spécification: <Deuvre>: Key = Value; Key = Value , Semicolon est un séparateur .
Si la valeur peut contenir un point-virgule (très rare), il est recommandé de ne pas le fourrer dans le DSN, mais de passer aux options du quatrième paramètre $ ou de la remplacer par une méthode de configuration sans point-virgule (comme la distribution des variables environnementales, puis l'orthographe DSN).
MySQL : Il est plus intuitif d'ajouter Charset = UTF8MB4 dans DSN; Ne définissez pas les noms après la connexion pour éviter la duplication.
PostgreSQL : il est recommandé de définir --Client_Encoding = UTF8 dans les options , ou d'utiliser SET Client_encoding sur 'UTF8' après la connexion.
SQL Server : Définissez l'option PDO :: SQLSRV_ATTR_ENCODING (comme SQLSRV_ENCODING_UTF8 ).
N'utilisez pas Unix_Socket et Host / Port dans MySQL.
La prise de PostgreSQL est implémentée en pointant l'hôte d'un répertoire.
Des chemins de fichier tels que SQLite sont recommandés d'utiliser des backslashs doubles ou des barres obstruées sur Windows: C: \\ Path \\ db.sqlite ou c: /path/db.sqlite .
Ne code pas le mot de passe du compte dans l'entrepôt:
.env : db_dsn = mysql: host =…; dbname =…; charset = utf8mb4
Runtime: $ PDO = new PDO (GETENV ('DB_DSN'), GETENV ('DB_USER'), GETENV ('DB_PASS'));
<span><span><span class="hljs-variable">$opts</span></span><span> = [
PDO::</span><span><span class="hljs-variable constant_">ATTR_ERRMODE</span></span><span> => PDO::</span><span><span class="hljs-variable constant_">ERRMODE_EXCEPTION</span></span><span>, </span><span><span class="hljs-comment">// Faire une exception,Facile à localiser</span></span><span>
PDO::</span><span><span class="hljs-variable constant_">ATTR_DEFAULT_FETCH_MODE</span></span><span> => PDO::</span><span><span class="hljs-variable constant_">FETCH_ASSOC</span></span><span>, </span><span><span class="hljs-comment">// Renvoie le tableau associatif par défaut</span></span><span>
PDO::</span><span><span class="hljs-variable constant_">ATTR_EMULATE_PREPARES</span></span><span> => </span><span><span class="hljs-literal">false</span></span><span>, </span><span><span class="hljs-comment">// Laissez le conducteur utiliser le prétraitement natif(Sécurité/Performance plus stable)</span></span><span>
];
</span><span><span class="hljs-comment">// MySQL SSL Exemple(Lorsque le conducteur support):</span></span><span>
</span><span><span class="hljs-variable">$opts</span></span><span>[PDO::</span><span><span class="hljs-variable constant_">MYSQL_ATTR_SSL_CA</span></span><span>] = </span><span><span class="hljs-string">'/etc/ssl/certs/ca.pem'</span></span><span>;
</span><span><span class="hljs-comment">// $opts[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = false; // Si vous avez besoin de sauter la vérification(Pas recommandé)</span></span><span>
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-variable">$dsn</span></span><span>, </span><span><span class="hljs-variable">$user</span></span><span>, </span><span><span class="hljs-variable">$pass</span></span><span>, </span><span><span class="hljs-variable">$opts</span></span><span>);
</span></span>indice:
Les déclarations de prétraitement peuvent être combinées avec ? ou des espaces réservés nommés pour éviter l'injection de SQL.
L'environnement de production doit activer TLS / SSL (nécessite un co-soutien entre le serveur et le pilote).
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">build_mysql_dsn</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">array</span></span></span><span> </span><span><span class="hljs-variable">$cfg</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
</span><span><span class="hljs-comment">// soutien host/port ou unix_socket,Filtrez automatiquement les valeurs vides</span></span><span>
</span><span><span class="hljs-variable">$parts</span></span><span> = [];
</span><span><span class="hljs-variable">$parts</span></span><span>[] = </span><span><span class="hljs-keyword">isset</span></span><span>(</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'unix_socket'</span></span><span>])
? </span><span><span class="hljs-string">'unix_socket='</span></span><span> . </span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'unix_socket'</span></span><span>]
: </span><span><span class="hljs-string">'host='</span></span><span> . (</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'host'</span></span><span>] ?? </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-keyword">empty</span></span><span>(</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'unix_socket'</span></span><span>]) && !</span><span><span class="hljs-keyword">empty</span></span><span>(</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'port'</span></span><span>])) {
</span><span><span class="hljs-variable">$parts</span></span><span>[] = </span><span><span class="hljs-string">'port='</span></span><span> . (</span><span><span class="hljs-keyword">int</span></span><span>)</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'port'</span></span><span>];
}
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-keyword">empty</span></span><span>(</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'dbname'</span></span><span>])) {
</span><span><span class="hljs-variable">$parts</span></span><span>[] = </span><span><span class="hljs-string">'dbname='</span></span><span> . </span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'dbname'</span></span><span>];
}
</span><span><span class="hljs-variable">$parts</span></span><span>[] = </span><span><span class="hljs-string">'charset='</span></span><span> . (</span><span><span class="hljs-variable">$cfg</span></span><span>[</span><span><span class="hljs-string">'charset'</span></span><span>] ?? </span><span><span class="hljs-string">'utf8mb4'</span></span><span>);
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-string">'mysql:'</span></span><span> . </span><span><span class="hljs-title function_ invoke__">implode</span></span><span>(</span><span><span class="hljs-string">';'</span></span><span>, </span><span><span class="hljs-variable">$parts</span></span><span>);
}
</span><span><span class="hljs-comment">// usage</span></span><span>
</span><span><span class="hljs-variable">$dsn</span></span><span> = </span><span><span class="hljs-title function_ invoke__">build_mysql_dsn</span></span><span>([
</span><span><span class="hljs-string">'host'</span></span><span> => </span><span><span class="hljs-string">'db.internal'</span></span><span>,
</span><span><span class="hljs-string">'port'</span></span><span> => </span><span><span class="hljs-number">3306</span></span><span>,
</span><span><span class="hljs-string">'dbname'</span></span><span> => </span><span><span class="hljs-string">'app'</span></span><span>,
</span><span><span class="hljs-string">'charset'</span></span><span> => </span><span><span class="hljs-string">'utf8mb4'</span></span><span>,
]);
</span><span><span class="hljs-comment">// new PDO($dsn, $user, $pass, $opts);</span></span><span>
</span></span>Le pilote n'est pas installé : Impossible de trouver le pilote → Vérifiez s'il y a PDO_MYSQL / PDO_PGSQL , etc. dans PHP -M .
Erreur d'hôte ou de port : SqlState [Hy000] [2002] (MySQL) → Vérifiez l'hôte / port ou Unix_socket .
La base de données n'existe pas : la base de données inconnue 'xxx' → corriger dbname ou créer la bibliothèque d'abord.
Problème de codage : le code brouillé apparaît → Confirmer que les jeux de caractères dans l'option DSN / sont cohérents (MySQL utilise charset = utf8mb4 , pg sets client_encoding = utf8 ).
TLS / CERTIFICATE : SSL FALCHAKE FAILS → Vérifiez le chemin CA, si TLS est activé sur le serveur, et le certificat correspond au nom de domaine.
Autorisations insuffisantes : autorisation refusée ou accès refusé → Vérifiez le nom d'utilisateur / mot de passe, autorisation d'utilisateur dans la bibliothèque Target.
<span><span>MySQL
mysql:host=HOST;port=3306;dbname=DB;charset=utf8mb4
mysql:unix_socket=/path/mysql.sock;dbname=DB;charset=utf8mb4
PostgreSQL
pgsql:host=HOST;port=5432;dbname=DB
pgsql:host=/var/run/postgresql;dbname=DB
SQLite
sqlite:/absolute/path/to/db.sqlite
sqlite::memory:
SQL Server
sqlsrv:Server=HOST,1433;Database=DB
sqlsrv:Server=HOST\INSTANCE;Database=DB
Oracle
oci:dbname=//HOST:1521/SERVICE;charset=AL32UTF8
Db2
ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=DB;HOSTNAME=HOST;PORT=50000;PROTOCOL=TCPIP;
Firebird
firebird:dbname=HOST:/path/to/db.fdb;charset=UTF8
</span></span>
Étiquettes associées:
PDO