我试图找出在PHP中编写健壮的面向对象数据库模型的最佳实践。我想使用数据访问层,然后有一个抽象的模型类,我的实际模型将能够扩展。我希望能够在这些层中封装所有基本的CRUD功能,因此我不必编写大量冗余代码。我无法找到有关如何执行此操作的教程。有没有人知道一个教程或有关于如何做到这一点的示例代码?
答案 0 :(得分:-1)
这些方面的东西: 这是使用php
的mysqli扩展的抽象打电话给这个文件:DbMgr.php
<?php
class DBMgr{
private $mysql_Host, $Port, $userName, $passWord, $DatabaseName, $connection, $dbType;
//Constructor function to connect and select database.
/*
* The argument is a assoc array with possible following structure
* array(
* 'source' => 'value is a string. Possible values are Func/Coded', Default value is Func. For Func, the application must have already defined a functiobn name get_DbConfig, which will return assoc array with following structure,
* array(
* 'host' => '',
* 'port' => '',
* 'username' => '',
* 'password' => '',
* 'database' => '',
* 'type' => 'optional. The default value is mysql'
* );
* 'type' => 'mandatory/Required only for Coded Source' Default value is mysql. Other possible values are nssql,postgresql.
* 'host' => 'mandatory/Required only for Coded Source'
* 'port' => 'mandatory/Required only for Coded Source'
* 'username' => 'mandatory/Required only for Coded Source'
* 'password' => 'mandatory/Required only for Coded Source'
* 'database' => 'mandatory/Required only for Coded Source. This is the database name.'
* );
*
*/
function __construct($config)
{
$this->dbType = $config['dbType'];
$this->mysql_Host = $config['host'];
$this->Port = $config['port'];
$this->userName = $config['username'];
$this->passWord = $config['password'];
$this->DatabaseName = $config['database'];
$this->connect_SpecificDatabase();
}
function __destruct() {
$this->connection = null;
}
private function connect_SpecificDatabase(){
if(!isset($this->connection)) {
switch ($this->dbType) {
case 'mysql':
$db = new mysqli('p:'.$this->mysql_Host, $this->userName, $this->passWord, $this->DatabaseName, $this->Port); // Make a connection my MySQL
$this->connection = $db;
break;
case 'postgresql':
// Make a connection to PostgreSQL
$connectionString = "host = '".$this->mysql_Host."' port = '".$this->Port."' dbname = '".$this->DatabaseName."' user='".$this->userName."' password = '".$this->passWord."'";
$db = pg_connect($connection_string);
$this->connection = $db;
break;
}
}
else {
$db = $this->connection;
}
if (!$db)
return "Error: Connection failed '".$this->set_dbError()."'";
}
private function set_dbError($Query, &$DB_OperationError = '')
{
include_once __DIR__.'./../ErrorHandling.php';
$DB_OperationError = "";
global $error_code;
switch ($this->dbType) {
case 'mysql':
$DB_OperationError = mysqli_error($this->connection);
$error_code = mysqli_errno($this->connection);
break;
case 'mssql':
$DB_OperationError = mssql_get_last_message();
break;
case 'postgresql':
$DB_OperationError = pg_last_error($this->connection);
break;
}
ErrorLogging('query: --'.$Query.' -- '.'Error: --'.$DB_OperationError);
}
private function FieldValuePair_ToString($FieldValueArray,$onlyValueString=false)
{
$FieldsAsString = "";
foreach ($FieldValueArray as $FieldName => $value) {
if($FieldsAsString != "")
$FieldsAsString .= ', ';
/* if(strpos($value, '+') > 0 || strpos($value, '-') > 0)
$FieldsAsString .= $FieldName." = ".$value;
*/
if(strpos($value,'\'') !== false || strpos($value,'\"') !== false) {
$value = addslashes($value);
}
if($onlyValueString){
if($value != 'now()')
$FieldsAsString .= "'".$value."'";
else
$FieldsAsString .= $value;
}
else{
if($value != 'now()')
$FieldsAsString .= $FieldName." = '".$value."'";
else
$FieldsAsString .= $FieldName." = ".$value;
}
}
return $FieldsAsString;
}
public function Prepare_Output($output, $output_Format, $keyField_Output = '')
{
$output_Format = strtolower($output_Format); // Convert output_Format to lowercase
if(!is_object($output))
return $output;
elseif($output->num_rows == 0)
return 0;
switch($output_Format)
{
case 'result':
return $output;
break;
case 'num_rows':
return $output->num_rows;
break;
case 'num_arr':
while ($row = $output->fetch_array(MYSQLI_NUM)) {
$output_arr[] = $row;
}
return $output_arr;
break;
case 'assoc':
default:
while ($row = $output->fetch_assoc()) {
if($keyField_Output != '' && isset($row[$keyField_Output])){
$output_arr[strval($row[$keyField_Output])] = $row;
}
else
$output_arr[] = $row;
}
return $output_arr;
break;
}
}
private function Prepare_Query($input_array, $prepare_For)
{
$Query = "";
switch($prepare_For)
{
case 'READ':
if($input_array['Fields'] == "" || $input_array['Fields'] == NULL || $input_array['Table'] == "" || $input_array['Table'] == NULL)
return false;
$Query .= "SELECT ";
$Query .= $input_array['Fields'];
$Query .= " FROM ";
$Query .= $input_array['Table'];
if(isset($input_array['clause']) && $input_array['clause'] != "" && $input_array['clause'] !== NULL)
{
$Query .= " WHERE ";
$Query .= $input_array['clause'];
}
if(isset($input_array['order']) && $input_array['order'] != "" && $input_array['order'] !== NULL)
{
$Query .= " ORDER BY ";
$Query .= $input_array['order'];
}
break;
case 'INSERT':
if($input_array['Fields'] == "" || $input_array['Fields'] == NULL || $input_array['Table'] == "" || $input_array['Table'] == NULL)
return false;
$Query .= "INSERT INTO ";
$Query .= $input_array['Table'];
$Query .= " SET ";
$Query .= $this->FieldValuePair_ToString($input_array['Fields']);
break;
case 'UPDATE':
if($input_array['Fields'] == "" || $input_array['Fields'] == NULL || $input_array['Table'] == "" || $input_array['Table'] == NULL)
return false;
$Query .= "UPDATE ";
$Query .= $input_array['Table'];
$Query .= " SET ";
$Query .= $this->FieldValuePair_ToString($input_array['Fields']);
if(isset($input_array['clause']) && $input_array['clause'] != "" && $input_array['clause'] !== NULL)
{
$Query .= " WHERE ";
$Query .= $input_array['clause'];
}
break;
case 'DELETE':
if($input_array['Table'] == "" || $input_array['Table'] == NULL)
return false;
$Query .= "DELETE FROM ";
$Query .= $input_array['Table']."";
if($input_array['clause'] != "" && $input_array['clause'] !== NULL)
{
$Query .= " WHERE ";
$Query .= $input_array['clause'];
}
break;
case 'INSERT_MR':
$vstring = ""; // Field String
if(is_array($input_array)) {
$tableName = $input_array['TABLE_NAME'];
$input_array = $input_array['FIELD_ARRAY'];
for($i = 0 ;$i < count($input_array); $i++) {
$vstring .= "(" . $this->FieldValuePair_ToString($input_array[$i],true) . ")";
if(! ($i == (count($input_array) - 1))) $vstring .= ",";
}
// Column String
$column_string = implode("," , array_keys($input_array[0])); // Get the column names
$Query = "INSERT INTO ".$tableName." (" . $column_string . ") VALUES ".$vstring.";"; // Form Query String
}
break;
case 'IMPORT_DB':
if(is_array($input_array)) {
$completePathOfSQLFile = "\"" . $input_array['COMPLETE_PATH'];
$Query = "mysql --user" . $this->userName . " --password " . $this->DatabaseName . " < " . $completePathOfSQLFile;
}
break;
case 'EXPORT_DB':
if(is_array($input_array)) {
$TableArray = $input_array['TABLE_LIST'];
$dumpFileName = $input_array['DUMP_FILE_NAME'];
$dQuery = "mysqldump -h ".$this->mysql_Host." --port=".$this->Port." --user=".$this->userName." --password=".$this->passWord;
$dumpFilePath = __DIR__;
$dumpFileName = $dumpFileName == "" ? time().'mysqlDump.sql': $dumpFileName;
if(($TableArray == null) || count($TableArray) == 0 ) {
// Export all tables
$Query = $dQuery . " --databases ".$this->DatabaseName." > ".$dumpFilePath."\\".$dumpFileName;
} else {
$tableNames = "";
// Export selective tables
foreach($TableArray as $k => $k_value) {
$tableNames .= " " . $$TableArray[$k];
}
$Query = $dQuery . " " . $this->DatabaseNames." " . $tableNames . " > \"" . $dumpFilePath."\\".$dumpFileName."\"";
}
}
break;
}
return $Query;
}
public function Read($input_array, $outputFormat, $DataType = "", $keyField_Output = '')
{
$Query = $this->Prepare_Query($input_array, 'READ');
$output = "";
if(!$Query)
$output= 'INVALID';
else
{
$result = $this->connection->query($Query);
if (!$result)
{
$this->set_dbError($Query);
$output = false;
}
else
{
$output = $this->Prepare_Output($result, $outputFormat, $keyField_Output);
if( ($DataType != "") && (strcasecmp(strtolower($DataType) , 'as_json') == 0) )
$output = json_encode($output);
}
}
return $output;
}
public function Insert($input_array)
{
$Query = $this->Prepare_Query($input_array, 'INSERT');
$output = "";
if(!$Query)
$output= 'INVALID';
else
{
$result = $this->connection->query($Query);
if (!$result)
{
$this->set_dbError($Query);
$output = false;
}
else
{
$output = mysqli_insert_id($this->connection);
if(!$output)
return true;
}
}
return $output;
}
public function Update($input_array)
{
$Query = $this->Prepare_Query($input_array, 'UPDATE');
$output = "";
if(!$Query)
$output= 'INVALID';
else
{
$result = $this->connection->query($Query);
if (!$result)
{
$this->set_dbError($Query);
$output = false;
}
else
{
$output = true;
}
}
return $output;
}
public function Delete($input_array)
{
$Query = $this->Prepare_Query($input_array, 'DELETE');
$output = "";
if(!$Query)
$output= 'INVALID';
else
{
$result = $this->connection->query($Query);
if (!$result)
{
$this->set_dbError($Query);
$output = false;
}
else
{
$output = true;
}
}
return $output;
}
public function Query($Query, $outputFormat = 'ASSOC', $DataType = "", $keyField_Output = '')
{
$result = $this->connection->query($Query);
if (!$result)
{
$this->set_dbError($Query);
$output = false;
}
else
{
$output = $this->Prepare_Output($result, $outputFormat, $keyField_Output);
if($DataType != "")
$output = json_encode($output);
}
return $output;
}
public function Export($ExportDBArray) {
$Query = $this->Prepare_Query($input_array, 'EXPORT_DB');
$op = '';
$REtVal = '';
$query = 'dir';
$resultQuery = exec($query,$op,$REtVal);
if($resultQuery) return true;
else return false;
}
public function Import($ImportDBArray) {
$Query = $this->Prepare_Query($ImportDBArray, 'IMPORT_DB');
$resultQuery = exec($Query);
}
public function InsertMR($multipleFieldsArray) {
$tableName = $multipleFieldsArray['TABLE_NAME'];
$listOfID = $multipleFieldsArray['ID_LIST'];
$FieldsArray = $multipleFieldsArray['FIELD_DETAILS'];
$input_array = array('FIELD_ARRAY' => $FieldsArray, 'TABLE_NAME' => $tableName);
$Query = $this->Prepare_Query($input_array, 'INSERT_MR');
$result = $this->connection->query($Query); // Run Query
$output = array();
if (!$result) {
$this->set_dbError($Query);
} else {
$insert_id = mysqli_insert_id($this->connection);
if($listOfID) {
for($i=0; $i<count($FieldsArray); $i++) {
$output[$i] = $insert_id;
$insert_id++;
}
} else {
$output[0] = $insert_id;
}
}
return $output;
}
public function closeConnection() {
if(isset($this->connection)) {
mysqli_close($this->connection);
}
}
};
?>
答案 1 :(得分:-1)
如果你想进一步抽象,只是对上面的DbMgr.php进行程序调用, 你可以使用下面的代码。这将有助于您快速开发项目,任何没有数据库知识的人也可以使用以下方法开发php mysql应用程序。
打电话给这个文件:DbMgrInterface.php
//Includes complete implementation of DB operations
require_once __DIR__.'/DbMgr.php';
$perform_Database_Operation = null; // Global variable to reuse the connection
$error_code = null; // Global variable holding the error_code for a transaction
function getDBConfig($config = ''){
$source = 'Func';
$type = 'mysql';
if(isset($config['source'])){
$source = $config['source'];
}
if( (strcasecmp("Func",$source) == 0) && (function_exists('get_DbConfig')) ) {
$config = get_DbConfig();
}
if(isset($config['type'])){
$type = $config['type'];
}
$config['dbType'] = strtolower($type);
$config['servername'] = $config['host'];
$config['Port'] = $config['port'];
$config['userName'] = $config['username'];
$config['passWord'] = $config['password'];
$config['DatabaseName'] = $config['database'];
return $config;
}
/**
Logic: If config array is passed to this method then definitely the new handle is required.
Else, If DBMgrHandle already exists then return the existing handle.
Else, get the default DB config, and instantiate a new DBMgr Handle.
*/
function DBMgr_Handle($config = '') {
global $perform_Database_Operation;
$className = 'DBMgr';
if(is_array($config)){
$config = getDBConfig($config);
if(strcasecmp($config['dbType'], 'mssql') == 0){
$className = 'SSRV';
}
$perform_Database_Operation = new $className($config);
return $perform_Database_Operation;
}
if(isset($perform_Database_Operation))
return $perform_Database_Operation;
$config = getDBConfig($config);
if(strcasecmp($config['dbType'], 'mssql') == 0){
$className = 'SSRV';
}
if(function_exists('getclassObject'))
$perform_Database_Operation = getclassObject($className, $config);
else
$perform_Database_Operation = new $className($config);
return $perform_Database_Operation;
}
/*=====================================================READ==============================================================*/
/*
* @access public
* @param associative_Array $readInput. Format is described below:
* array(
* 'Fields'=> 'Field1, Field2, Field3', //Mandatory
* 'Table'=> 'TableName', //Mandatory
* 'clause'=> 'FieldName = FieldValue', //optional
* 'order' => 'FieldName DESC' //optional
* )
clause refers exact/valid values as mysql query accepts.
clause is a condition to filter output. e.g. 'FieldName = DesiredValue' would return entries where FieldName has DesiredValue value only.
Order refers exact/valid values as mysql query accepts and is used to sort data selection. example value can be 'FieldName ASC' or 'FieldName DESC'.
* @param string $outputFormat. Values can be one of 'RESULT, NUM_ROWS, NUM_ARR, ASSOC', where ASSOC is default value.
* It defines whether the read should return 'mysql result resource/ Numbers of rows in result set / Numbered array / Associative array
* @param string $DataType. Value can only be 'JSON' else ''. Use this to get data set returned as json.
* @param string $keyField_Output. This can be a field name so that indexes of assoc array can be defined with value of the field passed.
*
* @return false, else 0(zero- for no corresponding entry), else output in described format.
* If mysql error is to be accessed, it is available with a aglobal variable $DB_OperationError
*/
function DB_Read($readInput, $outputFormat = "ASSOC", $DataType = "", $keyField_Output = '') {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Read($readInput, $outputFormat, $DataType, $keyField_Output);
}
/*=====================================================INSERT==============================================================*/
/*
* @access public
* @param associative_Array $insertInput. Format is described below:
* array(
* 'Table'=> 'TableName', //Mandatory
* 'Fields'=> array( //Mandatory
'FieldName1' =>Value1,
'FieldName2' =>Value2,
'FieldName_n'=>Value_n
)
* )
* So in above associative array the element refered by key 'Fields' is itself an associative array which would specify DbField and corresponding Value to be stored
* @return Inserted Id on success, else false on failure. If mysql error is to be accessed, it is available with a aglobal variable $DB_OperationError
*/
function DB_Insert($insertInput) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Insert($insertInput);
}
/*=====================================================UPDATE==============================================================*/
/*
* @access public
* @param associative_Array $updateInput. Format is described below:
* array(
* 'Table'=> 'TableName', //Mandatory
* 'Fields'=> array( //Mandatory
'FieldName1' =>Value1,
'FieldName2' =>Value2,
'FieldName_n'=>Value_n
),
* 'clause'=> 'FieldName = FieldValue', //optional
* )
* So in above associative array the element refered by key 'Fields' is itself an associative array which would specify DbField and corresponding Value to be stored
* @return true on success, else false. If mysql error is to be accessed, it is available with a aglobal variable $DB_OperationError
*/
function DB_Update($updateInput) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Update($updateInput);
}
/*=====================================================DELETE==============================================================*/
/*
* @access public
* @param associative_Array $deleteInput. Format is described below:
* array(
* 'Table'=> 'TableName', //Mandatory
* 'clause'=> 'FieldName = FieldValue', //OPTIONAL. But if not specified all the data from database would be deleted
* )
* So in above associative array the element refered by key 'Fields' is itself an associative array which would specify DbField and corresponding Value to be stored
* @return true on success, else false on failure. If mysql error is to be accessed, it is available with a aglobal variable $DB_OperationError
*/
function DB_Delete($deleteInput) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Delete($deleteInput);
}
/*=====================================================RUN ABSOLUTE QUERY==============================================================*/
/*
* @access public
* @param Query as a string. Query can be of any type
* @param string $outputFormat. Values can be one of 'RESULT, NUM_ROWS, NUM_ARR, ASSOC', where ASSOC is default value.
* It defines whether the read should return 'mysql result resource/ Numbers of rows in result set / Numbered array / Associative array
* @param string $DataType. Value can only be 'JSON' else ''. Use this to get data set returned as json.
* @param string $keyField_Output. This can be a field name so that indexes of assoc array can be defined with value of the field passed.
*
* @return false, else 0(zero- for no corresponding entry), else output in described format. If mysql error is to be accessed, it is available with a aglobal variable $DB_OperationError
*/
function DB_Query($query, $outputFormat = "ASSOC", $DataType = "", $keyField_Output = '') {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Query($query, $outputFormat, $DataType, $keyField_Output);
}
/**
* The function makes a complete database dump of dump for selective tables, depending upon the TABLE_LIST. If TABLE_LIST is empty,
* a complete database dump is made, else dump for selective tables is carried out.
* @param unknown $ExportDBArray
* $ExportDBArray = array(
'DUMP_FILE_NAME' => 'dump.sql', // optional
'TABLE_LIST' => array( // optional
'Table1' => 'userinfo',
'Table2' => 'usageinfo'
)
);
* @return boolean
*/
function DB_ExportTable($ExportDBArray) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Export($ExportDBArray);
}
/**
* The function imports SQL Dump from the given file path.
* @param unknown $ImportDBArray
* $ImportDBArray = array(
'COMPLETE_PATH' => __DIR__ . "\\database_dump.sql"
);
*/
function DB_ImportTable($ImportDBArray) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->Import($ImportDBArray);
}
/**
*
* @param unknown $multipleFieldsArray
* $multipleFieldsArray = array(
'TABLE_NAME' => 'userinfo',
'ID_LIST' => true ,
'FIELD_DETAILS' => array(
array('Username' => 'bjam123','Password' =>md5('password123'), 'UserType' => 1),
array('Username' => 'ppu12', 'Password' => md5('password1234'), 'UserType' => 2),
array('Username' => 'ppu13', 'Password' => md5('password12345'), 'UserType' => 3),
array('Username' => 'ppu14', 'Password' => md5('password123456'), 'UserType' => 4)
)
);
* @return array containing the insert_id
*/
function DB_InsertMultipleRows($multipleFieldsArray) {
$perform_Database_Operation = DBMgr_Handle();
return $perform_Database_Operation->InsertMR($multipleFieldsArray);
}
/**
* Call this function to perform MSSQL Server specific transactions
* @param unknown $fieldValueArray
* Format is described below:
* array(
* 'Fields'=> 'Field1, Field2, Field3', //Mandatory
* 'Table'=> 'TableName', //Mandatory
* 'clause'=> 'FieldName = FieldValue', //optional
* 'order' => 'FieldName DESC' //optional
* )
clause refers exact/valid values as mysql query accepts.
clause is a condition to filter output. e.g. 'FieldName = DesiredValue' would return entries where FieldName has DesiredValue value only.
Order refers exact/valid values as mysql query accepts and is used to sort data selection. example value can be 'FieldName ASC' or 'FieldName DESC'.
* @param unknown $operationType
* Possible Values - READ, INSERT, UPDATE, DELETE
* @param unknown $outputFormat
* Possible Values - ASSOC, NUM_ARR, NUM_ROWS
*/
function DB_SSRV_Transact($fieldValueArray, $operationType, $outputFormat) {
$perform_Database_Operation = SSRV_Handle();
$perform_Database_Operation->transact($fieldValueArray, $operation, $outputFormat);
}
/*=====================================================Close mysql connection or destroy mysqli object==============================================================*/
/*
* @access public
*/
function DB_Close()
{
$perform_Database_Operation = DBMgr_Handle();
$perform_Database_Operation->closeConnection();
global $perform_Database_Operation;
$perform_Database_Operation = null;
return;
}
?>