一步步编写PHP的Framework(十七)
由于模型中D这一部分是比较基础的,所以我们先把D这一部分做了。
D中最重要的是驱动类的编写,所以我们就先写驱动类,由于在驱动类中需要用到日志,所以我们先做一个简单的Logger类,这个类只有一个log的静态方法,如果debug开启,那么直接在浏览器上面输出信息,否则记录到日志中。
01 |
02 | class Logger extends Base { |
03 | public static function log($param) { |
04 | if(is_object($param)) { |
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传递的参数是对象,则代表是抛出了异常,如果是字符串,那么则可能是程序需要输出的警告或者Error信息,如果是其他类型,则不处理。
出于简化代码的目的,所以整个类代码非常少,只是判定了一下是否debug开启了,如果开启,则记录到日志,否则,直接打印出来。
如果你们对这个有兴趣,可以自己尝试做一个功能强大的日志系统,我这儿就不说了啊。。。
日志类写完之后,马上就开始编写驱动类吧,在写驱动类之前,我们还是按照上一次讲的将契约编写了,契约代码如下:
01 |
02 | interface IDbDriver { |
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 { |
03 | function prepare($sql); |
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_*这种来做驱动类,那么不好意思,你要自己做prepare了,因为mysql_*没有提供这种机制。
然后我们就是编写PDO的驱动类,代码如下:
01 |
02 | class PdoDriver extends Base implements IDbDriver { |
03 | private $_db = null; |
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连接DB是使用了DSN这种方式,当然,如果你还是习惯普通的使用数组搞定,那么你可能需要编写一些额外的代码,我这儿就不说了啊,我就直接使用DSN这种方式来做了。
大家看到的
1 | C('db=>dsn'),C('db=>user'),C('db=>pwd') |
这个我之前讲过,实际上读取的是配置文件中的内容,配置文件的内容如下:
01 |
02 | return array( |
03 | 'defaultController' => 'Index', |
04 | 'defaultAction' => 'index', |
05 | 'debug' => true, |
06 | 'errorReporting' => -1, |
07 | 'timeZone' => 'PRC', |
08 | 'db' => array( |
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然后才使用这句话,但是为了简便,我就直接这么搞了,你们只要清楚这样是不行的就OK!!!
实际上刚才这句话还有一个问题,这里我完全将编码方式写死了,必须是utf-8,但是实际上如果我们写在配置文件中更好!!
由于下面这几个函数都是调用了PDO自己的接口,所以我就不怎么具体讲了,具体的内容可参照PHP手册的PDO这一部分。
刚才这个PDO的驱动类只能完成mysql的操作,如果换成其他数据库,可能存在一定问题,就比如PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES "UTF8";',实际上我们也可以不修改这段代码,而针对其他数据库做一个适配器,具体的你可以网上百度一下。
写完驱动类之后,我们需要测试一下,我们在控制器中来测一下:
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_*,实现上面的接口也没有什么难度,也就是调用mysql_*这种接口而已,在prepare这一块儿可能需要你们自己好好想想该怎么做,其实最简单的方式就可以在执行execute的时候使用:
str_replace(array_keys($arr),array_values($arr),$sql);
$sql是调用prepare传递进去的字符串,$arr是execute传递的数组,但是注意,这里的数组的key需要处理一下,因为prepare时SQL参数占位符是如:id这种形式,而execute传递进来的直接入'id' => 2这种形式,所以首先需要将数组每个key添加字符:,然后给每个value进行字符串转义,然后再执行str_replace。
当然,我这种方式是最弱的方式,你可以自己用其他方式实现。
还有一个可能大家不太会的,就是mysql_*怎么处理Mysql事务呢,实际上非常简单,如果大家用过mysql的终端,就会熟悉mysql中有这样几条命令:begin,commit,rollback,所以,我们可以使用mysql_query来执行一条命令,如mysql_query('begin',$this->_db),这样就开启了一个事务,实际上这些接口都是按照mysql的功能来做的,所以,mysql支持的这些接口才支持,mysql不支持的,这些接口也搞不定了。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



In der MySQL -Datenbank wird die Beziehung zwischen dem Benutzer und der Datenbank durch Berechtigungen und Tabellen definiert. Der Benutzer verfügt über einen Benutzernamen und ein Passwort, um auf die Datenbank zuzugreifen. Die Berechtigungen werden über den Zuschussbefehl erteilt, während die Tabelle durch den Befehl create table erstellt wird. Um eine Beziehung zwischen einem Benutzer und einer Datenbank herzustellen, müssen Sie eine Datenbank erstellen, einen Benutzer erstellen und dann Berechtigungen erfüllen.

MySQL ist für Anfänger geeignet, da es einfach zu installieren, leistungsfähig und einfach zu verwalten ist. 1. Einfache Installation und Konfiguration, geeignet für eine Vielzahl von Betriebssystemen. 2. Unterstützung grundlegender Vorgänge wie Erstellen von Datenbanken und Tabellen, Einfügen, Abfragen, Aktualisieren und Löschen von Daten. 3. Bereitstellung fortgeschrittener Funktionen wie Join Operations und Unterabfragen. 4. Die Leistung kann durch Indexierung, Abfrageoptimierung und Tabellenpartitionierung verbessert werden. 5. Backup-, Wiederherstellungs- und Sicherheitsmaßnahmen unterstützen, um die Datensicherheit und -konsistenz zu gewährleisten.

Vereinfachung der Datenintegration: AmazonRDSMYSQL und Redshifts Null ETL-Integration Die effiziente Datenintegration steht im Mittelpunkt einer datengesteuerten Organisation. Herkömmliche ETL-Prozesse (Extrakt, Konvertierung, Last) sind komplex und zeitaufwändig, insbesondere bei der Integration von Datenbanken (wie AmazonRDSMysQL) in Data Warehouses (wie Rotverschiebung). AWS bietet jedoch keine ETL-Integrationslösungen, die diese Situation vollständig verändert haben und eine vereinfachte Lösung für die Datenmigration von RDSMysQL zu Rotverschiebung bietet. Dieser Artikel wird in die Integration von RDSMYSQL Null ETL mit RedShift eintauchen und erklärt, wie es funktioniert und welche Vorteile es Dateningenieuren und Entwicklern bringt.

Ausfüllen des MySQL -Benutzernamens und des Kennworts: 1. Bestimmen Sie den Benutzernamen und das Passwort; 2. Verbinden Sie eine Verbindung zur Datenbank; 3. Verwenden Sie den Benutzernamen und das Passwort, um Abfragen und Befehle auszuführen.

1. Verwenden Sie den richtigen Index, um das Abrufen von Daten zu beschleunigen, indem die Menge der skanierten Datenmenge ausgewählt wird. Wenn Sie mehrmals eine Spalte einer Tabelle nachschlagen, erstellen Sie einen Index für diese Spalte. Wenn Sie oder Ihre App Daten aus mehreren Spalten gemäß den Kriterien benötigen, erstellen Sie einen zusammengesetzten Index 2. Vermeiden Sie aus. Auswählen * Nur die erforderlichen Spalten. Wenn Sie alle unerwünschten Spalten auswählen, konsumiert dies nur mehr Serverspeicher und veranlasst den Server bei hoher Last oder Frequenzzeiten, beispielsweise die Auswahl Ihrer Tabelle, wie beispielsweise die Spalten wie innovata und updated_at und Zeitsteuer und dann zu entfernen.

Detaillierte Erläuterung von Datenbanksäureattributen Säureattribute sind eine Reihe von Regeln, um die Zuverlässigkeit und Konsistenz von Datenbanktransaktionen sicherzustellen. Sie definieren, wie Datenbanksysteme Transaktionen umgehen, und sorgen dafür, dass die Datenintegrität und -genauigkeit auch im Falle von Systemabstürzen, Leistungsunterbrechungen oder mehreren Benutzern gleichzeitiger Zugriff. Säureattributübersicht Atomizität: Eine Transaktion wird als unteilbare Einheit angesehen. Jeder Teil schlägt fehl, die gesamte Transaktion wird zurückgerollt und die Datenbank behält keine Änderungen bei. Wenn beispielsweise eine Banküberweisung von einem Konto abgezogen wird, jedoch nicht auf ein anderes erhöht wird, wird der gesamte Betrieb widerrufen. begintransaktion; updateAccountsSetBalance = Balance-100WH

Navicat selbst speichert das Datenbankkennwort nicht und kann das verschlüsselte Passwort nur abrufen. Lösung: 1. Überprüfen Sie den Passwort -Manager. 2. Überprüfen Sie Navicats "Messnot Password" -Funktion; 3.. Setzen Sie das Datenbankkennwort zurück; 4. Kontaktieren Sie den Datenbankadministrator.

SQllimit -Klausel: Steuern Sie die Anzahl der Zeilen in Abfrageergebnissen. Die Grenzklausel in SQL wird verwendet, um die Anzahl der von der Abfrage zurückgegebenen Zeilen zu begrenzen. Dies ist sehr nützlich, wenn große Datensätze, paginierte Anzeigen und Testdaten verarbeitet werden und die Abfrageeffizienz effektiv verbessern können. Grundlegende Syntax der Syntax: SelectColumn1, Spalte2, ... Fromtable_Namelimitnumber_of_rows; number_of_rows: Geben Sie die Anzahl der zurückgegebenen Zeilen an. Syntax mit Offset: SelectColumn1, Spalte2, ... Fromtable_NamelimitOffset, Number_of_rows; Offset: Skip überspringen
