まず、これら2つの方法の使用を簡単に確認しましょう。
MySQLIでは、 SET_CHARSETメソッドを使用して、MySQLデータベースに接続するときに文字セットを設定します。たとえば、文字セットをUTF-8に設定するには、これを行うことができます。
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_error) {
die("接続に失敗しました: " . $mysqli->connect_error);
}
$mysqli->set_charset("utf8");
この方法により、接続を通じて実行されるすべてのクエリが指定された文字セットを使用します。
PDOでは、文字設定は通常DSNで直接指定されますが、接続後に動的に調整する必要がある場合は、 SetAttributeメソッドを使用できます。一般的な使用法は次のとおりです。
$dsn = 'mysql:host=localhost;dbname=database;charset=utf8';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
];
$pdo = new PDO($dsn, 'user', 'password', $options);
この時点で、文字セットはPDO :: MySQL_ATTR_INIT_COMMANDを介して設定され、データベースに接続するときにUTF-8エンコードが使用されるようにします。
mysqli :: set_charsetとpdo :: setattributeは両方ともキャラクターセットを設定するために使用できますが、特に一緒に使用する必要がある場合、特定の使用と効果に違いがあります。
MySQLIとPDOを使用してデータベースに接続する場合、文字セットを設定するタイミングは非常に重要です。 MySqliの場合、キャラクターセットの設定はできるだけ早く実行する必要があり、接続を確立した直後に設定することをお勧めします。後続のクエリでキャラクターセットを変更すると、一貫性のない文字セットを引き起こす可能性があり、その結果、文字化けされた問題が発生します。
PDOの場合、接続中にDSNを介して設定された文字を設定することが通常、最も適切なアプローチです。セット後のセットにsetattributeメソッドを使用することは可能ですが、これは実行されたクエリをオーバーライドしない場合があるため、接続を作成するときに文字セットを直接指定することをお勧めします。
同じアプリケーションでMySQLIとPDOの両方を使用し、同じデータベース接続を共有する場合(たとえば、両方の方法がリクエストのさまざまな部分で使用されます)、文字セットの競合に特に注意する必要があります。たとえば、 MySQLIとPDOの文字セット設定は独立しており、それぞれのクエリにそれぞれ影響します。接続がMysqliのUTF-8に設定されている場合、 PDOではLATIN1では、一貫性のない文字エンコードパフォーマンスが発生する可能性があります。
キャラクターセットの競合を避けるために、いくつかの提案されたソリューションとベストプラクティスを次に示します。
可能であれば、同じリクエストでmysqliとPDOの両方を使用しないでください。データベース操作を実行する方法のいずれかを選択することをお勧めします。これにより、文字セット設定の均一性が保証されます。たとえば、 PDOの使用は、より柔軟で複数のデータベースタイプをサポートするため、データベースアクセスインターフェイスとして推奨されます。
MySQLIまたはPDOを使用するかどうかにかかわらず、すべてのデータベース接続で同じ文字セット設定を使用してください。マルチデータベース接続の場合、各接続を使用して一貫性を確保するために、各接続を使用することをお勧めします。
より複雑なアプリケーションの場合、データベース構成でデフォルトの文字セットを均一に設定することをお勧めします。たとえば、データベースサーバー上のデフォルトの文字セットをUTF-8に設定して、アプリケーションの文字設定を削減できます。