PDO를 사용해야하는 경우 첫 번째 단계는 DSN (데이터 소스 이름)을 올바르게 작성하는 것입니다. 이 기사는 공통 데이터베이스의 DSN 구문, 미스 포인트 및 모범 사례를 체계적으로 분류하고 직접 적용 할 수있는 예제 코드 및 검증 목록을 제공합니다.
DSN : PDO에게 어떤 드라이버 (MySQL, PGSQL, SQLITE…)를 알려줍니다. 어떤 라이브러리 및 기타 연결 매개 변수를 호스트합니다.
위치 : New PDO ($ dsn, $ username, $ password, $ 옵션)
구조 : <드라이버> : <key> = <value>; [<key> = <value>;…]
사례 민감도 : 드라이버 이름과 키 이름은 일반적으로 경우에 민감하지 않지만 값은 다릅니다 (예 : 파일 경로).
베이스:
<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>중요한 점 및 옵션 :
호스트 : 도메인 이름/IP를 사용할 수 있습니다. UNIX 소켓으로 이동하는 경우 unix_Socket =/path/mysql.sock을 사용 하고 호스트/포트를 다시 쓰지 마십시오 .
dbname : 대상 데이터베이스 이름.
Charset : UTF8MB4 로 설정하는 것이 좋습니다.
포트 : 생략 할 수 있고 기본값은 3306입니다.
SSL : MySQL/드라이버의 새 버전은 pdo :: mysql_attr_ssl_* 옵션과 결합 할 수 있습니다 (기사 끝의 "안전 및 성능 옵션"참조).
유닉스 소켓 예 :
<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>다중 매개 변수 스 플라이 싱 (Anti-Semi-Colon/Specialations)을위한 안전한 작문 방법 :
<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>베이스:
<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>핵심 사항 :
호스트는 경로 (Unix Domain 소켓 디렉토리, 일반적으로 /var/run/postgresql ) 일 수 있으며 현재 포트를 생략 할 수 있습니다.
문자 세트는 옵션 또는 연결 후 설정 이름을 실행하거나 옵션 = '-client_encoding = utf8'을 사용하는 것이 좋습니다.
일부 시나리오는 호스트 =/var/run/postgresql 의 쓰기 방법을 선호합니다.
유닉스 소켓 예 :
<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>파일 데이터베이스 :
<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>메모리 내 데이터베이스 :
<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>핵심 사항 :
경로에 공백이나 세미콜론이 포함 된 경우 실제 파일 경로에서 특수 문자를 피하는 것이 좋습니다. Windows에서 이중 백 슬래시 또는 슬래시 경로를 사용하십시오 : c : \\ data \\ db.sqlite 또는 c : /data/db.sqlite .
베이스:
<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>핵심 사항 :
서버는 호스트, 포트 또는 호스트 이름 \ 인스턴스를 쓸 수 있습니다.
pdo :: sqlsrv_attr_encoding 옵션을 통해 인코딩을 설정하는 것이 좋습니다.
TLS/암호화는 일반적으로 드라이버 옵션을 통해 전달됩니다 (기사 끝 참조).
이름이 지정된 예 :
<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>베이스:
<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>핵심 사항 :
dbname은 // 호스트에서 별명을 지원합니다 : port/service_name 또는 로컬 tnsnames.ora .
권장 AL32UTF8 인코딩.
<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>사양 : <드라이버> : key = value; key = value , 세미콜론은 분리기 입니다.
값에 세미콜론 (매우 드문 경우)이 포함될 수있는 경우 DSN에 넣지 않고 네 번째 매개 변수 $ 옵션 으로 변경하거나 세미콜론이없는 구성 메소드 (예 : 환경 변수 분포 및 철자 DSN)로 바꾸는 것이 좋습니다.
MySQL : DSN에서 charset = utf8mb4를 추가하는 것이 가장 직관적입니다. 복제를 피하기 위해 연결 후 이름을 설정 하지 마십시오 .
PostgreSQL : 옵션 에서 -client_encoding = utf8을 설정하거나 연결 후 Set Client_Encoding을 'UTF8'으로 사용하는 것이 좋습니다.
SQL Server : 옵션 PDO :: SQLSRV_ATTR_ENCODING (예 : SQLSRV_ENCODING_UTF8 ).
MySQL에서 unix_socket 및 호스트/포트를 사용하지 마십시오 .
PostgreSQL의 소켓은 호스트를 디렉토리를 가리키면 구현됩니다.
sqlite와 같은 파일 경로는 Windows에서 이중 백 슬래시 또는 전방 슬래시 를 사용하는 것이 좋습니다.
계정 비밀번호를 창고로 하드 코딩하지 마십시오.
.env : db_dsn = mysql : host =……
런타임 : $ 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">// 예외를 던지십시오,쉽게 찾을 수 있습니다</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">// 기본적으로 연관 배열을 반환합니다</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">// 운전자가 기본 전처리를 사용하도록하십시오(안전/더 안정적인 성능)</span></span><span>
];
</span><span><span class="hljs-comment">// MySQL SSL 예(운전자가 지원할 때):</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; // 확인을 건너 뛰어야하는 경우(권장되지 않습니다)</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>힌트:
전처리 진술을 결합 할 수 있습니까 ? 또는 SQL 주입을 피하기 위해 지명 된 자리 표시 자.
생산 환경은 TLS/SSL을 활성화해야합니다 (서버와 드라이버 간의 공동 지원이 필요).
<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">// 지원하다 host/port 또는 unix_socket,빈 값을 자동으로 필터링합니다</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">// 용법</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>드라이버가 설치되지 않습니다 : 드라이버를 찾을 수 없습니다 → PDO_MYSQL / PDO_PGSQL 등이 PHP -M 에 있는지 확인하십시오.
호스트 또는 포트 오류 : sqlstate [hy000] [2002] (MySQL) → 호스트/포트 또는 UNIX_Socket 확인.
데이터베이스는 존재하지 않습니다 . 알 수없는 데이터베이스 'XXX' → DBNAME 수정 또는 먼저 라이브러리를 만듭니다.
코딩 문제 : 갈색 코드가 나타납니다 → DSN/옵션의 문자 세트가 일관성이 있는지 확인합니다 (MySQL 사용 charset = utf8mb4 , pg sets client_encoding = utf8 ).
TLS/인증서 : SSL 핸드 셰이크 실패 → CA 경로 확인 서버에서 TLS가 활성화되어 있는지, 인증서는 도메인 이름과 일치합니다.
불충분 한 권한 : 권한 거부 또는 액세스 거부 → 대상 라이브러리의 사용자 이름/비밀번호, 사용자 권한을 확인합니다.
<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>
관련 태그:
PDO