我一直在努力学习OOP和课程,我想要对我正在编写的一个简单项目进行批评。
我编写了几个类,以便我更容易使用MySQL和PDO生成表。它仍在继续,但我想确保我没有“破碎”任何东西。
我的主要问题是我想知道我写的内容是否仍然被认为是“安全的”,主要来自SQL注入。
的index.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database Class</title>
</head>
<body>
<?php
include 'class.MySQL.php';
include 'class.TableBuilder.php';
//Check to make sure a valid connection has been made
//If so, instantiate the object and login to the database
$db = (new MySQLDatabase_Object)->check_login();
//Define the columns headings
//Can be empty, but shouldn't be
//Example:
//"First Name"
//"Last Name"
$columns = array(
'First Name',
'Last Name',
'Street Address'
);
//Build the 'SELECT' query fields
//Cannot be empty
//Example:
//"leads.fname" => "fname means"
//"leads.fname" => "fname"
$fields = array(
'leads.fname' => 'fname',
'leads.lname' => 'lname',
'leads.addr_street' => 'addr_street'
);
//Builds the 'FROM' query values
//This will be a single table name
//Cannot be empty
//Example:
//"leads"
$tables = array('leads');
//Builds the 'WHERE' query
//Can only use the JOIN query or the WHERE query, not both
//Can be empty
//Examples:
//"WHERE leads.fname LIKE '%Walt%'"
//"WHERE leads.fname = 'Walter'"
$where = array(
);
//Builds the JOIN query
//Can only use the JOIN query or the WHERE query, not both
//Can be empty
//Examples:
//"INNER JOIN appointments" => "leads.id = appointments.lead"
//"INNER JOIN leads_notes" => "leads.id = leads_notes.id_lead"
$join = array(
);
//Builds the AND/OR/NOT query
//Can be empty
//Examples:
//"AND leads.assigned = 1"
//"OR leads.assigned != 0"
//"NOT leads.assigned = 0"
$and = array(
);
//Sets the 'ORDER BY' clause
//Can be empty
//Example:
//"leads.lname ASC"
//"leads.fname DESC"
$order = array(
);
//Build and return the query
$query = MySQLDatabase_Object::query_builder_select($fields, $tables, $where, $join, $and, $order);
//Gather the result set from the query and
//place them in a nested array
$result_set = MySQLDatabase_Object::results($fields, $db, $query);
//Build the table, based on the result set and columns
//and print the table to the screen
$table = new MySQLTable;
echo $table->buildTable($columns, $result_set);
?>
</body>
</html>
class.MySQL.php:
<?php
class MySQLDatabase_Object {
//Create the database connection and attempt to login to the database
private function login() {
$host = "localhost"; //Host Name
$port = '3306'; //Default MySQL Port
$dbname = "xxxxxx"; //Database Name
$db_username = "xxxxxx"; //MySQL Username
$db_password = "xxxxxx"; //MySQL Password
$dsn = "mysql:host=$host;port=$port;dbname=$dbname"; //Data Source Name = Mysql
$db = new PDO($dsn, $db_username, $db_password); //Connect to DB
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
//Public-facing login method to log into the database and return the $db PDO
public function check_login() {
$db = $this->login();
return $db;
}
static function query_builder_select($fields, $tables, $where, $join, $and, $order) {
//Process the SELECT fields
$select_fields = self::check_fields($fields);
//Process the FROM field
$tables = self::check_table($tables);
//Processes the JOIN or WHERE fields
if (!empty($where) && !empty($join)) {
die("You can only use one of the JOIN or WHERE clauses. Not both.");
} elseif (!empty($where)) {
$where = self::check_where($where);
} elseif (!empty($join)) {
$where = self::check_join($join);
} else {
$where = null;
}
//Process the AND/OR/NOT fields
$and = self::check_and($and);
//Process the ORDER BY fields
$order = self::check_order($order);
//Build the SELECT query
$query = "SELECT $select_fields ";
$query .= "FROM $tables";
if (!is_null($where)) {
$query .= " $where";
}
if (!is_null($and)) {
$query .= " $and";
}
if (!is_null($order)) {
$query .= " ORDER BY $order";
}
echo $query;
return $query;
}
private static function check_fields($fields) {
//Purpose: Gathers all the values from the $fields array
//and formats them correctly to generate a correct "SELECT" statement
//Check for an empty array
if (empty($fields)) {
die("No query fields selected");
}
//
$select_fields = '';
foreach ($fields AS $key => $value) {
$select_fields .= "$key AS $value,";
}
//Remove the trailing comma from the last element in the array
$select_fields = trim($select_fields, ',');
return $select_fields;
}
private static function check_table($tables) {
//Get the table array elements and seperate them with a comma
if (!empty($tables)) {
$tables = implode(',', $tables);
$tables = trim($tables, ',');
} else {
die('No Tables selected');
}
return $tables;
}
private static function check_where($where) {
//Get the WHERE array elements and seperate them with a comma
if (!empty($where)) {
$where = implode(',', $where);
$where = trim($where, ',');
} else {
$where = null;
}
return $where;
}
private static function check_join($join) {
$join_options = '';
if (!empty($join)) {
foreach ($join AS $key => $value) {
$join_options .= " $key ON $value ";
}
} else {
$join_options = null;
}
return $join_options;
}
private static function check_and($and) {
//Get the WHERE array elements and seperate them with a comma
if (!empty($and)) {
$and = implode(' ', $and);
$and = trim($and, ' ');
} else {
$and = null;
}
return $and;
}
private static function check_order($order) {
//Get the order array elements and seperate them with a comma
if (!empty($order)) {
$order = implode(',', $order);
$order = trim($order, ',');
} else {
$order = null;
}
return $order;
}
static function results($fields, $db, $query) {
//Run the prepared query
$stmt = $db->prepare($query);
$stmt->execute();
$results = array();
$field_array = array();
foreach ($stmt->fetchAll(PDO::FETCH_OBJ) as $row) {
//Build the nested arrays
foreach ($fields AS $key => $value) {
$$value = $row->$value;
array_push($field_array, $$value);
}
//Add the nested arrays to the main array ($results)
array_push($results, $field_array);
$field_array = array();
}
return $results;
}
}
class.TableBuilder.php:
<?php
class MySQLTable {
public function buildTable($columns, $result_set) {
//Create an empty table
$table = '';
$table .= '<table border="1">';
//Build the column structure, passed in from the $columns array
$table .= "<tr>";
foreach ($columns as $column) {
$table .= "<td>$column</td>";
}
$table .= "</tr>";
//Build the rows from the $result_set array
foreach ($result_set AS $array) {
$table .= "<tr>";
//Pass each nested array to the table as a single row
//per nested array
foreach ($array AS $table_cell) {
$table .= "<td>$table_cell</td>";
}
//Placeholder for adding additional columns (usually button columns)
// $table .= "<td><button type='button'>Test</button></td>";
$table .= "</tr>";
}
//Complete the table
$table .= "</table>";
return $table;
}
}
为了使其正常工作,您需要使用数据库信息修改class.MySQL.php。
您可以修改index.php中的$ fields和$ columns,看看它是如何工作的。理论上,您应该能够在'$ columns'数组中命名列,在$ fields数组中命名您的MySQL SELECT字段,在$ tables中命名您的表名。
如果您需要更多信息,我很乐意提供帮助。
我知道只有简单的'WHERE'和'JOIN'子句处理。我将在接下来的工作。
感谢任何批评!