モデルの D 部分は比較的基本的なため、最初に D 部分を作成しました。
D で最も重要なことはドライバー クラスの作成です。ドライバー クラスでログを使用する必要があるため、最初に単純な Logger クラスを作成します。静的メソッドは 1 つだけです。デバッグがオンになっている場合、情報はブラウザーに直接出力され、それ以外の場合はログに記録されます。
01 |
02 | class Logger extends Base { |
04 | if(is_object($param)) { |
02
05 | if(true === C('debug')) { |
06 | throw $param; |
07 | } else { |
08 | file_put_contents(APP_PATH . '/log',$param,FILE_APPEND); |
09 | } |
10 | } elseif(is_string($param)) { |
11 | if(true === C('debug')) { |
12 | echo $param; |
13 | } else { |
14 | file_put_contents(APP_PATH . '/log',$param,FILE_APPEND); |
15 | } |
16 | } else {} |
17 | } |
18 | } |
Logger::log を介して渡されたパラメーターがオブジェクトであると仮定すると、例外がスローされたことを意味します。それが文字列の場合は、プログラムが出力する必要がある警告メッセージまたはエラー メッセージである可能性があります。他の種類の場合は処理されません。
コードを簡素化するために、クラス コード全体は非常に小さくなっています。デバッグがオンになっているかどうかを判断するだけです。オンになっていない場合は、ログに記録されます。直接印刷されます。
これに興味がある場合は、強力なログ システムを自分で作成してみることができますが、ここでは詳しく説明しません。 。 。
ログ クラスを作成したら、すぐにドライバー クラスの作成を開始します。ドライバー クラスを作成する前に、前回述べたようにコントラクト コードは次のとおりです。 >
<テーブル>01
01 |
03 | function execute($sql); |
04 | function connect(); |
05 | function close(); |
06 | function getAllByObject(); |
07 | function getAllByAssoArray(); |
08 | function getAllByArray(); |
09 | function beginTrans(); |
10 | function commit(); |
11 | function rollback(); |
12 | } |
すぐに PDO をドライバー クラスとして使用するため、誰もが PDO の前処理に慣れ、このインターフェイスを簡素化するために、これを書く時間が限られているため、この規約を次のように変更しました。次のようになります:
<テーブル>
01 |
02 | interface IDbDriver { |
04 | function execute(Array $arr); |
05 | function connect(); |
06 | function close(); |
07 | function getAllByAssocArray(); |
08 | function beginTrans(); |
09 | function commit(); |
10 | function rollback(); |
11 | } |
Java の JDBC を学習したことがあれば、PDO に非常に慣れているでしょう。もちろん、mysql_* インターフェースの使用に慣れている場合は、視点を変える必要があるかもしれません。 msyql_* をドライバー クラスとして使用する場合、mysql_* はこのメカニズムを提供していないため、申し訳ありませんが、自分で準備する必要があります。
次に、PDO ドライバー クラスを作成します。コードは次のとおりです。
<テーブル>
01 |
02 | class PdoDriver extends Base implements IDbDriver { |
04 | private $_pstmt = null; |
05 | public function __construct() { |
06 | $this->connect(); |
07 | } |
08 | public function connect() { |
09 | try { |
10 | $this->_db = newPDO(C('db=>dsn'),C('db=>user'),C('db=>pwd'),array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES "UTF8";')); |
11 | if(null !== $this->_db) { |
12 | Logger::log('[Notice]connect success!'); |
13 | } else { |
14 | Logger::log('[Error]:connect failed'); |
15 | } |
16 | } catch(PDOException $e) { |
17 | Logger::log( $e); |
18 | } |
19 | } |
20 | public function close() { |
21 | if(null !== $this->_db) { |
22 | unset($this->_db); |
23 | } |
24 | } |
25 | public function prepare($sql) { |
26 | if(null !== $this->_pstmt) { |
27 | $this->_pstmt = null; |
28 | } |
29 | $this->_pstmt = $this->_db->prepare($sql); |
30 | } |
31 | public function execute(Array $arr) { |
32 | if(null === $this->_pstmt) { |
33 | Logger::log('[Error]not prepared statement'); |
34 | } else { |
35 | if(false === $this->_pstmt->execute($arr)) { |
36 | Logger::log('[Error]sql error,error info is : ' . $this->_ptstmt->errorInfo()); |
37 | } else { |
38 | Logger::log('[Notice]:execute success'); |
39 | } |
40 | } |
41 | } |
42 | public function getAllByAssocArray() { |
43 | return $this->_pstmt->fetchAll(PDO::FETCH_ASSOC); |
44 | } |
45 | public function beginTrans() { |
46 | $this->_db->beginTransaction(); |
47 | } |
48 | public function commit() { |
49 | $this->_db->commit(); |
50 | } |
51 | public function rollback() { |
52 | $this->_db->rollback(); |
53 | } |
54 | } |
まず、このクラスはインスタンス化されると自動的にDBに接続、つまりconnectメソッドを呼び出します。
PDO は DSN を使用して DB に接続します。もちろん、配列の使用に慣れている場合は、追加のコードを記述する必要があるかもしれません。ここでは説明しません。この方法で DSN を直接使用してください。
みんなが見ているもの
1 | C('db=>dsn'),C('db=>user'),C('db=>pwd') |
01 |
02 | return array( |
03 | 'defaultController' => 'Index', |
01
04 | 'defaultAction' => 'index', |
05 | 'debug' => true, |
06 | 'errorReporting' => -1, | ||||
|
|
||||
03 | 'defaultController' => 'インデックス', | ||||
04 | 'defaultAction' => 'インデックス', | ||||
05 | 'デバッグ' => true、 | ||||
06 | 'errorReporting' => -1, | ||||
07 | 'timeZone' => 'PRC', | ||||
08 | 'db' => 配列( |
09 | 'dsn' => 'mysql:dbname=test;host=localhost', |
10 | 'user' => 'test', |
11 | 'pwd' => 'test', |
12 |
13 | ) |
14 | ); |
C 関数は、このファイルの設定項目を読み出す役割を果たします。これは、Thinkphp に慣れている子供たちにもよく知られているかもしれません。 !
PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES "UTF8";'この文は、mysql の中国語の文字化けの問題を解決します。PDO は実際に統一インターフェイスを提供しているため、元々はmysql の場合はデータベースの種類を指定し、この文を使用しますが、簡単にするために、これが不可能であることを知っていれば、これで問題ありません。 ! !
実は、今の文にはもう一つ問題があって、ここでエンコード方式を完全に書いてしまったのですが、本当は設定ファイルに書いた方が良いのです。 ! !
以下の関数はすべて PDO 独自のインターフェイスを呼び出すため、詳細は説明しません。具体的な内容については、PHP マニュアルの PDO の部分を参照してください。
現在の PDO ドライバー クラスは、mysql の操作のみを完了できます。他のデータベースに切り替えると、PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES "UTF8";' などの特定の問題が発生する可能性があります。実際、このコードを変更せずに他のデータベース用のアダプターを作成することもできます。詳細については、Baidu オンラインで検索してください。
ドライバー クラスを作成したら、コントローラーでテストする必要があります。
01 |
02 | class TestController extends Controller { |
03 | public function test() { |
04 | $test = new PdoDriver(); |
05 | $test->prepare('select * from test where id > :id'); |
06 | $test->execute(array( |
07 | 'id' => '2' |
08 | )); |
09 | var_dump($test->getAllByAssocArray()); |
10 | } |
11 | } |
注: モデルを作成した後は、このように直接呼び出すことはできません。外部コントローラーに直接アクセスできる部分は E であるためです。E は C と F の内容を呼び出し、C は D の内容を呼び出します。 。
先ほど、PDO を使用してドライバー クラスを実装する方法について説明しました。mysql をターゲットにしている場合は、mysql_* または mysqli を使用することもできます。 mysql_* では、上記のインターフェイスの実装がありません。何が難しいのでしょうか? mysql_* インターフェイスを呼び出すだけです。実際には、実行時に最も簡単な方法を使用する必要があります。実行:
str_replace(array_keys($arr),array_values($arr),$sql);
$sql は prepare の呼び出しによって渡される文字列、$arr は実行によって渡される配列ですが、準備中の SQL パラメータ プレースホルダは次のようなものであるため、ここでの配列のキーを処理する必要があることに注意してください。 : id 形式であり、execute によって渡される形式は直接 'id' => 2 の形式であるため、まず配列の各キーに文字を追加する必要があります。次に、各値に対して文字列エスケープを実行します。 str_replaceを実行します。
もちろん、私の方法は最も弱い方法です。他の方法を使用して自分で達成することもできます。
もう 1 つよく知らないことがあります。それは、mysql_* が MySQL トランザクションを処理する方法です。mysql ターミナルを使用したことがある場合は、次のコマンドに精通しているでしょう。 mysql: begin 、 commit 、 rollback なので、 mysql_query を使用して、トランザクションを開始する mysql_query('begin',$this->_db) などのコマンドを実行できます。実際、これらのインターフェイスは次の関数に基づいています。 mysql なので、mysql でサポートされているインターフェイスのみがサポートされ、mysql でサポートされていないインターフェイスは処理できません。