このアプローチの使用に根本的な欠陥はありますか?
最初に理解しなければならないことは、それがストレージロジック$pdo
の一部であるということです。つまり、SQL テーブルであれコレクションであれ、抽象データ アクセスを行うクラス内でのみ使用する必要があります。
コードを見てみましょう。
function somefunction(){
global $pdo;
$statement = $pdo->prepare("some query");
$statement->execute();
}
将来、MySQL から Mongo/MSSQL/PgSQL に切り替えたい場合はどうしますか? 次に、多くのコードを書き直す必要があります。
また、データベース ベンダーごとに、異なる変数を使用して個別のファイルを作成する必要があります。ちょうどこのような
function somefunction(){
global $mongo;
return $mongo->fetch(...);
}
グローバル状態を使用すると、パラメーターを渡すことができず、実行時に関数の動作を変更できないため、大量のコードの重複が発生します。
では、これを見てみましょう。
function somefunction($pdo){
$statement = $pdo->prepare("some query");
$statement->execute();
}
ここで$pdo
は、引数として渡されるため、グローバルな状態はありません。しかし、問題は残ります。単一責任の原則に違反することになります。
保守可能で、クリーンで、非常に読みやすいものが本当に必要な場合は、DataMappersを使用することをお勧めします。これが例です。
$pdo = new PDO(...);
$mapper = new MySQL_DataMapper($pdo);
$stuff = $mapper->fetchUserById($_SESSION['id'])
var_dump($stuff); // Array(...)
// The class itself, it should look like this
class MySQL_DataMapper
{
private $table = 'some_table';
private $pdo;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
public function fetchUserById($id)
{
$query = "SELECT * FROM `{$this->table}` WHERE `id` =:id";
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(
':id' => $id
));
return $stmt->fetch();
}
}
結論
プロジェクトが小さいか大きいかは問題ではありません。すべての形式 (グローバル変数、静的クラス、シングルトン) で常にグローバル状態を避ける必要があります -コードの保守性のために
$pdo
これはビジネス ロジックの一部ではないことを覚えておく必要があります。ストレージロジックの一部です。つまり、重い計算など、ビジネス ロジックで何かを開始する前に、テーブル アクセス (CRUD 操作を含む) を実際に抽象化する必要があります。
data access abstraction
あなたとあなたをつなぐ架け橋computation logic
は通常サービスと呼ばれます
常に関数の必要性をパラメータとして渡す必要があります
コードについて心配するのをやめて、抽象化レイヤーについて考え始めたほうがよいでしょう。
最後に、何らかの処理を開始する前に、まずすべてのサービスを初期化し、ユーザーの入力 (または)bootstrap.php
に従ってストレージのクエリを開始します。$_POST
$_GET
と同じように、
public function indexAction()
{
$id = $_POST['id']; // That could be $this->request->getPost('id')
$result = $this->dataMapper->fetchById($id);
return print_r($result, true);
}